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