summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-console/MyPty.cpp22
-rw-r--r--noncore/apps/opie-console/procctl.cpp2
2 files changed, 18 insertions, 6 deletions
diff --git a/noncore/apps/opie-console/MyPty.cpp b/noncore/apps/opie-console/MyPty.cpp
index 10828b0..cacb4ce 100644
--- a/noncore/apps/opie-console/MyPty.cpp
+++ b/noncore/apps/opie-console/MyPty.cpp
@@ -61,95 +61,99 @@
There's a sinister ioctl(2), signal(2) and job control stuff
nessesary to make everything work as it should.
*/
#include <qapplication.h>
#include <qsocketnotifier.h>
#include <qstring.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#ifdef HAVE_OPENPTY
#include <pty.h>
#endif
+#include "procctl.h"
#include "MyPty.h"
#undef VERBOSE_DEBUG
/* -------------------------------------------------------------------------- */
/*!
Informs the client program about the
actual size of the window.
*/
void MyPty::setSize(int lines, int columns)
{
struct winsize wsize;
wsize.ws_row = (unsigned short)lines;
wsize.ws_col = (unsigned short)columns;
if(m_fd < 0) return;
ioctl(m_fd,TIOCSWINSZ,(char *)&wsize);
}
void MyPty::donePty()
{
// This is code from the Qt DumbTerminal example
int status = 0;
::close(m_fd);
if (m_cpid) {
+ qWarning("killing!!!");
kill(m_cpid, SIGHUP);
waitpid(m_cpid, &status, 0);
}
- emit done(status);
+ m_cpid = 0;
+// emit done(status);
}
const char* MyPty::deviceName()
{
return m_ttynam;
}
void MyPty::error()
{
+ qWarning("error");
// This is code from the Qt DumbTerminal example
donePty();
}
void MyPty::start() {
char* cmd = "/bin/sh";
QStrList lis;
int r =run(cmd, lis, 0, 0);
r = r;
}
/*!
start the client program.
*/
int MyPty::run(const char* cmd, QStrList &, const char*, int)
{
// This is code from the Qt DumbTerminal example
m_cpid = fork();
if ( !m_cpid ) {
// child - exec shell on tty
for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
int ttyfd = ::open(m_ttynam, O_RDWR);
dup2(ttyfd, STDIN_FILENO);
dup2(ttyfd, STDOUT_FILENO);
@@ -161,139 +165,147 @@ int MyPty::run(const char* cmd, QStrList &, const char*, int)
perror( "failed to set process group" );
#if defined (TIOCSCTTY)
// grabbed from APUE by Stevens
ioctl(STDIN_FILENO, TIOCSCTTY, 0);
#endif
tcgetattr( STDIN_FILENO, &ttmode );
ttmode.c_cc[VINTR] = 3;
ttmode.c_cc[VERASE] = 8;
tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
setenv("TERM","vt100",1);
setenv("COLORTERM","0",1);
if (getuid() == 0) {
char msg[] = "WARNING: You are running this shell as root!\n";
write(ttyfd, msg, sizeof(msg));
}
execl(cmd, cmd, 0);
donePty();
exit(-1);
}
// parent - continue as a widget
QSocketNotifier* sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this);
- QSocketNotifier* sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this);
+// QSocketNotifier* sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this);
connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
- connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
+// connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
return 0;
}
int MyPty::openPty()
{
// This is code from the Qt DumbTerminal example
int ptyfd = -1;
#ifdef HAVE_OPENPTY
int ttyfd;
if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
ptyfd = -1;
else
close(ttyfd); // we open the ttynam ourselves.
#else
for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1);
sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1);
if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) {
if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) {
::close(ptyfd);
ptyfd = -1;
}
}
}
}
#endif
if ( ptyfd < 0 ) {
qApp->exit(1);
return -1;
}
return ptyfd;
}
/*!
Create an instance.
*/
MyPty::MyPty(const Profile&) : m_cpid(0)
{
m_fd = openPty();
+ ProcCtl* ctl = ProcCtl::self();
}
/*!
Destructor.
Note that the related client program is not killed
(yet) when a instance is deleted.
*/
MyPty::~MyPty()
{
donePty();
}
QString MyPty::identifier()const {
return QString::fromLatin1("term");
}
QString MyPty::name()const{
return identifier();
}
bool MyPty::open() {
start();
return true;
}
void MyPty::close() {
donePty();
}
void MyPty::reload( const Profile& ) {
}
/*! sends len bytes through the line */
void MyPty::send(const QByteArray& ar)
{
-
+ qWarning("sending!");
#ifdef VERBOSE_DEBUG
// verbose debug
printf("sending bytes:\n");
for (uint i = 0; i < ar.count(); i++)
printf("%c", ar[i]);
printf("\n");
#endif
::write(m_fd, ar.data(), ar.count());
}
/*! indicates that a block of data is received */
void MyPty::readPty()
{
+ qWarning("read");
QByteArray buf(4096);
int len = ::read( m_fd, buf.data(), 4096 );
- if (len == -1)
+ if (len == -1 || len == 0) {
+ qWarning("donePty!!! now!");
donePty();
+ qWarning("return %s", sender()->className() );
+ delete sender();
+ return;
+ }
if (len < 0)
return;
+
buf.resize(len);
emit received(buf);
#ifdef VERBOSE_DEBUG
// verbose debug
printf("read bytes:\n");
for (uint i = 0; i < buf.count(); i++)
printf("%c", buf[i]);
printf("\n");
#endif
}
diff --git a/noncore/apps/opie-console/procctl.cpp b/noncore/apps/opie-console/procctl.cpp
index b0b6846..d1cfaf6 100644
--- a/noncore/apps/opie-console/procctl.cpp
+++ b/noncore/apps/opie-console/procctl.cpp
@@ -50,48 +50,48 @@ void ProcCtl::remove( pid_t pi ) {
if ( pi == con->pid ) {
forw->prev = con->prev;
delete con;
return;
}
forw = con;
con = con->prev;
}
}
void ProcCtl::remove( ProcContainer con ) {
remove( con.pid );
}
int ProcCtl::status(pid_t pid )const{
ProcContainer *con = m_last;
while (con) {
if (con->pid == pid )
return con->status;
con = con->prev;
}
return -1;
}
void ProcCtl::signal_handler(int) {
- qWarning("signal handler");
+ qWarning("signal handler in ProcCtl");
int status;
signal( SIGCHLD, signal_handler );
pid_t pi = waitpid( -1, &status, WNOHANG );
/*
* find the container for pid
*
*/
if ( pi < 0 ) {
return;
}
ProcContainer* con = m_last;
while (con) {
if ( con->pid == pi ) {
con->status = status;
char result = 1;
/* give a 'signal' */
::write(con->fd, &result, 1 );
}
con = con->prev;
}
}