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