00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025 #include <stdio.h>
00026
00027 #include "kprocio.h"
00028
00029 #include <kdebug.h>
00030 #include <qtextcodec.h>
00031
00032 KProcIO::KProcIO ( QTextCodec *_codec)
00033 : codec(_codec)
00034 {
00035 rbi=0;
00036 readsignalon=writeready=TRUE;
00037 outbuffer.setAutoDelete(true);
00038
00039 if (!codec)
00040 {
00041 codec = QTextCodec::codecForName("ISO 8859-1");
00042 if (!codec)
00043 {
00044 kdError(174) << "Can't create ISO 8859-1 codec!" << endl;
00045 }
00046 }
00047 }
00048
00049 KProcIO::~KProcIO()
00050 {
00051 }
00052
00053 void
00054 KProcIO::resetAll ()
00055 {
00056 if (isRunning())
00057 kill();
00058
00059 clearArguments();
00060 rbi=0;
00061 readsignalon=writeready=TRUE;
00062
00063 disconnect (this, SIGNAL (receivedStdout (KProcess *, char *, int)),
00064 this, SLOT (received (KProcess *, char *, int)));
00065
00066 disconnect (this, SIGNAL (receivedStderr (KProcess *, char *, int)),
00067 this, SLOT (received (KProcess *, char *, int)));
00068
00069 disconnect (this, SIGNAL (wroteStdin(KProcess *)),
00070 this, SLOT (sent (KProcess *)));
00071
00072 outbuffer.clear();
00073
00074 }
00075
00076 bool KProcIO::start (RunMode runmode, bool includeStderr)
00077 {
00078 connect (this, SIGNAL (receivedStdout (KProcess *, char *, int)),
00079 this, SLOT (received (KProcess *, char *, int)));
00080
00081 if (includeStderr)
00082 {
00083 connect (this, SIGNAL (receivedStderr (KProcess *, char *, int)),
00084 this, SLOT (received (KProcess *, char *, int)));
00085 }
00086
00087 connect (this, SIGNAL (wroteStdin(KProcess *)),
00088 this, SLOT (sent (KProcess *)));
00089
00090 return KProcess::start (runmode, KProcess::All);
00091 }
00092
00093 bool KProcIO::writeStdin (const QString &line, bool appendnewline)
00094 {
00095 return writeStdin(codec->fromUnicode(line), appendnewline);
00096 }
00097
00098 bool KProcIO::writeStdin (const QCString &line, bool appendnewline)
00099 {
00100 QCString *qs = new QCString(line);
00101
00102 if (appendnewline)
00103 {
00104 *qs += '\n';
00105 }
00106
00107 int l = qs->length();
00108 if (!l)
00109 {
00110 delete qs;
00111 return true;
00112 }
00113
00114 QByteArray *b = (QByteArray *) qs;
00115 b->truncate(l);
00116
00117 outbuffer.append(b);
00118
00119 if (writeready)
00120 {
00121 writeready=FALSE;
00122 return KProcess::writeStdin( b->data(), b->size() );
00123 }
00124 return true;
00125 }
00126
00127 bool KProcIO::writeStdin(const QByteArray &data)
00128 {
00129 if (!data.size())
00130 return true;
00131 QByteArray *b = new QByteArray(data);
00132 outbuffer.append(b);
00133
00134 if (writeready)
00135 {
00136 writeready=FALSE;
00137 return KProcess::writeStdin( b->data(), b->size() );
00138 }
00139 return true;
00140 }
00141
00142 void KProcIO::closeWhenDone()
00143 {
00144 if (writeready)
00145 {
00146 closeStdin();
00147 return;
00148 }
00149 outbuffer.append(0);
00150
00151 return;
00152 }
00153
00154 void KProcIO::sent(KProcess *)
00155 {
00156 outbuffer.removeFirst();
00157
00158 if (outbuffer.count()==0)
00159 {
00160 kdDebug(174) << "Empty" << endl;
00161 writeready=TRUE;
00162 }
00163 else
00164 {
00165 QByteArray *b = outbuffer.first();
00166 if (!b)
00167 {
00168 kdDebug(174) << "Closing" << endl;
00169 closeStdin();
00170 }
00171 else
00172 {
00173 kdDebug(174) << "Sending [" << b->size() << "]" << endl;
00174 KProcess::writeStdin(b->data(), b->size());
00175 }
00176 }
00177
00178 }
00179
00180 void KProcIO::received (KProcess *, char *buffer, int buflen)
00181 {
00182 recvbuffer += QCString(buffer, buflen+1);
00183
00184 controlledEmission();
00185 }
00186
00187 void KProcIO::ackRead ()
00188 {
00189 readsignalon=TRUE;
00190 if (needreadsignal || recvbuffer.length()!=0)
00191 controlledEmission();
00192 }
00193
00194 void KProcIO::controlledEmission ()
00195 {
00196 if (readsignalon)
00197 {
00198 needreadsignal=FALSE;
00199 readsignalon=FALSE;
00200 emit readReady (this);
00201 }
00202 else
00203 {
00204 needreadsignal=TRUE;
00205 }
00206 }
00207
00208 void KProcIO::enableReadSignals (bool enable)
00209 {
00210 readsignalon=enable;
00211
00212 if (enable && needreadsignal)
00213 emit readReady (this);
00214 }
00215
00216 int KProcIO::readln (QString &line, bool autoAck, bool *partial)
00217 {
00218 int len;
00219
00220 if (autoAck)
00221 readsignalon=TRUE;
00222
00223
00224
00225 len=recvbuffer.find ('\n',rbi)-rbi;
00226
00227 kdDebug(174) << "KPIO::readln" << endl;
00228
00229
00230 if ((len<0) &&
00231 ((unsigned int)rbi<recvbuffer.length()))
00232 {
00233 recvbuffer=recvbuffer.mid (rbi,recvbuffer.length()-rbi);
00234 rbi=0;
00235 if (partial)
00236 {
00237 len = recvbuffer.length();
00238 line = recvbuffer;
00239 recvbuffer = "";
00240 *partial = true;
00241 return len;
00242 }
00243 return -1;
00244 }
00245
00246 if (len>=0)
00247 {
00248 line = codec->toUnicode(recvbuffer.mid(rbi,len), len);
00249 rbi += len+1;
00250 if (partial)
00251 *partial = false;
00252 return len;
00253 }
00254
00255 recvbuffer="";
00256 rbi=0;
00257
00258
00259 return -1;
00260
00261 }
00262
00263 void KProcIO::virtual_hook( int id, void* data )
00264 { KProcess::virtual_hook( id, data ); }
00265
00266 #include "kprocio.moc"
00267