⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q3process_unix.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		this, SLOT(socketWrite(int)) );	// setup notifiers for the sockets	if ( !d->stdinBuf.isEmpty() ) {	    d->notifierStdin->setEnabled( true );	}    }    if ( comms & Stdout ) {	::close( sStdout[1] );	d->proc->socketStdout = sStdout[0];	d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read );	connect( d->notifierStdout, SIGNAL(activated(int)),		this, SLOT(socketRead(int)) );	if ( ioRedirection )	    d->notifierStdout->setEnabled( true );    }    if ( comms & Stderr ) {	::close( sStderr[1] );	d->proc->socketStderr = sStderr[0];	d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read );	connect( d->notifierStderr, SIGNAL(activated(int)),		this, SLOT(socketRead(int)) );	if ( ioRedirection )	    d->notifierStderr->setEnabled( true );    }    // cleanup and return    delete[] arglistQ;    delete[] arglist;    return true;error:#if defined(QT_Q3PROCESS_DEBUG)    qDebug( "Q3Process::start(): error starting process" );#endif    if ( d->procManager )	d->procManager->cleanup();    if ( comms & Stdin ) {	::close( sStdin[1] );	::close( sStdin[0] );    }    if ( comms & Stdout ) {	::close( sStdout[0] );	::close( sStdout[1] );    }    if ( comms & Stderr ) {	::close( sStderr[0] );	::close( sStderr[1] );    }    ::close( fd[0] );    ::close( fd[1] );    delete[] arglistQ;    delete[] arglist;    return false;}/*!    Asks the process to terminate. Processes can ignore this if they    wish. If you want to be certain that the process really    terminates, you can use kill() instead.    The slot returns immediately: it does not wait until the process    has finished. When the process terminates, the processExited()    signal is emitted.    \sa kill() processExited()*/void Q3Process::tryTerminate() const{    if ( d->proc != 0 )	::kill( d->proc->pid, SIGTERM );}/*!    Terminates the process. This is not a safe way to end a process    since the process will not be able to do any cleanup.    tryTerminate() is safer, but processes can ignore a    tryTerminate().    The nice way to end a process and to be sure that it is finished,    is to do something like this:    \code	process->tryTerminate();	QTimer::singleShot( 5000, process, SLOT(kill()) );    \endcode    This tries to terminate the process the nice way. If the process    is still running after 5 seconds, it terminates the process the    hard way. The timeout should be chosen depending on the time the    process needs to do all its cleanup: use a higher value if the    process is likely to do a lot of computation or I/O on cleanup.    The slot returns immediately: it does not wait until the process    has finished. When the process terminates, the processExited()    signal is emitted.    \sa tryTerminate() processExited()*/void Q3Process::kill() const{    if ( d->proc != 0 )	::kill( d->proc->pid, SIGKILL );}/*!    Returns true if the process is running; otherwise returns false.    \sa normalExit() exitStatus() processExited()*/bool Q3Process::isRunning() const{    if ( d->exitValuesCalculated ) {#if defined(QT_Q3PROCESS_DEBUG)	qDebug( "Q3Process::isRunning(): false (already computed)" );#endif	return false;    }    if ( d->proc == 0 )	return false;    int status;    if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid ) {	// compute the exit values	Q3Process *that = (Q3Process*)this; // mutable	that->exitNormal = WIFEXITED( status ) != 0;	if ( exitNormal ) {	    that->exitStat = (char)WEXITSTATUS( status );	}	d->exitValuesCalculated = true;	// On heavy processing, the socket notifier for the sigchild might not	// have found time to fire yet.	if ( d->procManager && d->procManager->sigchldFd[1] < FD_SETSIZE ) {	    fd_set fds;	    struct timeval tv;	    FD_ZERO( &fds );	    FD_SET( d->procManager->sigchldFd[1], &fds );	    tv.tv_sec = 0;	    tv.tv_usec = 0;	    if ( ::select( d->procManager->sigchldFd[1]+1, &fds, 0, 0, &tv ) > 0 )		d->procManager->sigchldHnd( d->procManager->sigchldFd[1] );	}#if defined(QT_Q3PROCESS_DEBUG)	qDebug( "Q3Process::isRunning() (PID: %d): false", d->proc->pid );#endif	return false;    }#if defined(QT_Q3PROCESS_DEBUG)    qDebug( "Q3Process::isRunning() (PID: %d): true", d->proc->pid );#endif    return true;}/*!    Returns true if it's possible to read an entire line of text from    standard output at this time; otherwise returns false.    \sa readLineStdout() canReadLineStderr()*/bool Q3Process::canReadLineStdout() const{    if ( !d->proc || !d->proc->socketStdout )	return d->bufStdout.size() != 0;    Q3Process *that = (Q3Process*)this;    return that->membufStdout()->scanNewline( 0 );}/*!    Returns true if it's possible to read an entire line of text from    standard error at this time; otherwise returns false.    \sa readLineStderr() canReadLineStdout()*/bool Q3Process::canReadLineStderr() const{    if ( !d->proc || !d->proc->socketStderr )	return d->bufStderr.size() != 0;    Q3Process *that = (Q3Process*)this;    return that->membufStderr()->scanNewline( 0 );}/*!    Writes the data \a buf to the process's standard input. The    process may or may not read this data.    This function returns immediately; the Q3Process class might write    the data at a later point (you must enter the event loop for this    to occur). When all the data is written to the process, the signal    wroteToStdin() is emitted. This does not mean that the process    actually read the data, since this class only detects when it was    able to write the data to the operating system.    \sa wroteToStdin() closeStdin() readStdout() readStderr()*/void Q3Process::writeToStdin( const QByteArray& buf ){#if defined(QT_Q3PROCESS_DEBUG)//    qDebug( "Q3Process::writeToStdin(): write to stdin (%d)", d->socketStdin );#endif    d->stdinBuf.enqueue( new QByteArray(buf) );    if ( d->notifierStdin != 0 )	d->notifierStdin->setEnabled( true );}/*!    Closes the process's standard input.    This function also deletes any pending data that has not been    written to standard input.    \sa wroteToStdin()*/void Q3Process::closeStdin(){    if ( d->proc == 0 )	return;    if ( d->proc->socketStdin !=0 ) {	while ( !d->stdinBuf.isEmpty() ) {	    delete d->stdinBuf.dequeue();	}	delete d->notifierStdin;	d->notifierStdin = 0;	if ( ::close( d->proc->socketStdin ) != 0 ) {	    qWarning( "Could not close stdin of child process" );	}#if defined(QT_Q3PROCESS_DEBUG)	qDebug( "Q3Process::closeStdin(): stdin (%d) closed", d->proc->socketStdin );#endif	d->proc->socketStdin = 0;    }}/*  This private slot is called when the process has outputted data to either  standard output or standard error.*/void Q3Process::socketRead( int fd ){    if ( d->socketReadCalled ) {	// the slots that are connected to the readyRead...() signals might	// trigger a recursive call of socketRead(). Avoid this since you get a	// blocking read otherwise.	return;    }#if defined(QT_Q3PROCESS_DEBUG)    qDebug( "Q3Process::socketRead(): %d", fd );#endif    if ( fd == 0 )	return;    if ( !d->proc )	return;    Q3Membuf *buffer = 0;    int n;    if ( fd == d->proc->socketStdout ) {	buffer = &d->bufStdout;    } else if ( fd == d->proc->socketStderr ) {	buffer = &d->bufStderr;    } else {	// this case should never happen, but just to be safe	return;    }#if defined(QT_Q3PROCESS_DEBUG)    uint oldSize = buffer->size();#endif    // try to read data first (if it fails, the filedescriptor was closed)    const int basize = 4096;    QByteArray *ba = new QByteArray( basize );    n = ::read( fd, ba->data(), basize );    if ( n > 0 ) {	ba->resize( n );	buffer->append( ba );	ba = 0;    } else {	delete ba;	ba = 0;    }    // eof or error?    if ( n == 0 || n == -1 ) {	if ( fd == d->proc->socketStdout ) {#if defined(QT_Q3PROCESS_DEBUG)	    qDebug( "Q3Process::socketRead(): stdout (%d) closed", fd );#endif	    d->notifierStdout->setEnabled( false );	    delete d->notifierStdout;	    d->notifierStdout = 0;	    ::close( d->proc->socketStdout );	    d->proc->socketStdout = 0;	    return;	} else if ( fd == d->proc->socketStderr ) {#if defined(QT_Q3PROCESS_DEBUG)	    qDebug( "Q3Process::socketRead(): stderr (%d) closed", fd );#endif	    d->notifierStderr->setEnabled( false );	    delete d->notifierStderr;	    d->notifierStderr = 0;	    ::close( d->proc->socketStderr );	    d->proc->socketStderr = 0;	    return;	}    }    if ( fd < FD_SETSIZE ) {	fd_set fds;	struct timeval tv;	FD_ZERO( &fds );	FD_SET( fd, &fds );	tv.tv_sec = 0;	tv.tv_usec = 0;	while ( ::select( fd+1, &fds, 0, 0, &tv ) > 0 ) {	    // prepare for the next round	    FD_ZERO( &fds );	    FD_SET( fd, &fds );	    // read data	    ba = new QByteArray( basize );	    n = ::read( fd, ba->data(), basize );	    if ( n > 0 ) {		ba->resize( n );		buffer->append( ba );		ba = 0;	    } else {		delete ba;		ba = 0;		break;	    }	}    }    d->socketReadCalled = true;    if ( fd == d->proc->socketStdout ) {#if defined(QT_Q3PROCESS_DEBUG)	qDebug( "Q3Process::socketRead(): %d bytes read from stdout (%d)",		buffer->size()-oldSize, fd );#endif	emit readyReadStdout();    } else if ( fd == d->proc->socketStderr ) {#if defined(QT_Q3PROCESS_DEBUG)	qDebug( "Q3Process::socketRead(): %d bytes read from stderr (%d)",		buffer->size()-oldSize, fd );#endif	emit readyReadStderr();    }    d->socketReadCalled = false;}/*  This private slot is called when the process tries to read data from standard  input.*/void Q3Process::socketWrite( int fd ){    while ( fd == d->proc->socketStdin && d->proc->socketStdin != 0 ) {	if ( d->stdinBuf.isEmpty() ) {	    d->notifierStdin->setEnabled( false );	    return;	}	ssize_t ret = ::write( fd,		d->stdinBuf.head()->data() + d->stdinBufRead,		d->stdinBuf.head()->size() - d->stdinBufRead );#if defined(QT_Q3PROCESS_DEBUG)	qDebug( "Q3Process::socketWrite(): wrote %d bytes to stdin (%d)", ret, fd );#endif	if ( ret == -1 )	    return;	d->stdinBufRead += ret;	if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) {	    d->stdinBufRead = 0;	    delete d->stdinBuf.dequeue();	    if ( wroteToStdinConnected && d->stdinBuf.isEmpty() )		emit wroteToStdin();	}    }}/*!  \internal  Flushes standard input. This is useful if you want to use Q3Process in a  synchronous manner.  This function should probably go into the public API.*/void Q3Process::flushStdin(){    if (d->proc)        socketWrite(d->proc->socketStdin);}/*  This private slot is only used under Windows (but moc does not know about #if  defined()).*/void Q3Process::timeout(){}/*  This private function is used by connectNotify() and disconnectNotify() to  change the value of ioRedirection (and related behaviour)*/void Q3Process::setIoRedirection( bool value ){    ioRedirection = value;    if ( ioRedirection ) {	if ( d->notifierStdout )	    d->notifierStdout->setEnabled( true );	if ( d->notifierStderr )	    d->notifierStderr->setEnabled( true );    } else {	if ( d->notifierStdout )	    d->notifierStdout->setEnabled( false );	if ( d->notifierStderr )	    d->notifierStderr->setEnabled( false );    }}/*  This private function is used by connectNotify() and  disconnectNotify() to change the value of notifyOnExit (and related  behaviour)*/void Q3Process::setNotifyOnExit( bool value ){    notifyOnExit = value;}/*  This private function is used by connectNotify() and disconnectNotify() to  change the value of wroteToStdinConnected (and related behaviour)*/void Q3Process::setWroteStdinConnected( bool value ){    wroteToStdinConnected = value;}/*!    \typedef Q3Process::PID    \internal*//*!    Returns platform dependent information about the process. This can    be used together with platform specific system calls.    Under Unix the return value is the PID of the process, or -1 if no    process belongs to this object.    Under Windows it is a pointer to the \c PROCESS_INFORMATION    struct, or 0 if no process is belongs to this object.    Use of this function's return value is likely to be non-portable.*/Q3Process::PID Q3Process::processIdentifier(){    if ( d->proc == 0 )	return -1;    return d->proc->pid;}#endif // QT_NO_PROCESS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -