-rw-r--r-- | noncore/apps/opie-console/filetransfer.cpp | 3 | ||||
-rw-r--r-- | noncore/apps/opie-console/opie-console.pro | 4 | ||||
-rw-r--r-- | noncore/apps/opie-console/procctl.cpp | 90 | ||||
-rw-r--r-- | noncore/apps/opie-console/procctl.h | 33 |
4 files changed, 125 insertions, 5 deletions
diff --git a/noncore/apps/opie-console/filetransfer.cpp b/noncore/apps/opie-console/filetransfer.cpp index 7b75d35..7fd9f37 100644 --- a/noncore/apps/opie-console/filetransfer.cpp +++ b/noncore/apps/opie-console/filetransfer.cpp @@ -23,223 +23,220 @@ public: }; */ bool FileTransfer::terminate = false; pid_t FileTransfer::m_pid; FileTransfer::FileTransfer( Type t, IOLayer* lay ) : FileTransferLayer( lay ), m_type( t ) { signal(SIGPIPE, SIG_IGN ); signal( SIGCHLD, signal_handler ); m_not = 0l; } FileTransfer::~FileTransfer() { } /** * now we will send the file. * * we request an fd. The IOLayer should be closed * then we will setup a pipe for progress communication * then we will dup2 the m_fd in the forked process * to do direct IO from and to the fd */ void FileTransfer::sendFile( const QString& file ) { m_prog =-1; m_fd = layer()->rawIO(); // // m_fd = ::open("/dev/ttyS0", O_RDWR); m_file = file; if ( pipe( m_comm ) < 0 ) m_comm[0] = m_comm[1] = 0; if ( pipe( m_info ) < 0 ) m_info[0] = m_info[1] = 0; m_pid = fork(); switch( m_pid ) { case -1: emit error( StartError, tr("Was not able to fork") ); break; case 0:{ setupChild(); qWarning("output:"+file ); /* exec */ char* verbose = "-vv"; char* binray = "-b"; /* we should never return from here */ execlp("sz", "sz", verbose, binray, file.latin1(), NULL ); /* communication for error!*/ char resultByte =1; if (m_info[1] ) write(m_info[1], &resultByte, 1 ); _exit( -1 ); break; } default:{ if ( m_info[1] ) close( m_info[1] ); if ( m_info[0] ) for (;;) { char resultByte; int len; len = read(m_info[0], &resultByte, 1 ); /* len == 1 start up failed */ if ( len == 1 ) { emit error( StartError, tr("Could not start") ); return; } if ( len == -1 ) if ( (errno == ECHILD ) || (errno == EINTR ) ) continue; // len == 0 or something like this break; } if ( m_info[0] ) close( m_info[0] ); terminate = false; fd_set fds; struct timeval timeout; int sel; /* replace by QSocketNotifier!!! */ m_not = new QSocketNotifier(m_comm[0], QSocketNotifier::Read ); connect(m_not, SIGNAL(activated(int) ), this, SLOT(slotRead() ) ); } break; } } /* * let's call the one with the filename */ void FileTransfer::sendFile( const QFile& file ) { sendFile( file.name() ); } /* * our signal handler to be replaced by * a procctl thingie */ void FileTransfer::signal_handler(int ) { qWarning("Terminated"); int status; signal( SIGCHLD, signal_handler ); waitpid( m_pid, &status, WNOHANG ); terminate = true; } /* * setting up communication * between parent child and ioLayer */ void FileTransfer::setupChild() { /* * we do not want to read from our * information channel */ if (m_info[0] ) close(m_info[0] ); /* * FD_CLOEXEC will close the * fd on successfull exec */ if (m_info[1] ) fcntl(m_info[1], F_SETFD, FD_CLOEXEC ); if (m_comm[0] ) close( m_comm[0] ); /* * now set the communication * m_fd STDIN_FILENO * STDOUT_FILENO * STDERR_FILENO */ dup2( m_fd, STDIN_FILENO ); dup2( m_fd, STDOUT_FILENO ); dup2( m_comm[1], STDERR_FILENO ); } /* * read from the stderr of the child * process */ void FileTransfer::slotRead() { QByteArray ar(4096); int len = read(m_comm[0], ar.data(), 4096 ); qWarning("slot read %d", len); for (int i = 0; i < len; i++ ) { // printf("%c", ar[i] ); } ar.resize( len ); QString str( ar ); QStringList lis = QStringList::split(' ', str ); /* * Transfer finished.. either complete or incomplete */ if ( lis[0].simplifyWhiteSpace() == "Transfer" ) { qWarning("sent!!!!"); emit sent(); return; } /* * do progress reading */ slotProgress( lis ); } /* * find the progress */ void FileTransfer::slotProgress( const QStringList& list ) { bool complete = true; int min, sec; int bps; unsigned long sent, total; min = sec = bps = -1; sent = total = 0; // Data looks like this // 0 1 2 3 4 5 // Bytes Sent 65536/11534336 BPS:7784 ETA 24:33 QStringList progi = QStringList::split('/', list[2].simplifyWhiteSpace() ); sent = progi[0].toULong(&complete ); if (!complete ) return; total = progi[1].toULong(&complete ); if (!complete || total == 0) { - qWarning("returning!!"); return; } qWarning("%s, %d, %d", progi.join("/").latin1(), sent, total ); double pro = (double)sent/total; int prog = pro * 100; // speed progi = QStringList::split(':', list[3].simplifyWhiteSpace() ); bps = progi[1].toInt(); // time progi = QStringList::split(':', list[5].simplifyWhiteSpace() ); min = progi[0].toInt(); sec = progi[1].toInt(); - qWarning("Prog!:%d", prog ); if ( prog > m_prog ) { m_prog = prog; emit progress(m_file, m_prog, bps, -1, min , sec ); - qWarning("Progress: %s, %d\%, %d, %d:%d", m_file.latin1(), m_prog, bps, min, sec ); } } void FileTransfer::cancel() { ::kill(m_pid,9 ); delete m_not; } diff --git a/noncore/apps/opie-console/opie-console.pro b/noncore/apps/opie-console/opie-console.pro index 37cef92..9208042 100644 --- a/noncore/apps/opie-console/opie-console.pro +++ b/noncore/apps/opie-console/opie-console.pro @@ -1,64 +1,64 @@ TEMPLATE = app #CONFIG = qt warn_on release CONFIG = qt debug DESTDIR = $(OPIEDIR)/bin HEADERS = io_layer.h io_serial.h io_irda.h \ file_layer.h filetransfer.h \ metafactory.h \ session.h \ mainwindow.h \ profile.h \ profileconfig.h \ profilemanager.h \ configwidget.h \ tabwidget.h \ configdialog.h \ emulation_layer.h \ vt102emulation.h \ common.h \ history.h \ screen.h \ keytrans.h \ widget_layer.h \ transferdialog.h \ profiledialogwidget.h \ profileeditordialog.h \ default.h \ terminalwidget.h \ iolayerbase.h \ serialconfigwidget.h irdaconfigwidget.h btconfigwidget.h \ - emulation_widget.h + emulation_widget.h procctl.h SOURCES = io_layer.cpp io_serial.cpp io_irda.cpp \ file_layer.cpp filetransfer.cpp \ main.cpp \ metafactory.cpp \ session.cpp \ mainwindow.cpp \ profile.cpp \ profileconfig.cpp \ profilemanager.cpp \ tabwidget.cpp \ configdialog.cpp \ emulation_layer.cpp \ vt102emulation.cpp \ history.cpp \ screen.cpp \ keytrans.cpp \ widget_layer.cpp \ transferdialog.cpp \ profiledialogwidget.cpp \ profileeditordialog.cpp \ default.cpp \ terminalwidget.cpp \ iolayerbase.cpp \ serialconfigwidget.cpp irdaconfigwidget.cpp btconfigwidget.cpp \ - emulation_widget.cpp + emulation_widget.cpp procctl.cpp INTERFACES = configurebase.ui editbase.ui INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include LIBS += -lqpe -lopie TARGET = opie-console diff --git a/noncore/apps/opie-console/procctl.cpp b/noncore/apps/opie-console/procctl.cpp new file mode 100644 index 0000000..6839a84 --- a/dev/null +++ b/noncore/apps/opie-console/procctl.cpp @@ -0,0 +1,90 @@ +#include <sys/wait.h> + +#include <fcntl.h> +#include <unistd.h> + +#include "procctl.h" + +ProcContainer *ProcCtl::m_last = 0; + +ProcCtl::ProcCtl() { + signal( SIGCHLD, signal_handler ); +} +ProcCtl::~ProcCtl() { +} +void ProcCtl::add(pid_t pi, int fd ) { + ProcContainer * con = new ProcContainer; + //memset(con, 0, sizeof(con) ); + con->pid = pi; + con->fd = fd; + con->status = 0; + con->prev = m_last; + + m_last = con; + +} +void ProcCtl::remove( pid_t pi ) { + /* + * We first check if the last item + * is equal to pi the we + * + */ + ProcContainer* con; + if (m_last->pid == pi ) { + con = m_last; + m_last = con->prev; + delete con; + return; + } + + con = m_last; + ProcContainer* forw = 0l; + while (con ) { + /* remove it */ + 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) { + 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; + } +} diff --git a/noncore/apps/opie-console/procctl.h b/noncore/apps/opie-console/procctl.h new file mode 100644 index 0000000..e2161f3 --- a/dev/null +++ b/noncore/apps/opie-console/procctl.h @@ -0,0 +1,33 @@ +#ifndef OPIE_PROC_CTL_H +#define OPIE_PROC_CTL_H + +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> + +#include <qmap.h> + + +struct ProcContainer { + pid_t pid; + int fd; + int status; + ProcContainer* prev; +}; + +class ProcCtl { +public: + ProcCtl(); + ~ProcCtl(); + + int status(pid_t)const; + void add( pid_t, int fd ); + void remove( pid_t ); + void remove( ProcContainer ); +private: + static void signal_handler(int); + static ProcContainer* m_last; +}; + +#endif |