kjavaprocess.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kjavaprocess.h"
00023
00024 #include <kdebug.h>
00025 #include <kio/kprotocolmanager.h>
00026
00027 #include <qtextstream.h>
00028 #include <qmap.h>
00029
00030 #include <config.h>
00031
00032 #include <unistd.h>
00033 #include <qptrlist.h>
00034
00035 class KJavaProcessPrivate
00036 {
00037 friend class KJavaProcess;
00038 private:
00039 QString jvmPath;
00040 QString classPath;
00041 QString mainClass;
00042 QString extraArgs;
00043 QString classArgs;
00044 QPtrList<QByteArray> BufferList;
00045 QMap<QString, QString> systemProps;
00046 bool processKilled;
00047 };
00048
00049 KJavaProcess::KJavaProcess() : KProcess()
00050 {
00051 d = new KJavaProcessPrivate;
00052 d->BufferList.setAutoDelete( true );
00053 d->processKilled = false;
00054
00055 javaProcess = this;
00056
00057 connect( javaProcess, SIGNAL( wroteStdin( KProcess * ) ),
00058 this, SLOT( slotWroteData() ) );
00059 connect( javaProcess, SIGNAL( receivedStdout( int, int& ) ),
00060 this, SLOT( slotReceivedData(int, int&) ) );
00061 connect( javaProcess, SIGNAL( processExited (KProcess *) ),
00062 this, SLOT( slotExited (KProcess *) ) );
00063
00064 d->jvmPath = "java";
00065 d->mainClass = "-help";
00066 }
00067
00068 KJavaProcess::~KJavaProcess()
00069 {
00070 if ( isRunning() )
00071 {
00072 kdDebug(6100) << "stopping java process" << endl;
00073 stopJava();
00074 }
00075
00076
00077 delete d;
00078 }
00079
00080 bool KJavaProcess::isRunning()
00081 {
00082 return javaProcess->isRunning();
00083 }
00084
00085 bool KJavaProcess::startJava()
00086 {
00087 return invokeJVM();
00088 }
00089
00090 void KJavaProcess::stopJava()
00091 {
00092 killJVM();
00093 }
00094
00095 void KJavaProcess::setJVMPath( const QString& path )
00096 {
00097 d->jvmPath = path;
00098 }
00099
00100 void KJavaProcess::setClasspath( const QString& classpath )
00101 {
00102 d->classPath = classpath;
00103 }
00104
00105 void KJavaProcess::setSystemProperty( const QString& name,
00106 const QString& value )
00107 {
00108 d->systemProps.insert( name, value );
00109 }
00110
00111 void KJavaProcess::setMainClass( const QString& className )
00112 {
00113 d->mainClass = className;
00114 }
00115
00116 void KJavaProcess::setExtraArgs( const QString& args )
00117 {
00118 d->extraArgs = args;
00119 }
00120
00121 void KJavaProcess::setClassArgs( const QString& args )
00122 {
00123 d->classArgs = args;
00124 }
00125
00126
00127 QByteArray* KJavaProcess::addArgs( char cmd_code, const QStringList& args )
00128 {
00129
00130 QByteArray* buff = new QByteArray();
00131 QTextOStream output( *buff );
00132 char sep = 0;
00133
00134
00135 QCString space( " " );
00136 output << space;
00137
00138
00139 output << cmd_code;
00140
00141
00142 if( args.isEmpty() )
00143 {
00144 output << sep;
00145 }
00146 else
00147 {
00148 for( QStringList::ConstIterator it = args.begin();
00149 it != args.end(); ++it )
00150 {
00151 if( !(*it).isEmpty() )
00152 {
00153 output << (*it).local8Bit();
00154 }
00155 output << sep;
00156 }
00157 }
00158
00159 return buff;
00160 }
00161
00162 void KJavaProcess::storeSize( QByteArray* buff )
00163 {
00164 int size = buff->size() - 8;
00165 QString size_str = QString("%1").arg( size, 8 );
00166 kdDebug(6100) << "KJavaProcess::storeSize, size = " << size_str << endl;
00167
00168 const char* size_ptr = size_str.latin1();
00169 for( int i = 0; i < 8; i++ )
00170 buff->at(i) = size_ptr[i];
00171 }
00172
00173 void KJavaProcess::sendBuffer( QByteArray* buff )
00174 {
00175 d->BufferList.append( buff );
00176 if( d->BufferList.count() == 1)
00177 {
00178 popBuffer();
00179 }
00180 }
00181
00182 void KJavaProcess::send( char cmd_code, const QStringList& args )
00183 {
00184 if( isRunning() )
00185 {
00186 QByteArray* buff = addArgs( cmd_code, args );
00187 storeSize( buff );
00188 kdDebug(6100) << "<KJavaProcess::send " << (int)cmd_code << endl;
00189 sendBuffer( buff );
00190 }
00191 }
00192
00193 void KJavaProcess::send( char cmd_code, const QStringList& args,
00194 const QByteArray& data )
00195 {
00196 if( isRunning() )
00197 {
00198 kdDebug(6100) << "KJavaProcess::send, qbytearray is size = " << data.size() << endl;
00199
00200 QByteArray* buff = addArgs( cmd_code, args );
00201 int cur_size = buff->size();
00202 int data_size = data.size();
00203 buff->resize( cur_size + data_size );
00204 memcpy( buff->data() + cur_size, data.data(), data_size );
00205
00206 storeSize( buff );
00207 sendBuffer( buff );
00208 }
00209 }
00210
00211 void KJavaProcess::popBuffer()
00212 {
00213 QByteArray* buf = d->BufferList.first();
00214 if( buf )
00215 {
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 if ( !javaProcess->writeStdin( buf->data(),
00231 buf->size() ) )
00232 {
00233 kdError(6100) << "Could not write command" << endl;
00234 }
00235 }
00236 }
00237
00238 void KJavaProcess::slotWroteData( )
00239 {
00240
00241 d->BufferList.removeFirst();
00242 kdDebug(6100) << "slotWroteData " << d->BufferList.count() << endl;
00243
00244 if ( !d->BufferList.isEmpty() )
00245 {
00246 popBuffer();
00247 }
00248 }
00249
00250
00251 bool KJavaProcess::invokeJVM()
00252 {
00253
00254 *javaProcess << d->jvmPath;
00255
00256 if( !d->classPath.isEmpty() )
00257 {
00258 *javaProcess << "-classpath";
00259 *javaProcess << d->classPath;
00260 }
00261
00262
00263 for( QMap<QString,QString>::Iterator it = d->systemProps.begin();
00264 it != d->systemProps.end(); ++it )
00265 {
00266 QString currarg;
00267
00268 if( !it.key().isEmpty() )
00269 {
00270 currarg = "-D" + it.key();
00271 if( !it.data().isEmpty() )
00272 currarg += "=" + it.data();
00273 }
00274
00275 if( !currarg.isEmpty() )
00276 *javaProcess << currarg;
00277 }
00278
00279
00280 if( !d->extraArgs.isEmpty() )
00281 {
00282
00283
00284 QStringList args = QStringList::split( " ", d->extraArgs );
00285 for ( QStringList::Iterator it = args.begin(); it != args.end(); ++it )
00286 *javaProcess << *it;
00287 }
00288
00289 *javaProcess << d->mainClass;
00290
00291 if ( !d->classArgs.isNull() )
00292 *javaProcess << d->classArgs;
00293
00294 kdDebug(6100) << "Invoking JVM now...with arguments = " << endl;
00295 QString argStr;
00296 QTextOStream stream( &argStr );
00297 QValueList<QCString> args = javaProcess->args();
00298 qCopy( args.begin(), args.end(), QTextOStreamIterator<QCString>( stream, " " ) );
00299 kdDebug(6100) << argStr << endl;
00300
00301 KProcess::Communication flags = (KProcess::Communication)
00302 (KProcess::Stdin | KProcess::Stdout |
00303 KProcess::NoRead);
00304
00305 bool rval = javaProcess->start( KProcess::NotifyOnExit, flags );
00306 if( rval )
00307 javaProcess->resume();
00308 else
00309 killJVM();
00310
00311 return rval;
00312 }
00313
00314 void KJavaProcess::killJVM()
00315 {
00316 d->processKilled = true;
00317 disconnect( javaProcess, SIGNAL( receivedStdout( int, int& ) ),
00318 this, SLOT( slotReceivedData(int, int&) ) );
00319 javaProcess->kill();
00320 }
00321
00322 void KJavaProcess::flushBuffers()
00323 {
00324 while ( !d->BufferList.isEmpty() )
00325 slotSendData(0);
00326 }
00327
00328
00329
00330
00331 void KJavaProcess::slotReceivedData( int fd, int& len )
00332 {
00333
00334
00335 char length[9] = { 0 };
00336 int num_bytes = ::read( fd, length, 8 );
00337 if( !num_bytes )
00338 {
00339 len = 0;
00340 return;
00341 }
00342 if( num_bytes == -1 )
00343 {
00344 kdError(6100) << "could not read 8 characters for the message length!!!!" << endl;
00345 len = 0;
00346 return;
00347 }
00348
00349 QString lengthstr( length );
00350 bool ok;
00351 int num_len = lengthstr.toInt( &ok );
00352 if( !ok )
00353 {
00354 kdError(6100) << "could not parse length out of: " << lengthstr << endl;
00355 len = num_bytes;
00356 return;
00357 }
00358
00359
00360 char* msg = new char[num_len];
00361 int num_bytes_msg = ::read( fd, msg, num_len );
00362 if( num_bytes_msg == -1 || num_bytes_msg != num_len )
00363 {
00364 kdError(6100) << "could not read the msg, num_bytes_msg = " << num_bytes_msg << endl;
00365 delete[] msg;
00366 len = num_bytes;
00367 return;
00368 }
00369
00370 QByteArray qb;
00371 emit received( qb.duplicate( msg, num_len ) );
00372 delete[] msg;
00373 len = num_bytes + num_bytes_msg;
00374 }
00375
00376 void KJavaProcess::slotExited( KProcess *process )
00377 {
00378 if (process == javaProcess) {
00379 int status = -1;
00380 if (!d->processKilled) {
00381 status = javaProcess->exitStatus();
00382 }
00383 kdDebug(6100) << "jvm exited with status " << status << endl;
00384 emit exited(status);
00385 }
00386 }
00387
00388 #include "kjavaprocess.moc"
This file is part of the documentation for khtml Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 23 17:13:18 2004 by
doxygen 1.3.8-20040913 written by
Dimitri van Heesch, © 1997-2003