summaryrefslogtreecommitdiff
authorzecke <zecke>2002-10-12 00:30:06 (UTC)
committer zecke <zecke>2002-10-12 00:30:06 (UTC)
commit0a3ffe7e5657bed4cb77d9bc23457755e2d02591 (patch) (side-by-side diff)
treea1b83e61035433668ca5c9e3af31586880535c98
parentffa7f45a2100b7c438a437fce2d3a47608bd36e3 (diff)
downloadopie-0a3ffe7e5657bed4cb77d9bc23457755e2d02591.zip
opie-0a3ffe7e5657bed4cb77d9bc23457755e2d02591.tar.gz
opie-0a3ffe7e5657bed4cb77d9bc23457755e2d02591.tar.bz2
This is targetted to the people telling
in computer science classes that I'm toolkit dependant This is a Process Controller which will be used to work around the limit of only beeing able to do one FileTransfer at a Time
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/filetransfer.cpp3
-rw-r--r--noncore/apps/opie-console/opie-console.pro4
-rw-r--r--noncore/apps/opie-console/procctl.cpp90
-rw-r--r--noncore/apps/opie-console/procctl.h33
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