summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-console/filereceive.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-console/filereceive.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-console/filereceive.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/noncore/apps/opie-console/filereceive.cpp b/noncore/apps/opie-console/filereceive.cpp
new file mode 100644
index 0000000..26b3dec
--- a/dev/null
+++ b/noncore/apps/opie-console/filereceive.cpp
@@ -0,0 +1,159 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include <signal.h>
4#include <errno.h>
5
6#include <qsocketnotifier.h>
7
8#include "io_layer.h"
9#include "procctl.h"
10#include "filereceive.h"
11
12FileReceive::FileReceive( Type t, IOLayer* lay, const QString& dir )
13 : ReceiveLayer(lay, dir ), m_type( t )
14{
15 m_fd = -1;
16 m_not = 0l;
17 m_proc = 0l;
18}
19FileReceive::~FileReceive() {
20}
21void FileReceive::receive() {
22 receive( currentDir() );
23}
24void FileReceive::receive( const QString& dir ) {
25 m_prog = -1;
26 m_fd = layer()->rawIO();
27 m_curDir = dir;
28
29 if (pipe( m_comm ) < 0 )
30 m_comm[0] = m_comm[1] = 0;
31 if (pipe( m_info ) < 0 )
32 m_info[0] = m_info[1] = 0;
33
34 m_pid = fork();
35 switch( m_pid ) {
36 case -1:
37 //emit error
38 slotExec();
39 break;
40 /* child */
41 case 0: {
42 setupChild();
43 char* typus = NULL;
44 switch(m_type ) {
45 case SZ:
46 break;
47 case SX:
48 typus = "-X";
49 break;
50 case SY:
51 typus = "--ymodem";
52 break;
53 }
54
55 /* we should never return from here */
56 execlp("rz", "rz", typus, NULL );
57
58 char resultByte = 1;
59 if (m_info[1] )
60 ::write(m_info[1], &resultByte, 1 );
61
62 _exit( -1 );
63 break;
64 }
65 default: {
66 if ( m_info[1] )
67 close( m_info[1] );
68
69 if ( m_info[0] ) for (;;) {
70 char resultByte; int len;
71 len = read(m_info[0], &resultByte, 1 );
72 /* len == 1 start up failed */
73 if ( len == 1 ) {
74 emit error( StartError, tr("Could not start") );
75 return;
76 }
77 if ( len == -1 )
78 if ( (errno == ECHILD ) || (errno == EINTR ) )
79 continue;
80
81 // len == 0 or something like this
82 break;
83 }
84
85 if ( m_info[0] )
86 close( m_info[0] );
87
88 m_not = new QSocketNotifier(m_comm[0], QSocketNotifier::Read );
89 connect(m_not, SIGNAL(activated(int) ),
90 this, SLOT(slotRead() ) );
91 if ( pipe(m_term) < 0 )
92 m_term[0] = m_term[1] = 0;
93
94 ProcCtl::self()->add(m_pid, m_term[1] );
95 m_proc = new QSocketNotifier(m_term[0], QSocketNotifier::Read );
96 connect(m_proc, SIGNAL(activated(int) ),
97 this, SLOT(slotExec() ) );
98
99 }
100 break;
101
102 }
103
104}
105void FileReceive::cancel() {
106 ::kill(m_pid, 9 );
107}
108void FileReceive::setupChild() {
109 changeDir( currentDir() );
110 /*
111 * we do not want to read from our
112 * information channel
113 */
114 if (m_info[0] )
115 close(m_info[0] );
116 /*
117 * FD_CLOEXEC will close the
118 * fd on successfull exec
119 */
120 if (m_info[1] )
121 fcntl(m_info[1], F_SETFD, FD_CLOEXEC );
122
123 if (m_comm[0] )
124 close( m_comm[0] );
125 /*
126 * now set the communication
127 * m_fd STDIN_FILENO
128 * STDOUT_FILENO
129 * STDERR_FILENO
130 */
131 dup2( m_fd, STDIN_FILENO );
132 dup2( m_fd, STDOUT_FILENO );
133 dup2( m_comm[1], STDERR_FILENO );
134}
135void FileReceive::slotRead() {
136 QByteArray ar(4096);
137 int len = read(m_comm[0], ar.data(), 4096 );
138 qWarning("slot read %d", len);
139 for (int i = 0; i < len; i++ ) {
140 // printf("%c", ar[i] );
141 }
142 ar.resize( len );
143 QString str( ar );
144 qWarning(str.simplifyWhiteSpace() );
145}
146void FileReceive::slotExec() {
147 char buf[2];
148 ::read(m_term[0], buf, 1 );
149 delete m_proc;
150 delete m_not;
151 m_not = m_proc = 0l;
152 close( m_term[0] );
153 close( m_term[1] );
154 close( m_comm[0] );
155 close( m_comm[1] );
156 layer()->closeRawIO(m_fd);
157 emit received(QString::null);
158
159}