kprocio.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 1997 David Sweet <dsweet@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
00017 */
00018 
00019 // $Id: kprocio.cpp 465272 2005-09-29 09:47:40Z mueller $
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(); // Try Locale codec first
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); // Strip trailing null
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; //will stay off until read is acknowledged
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   //need to reduce the size of recvbuffer at some point...
00237 
00238   len=recvbuffer.find ('\n',rbi)-rbi;
00239 
00240   //kdDebug(174) << "KPIO::readln" << endl;
00241 
00242   //in case there's no '\n' at the end of the buffer
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   //-1 on return signals "no more data" not error
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 
KDE Home | KDE Accessibility Home | Description of Access Keys