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

📄 vk_process.cpp

📁 Linux平台下的内核及程序调试器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#if defined(VK_PROCESS_DEBUG)      qDebug( "VKProcessManager: install a SIGPIPE handler (SIG_IGN)" );#endif      act.sa_handler = QT_SIGNAL_IGNORE;      sigemptyset( &(act.sa_mask) );      sigaddset( &(act.sa_mask), SIGPIPE );      act.sa_flags = 0;      if ( sigaction( SIGPIPE, &act, &oldactPipe ) != 0 )         qWarning( "Error installing SIGPIPE handler" );   }     VKProcessManager::~VKProcessManager()      {         delete procList;         if ( sigchldFd[0] != 0 )            ::close( sigchldFd[0] );         if ( sigchldFd[1] != 0 )            ::close( sigchldFd[1] );         // restore SIGCHLD handler#if defined(VK_PROCESS_DEBUG)         qDebug( "VKProcessManager: restore old sigchild handler" );#endif         if ( sigaction( SIGCHLD, &oldactChld, 0 ) != 0 )            qWarning( "Error restoring SIGCHLD handler" );#if defined(VK_PROCESS_DEBUG)         qDebug( "VKProcessManager: restore old sigpipe handler" );#endif         if ( sigaction( SIGPIPE, &oldactPipe, 0 ) != 0 )            qWarning( "Error restoring SIGPIPE handler" );      }   void VKProcessManager::append( VKProc *p )      {         procList->append( p );#if defined(VK_PROCESS_DEBUG)         qDebug( "VKProcessManager: append process (procList.count(): %d)",                  procList->count() );#endif      }   void VKProcessManager::remove( VKProc *p )      {         procList->remove( p );#if defined(VK_PROCESS_DEBUG)         qDebug( "VKProcessManager: remove process (procList.count(): %d)",                  procList->count() );#endif         cleanup();      }   void VKProcessManager::cleanup()      {         if ( procList->count() == 0 ) {            QTimer::singleShot( 0, this, SLOT(removeMe()) );         }      }   void VKProcessManager::removeMe()      {         if ( procList->count() == 0 ) {            qRemovePostRoutine(vkprocess_cleanup);            VKProcessPrivate::procManager = 0;            delete this;         }      }   void VKProcessManager::sigchldHnd( int fd )      {         /* Disable the socket notifier to make sure that this function is            not called recursively -- this can happen, if you enter the event            loop in the slot connected to the processExited() signal (e.g. by            showing a modal dialog) and there are more than one process which            exited in the meantime. */         if ( sn ) {            if ( !sn->isEnabled() )               return;            sn->setEnabled( false );         }         char tmp;         ::read( fd, &tmp, sizeof(tmp) );#if defined(VK_PROCESS_DEBUG)         qDebug( "VKProcessManager::sigchldHnd()" );#endif         VKProc *proc;         VKProcess *process;         bool removeProc;         proc = procList->first();         while ( proc != 0 ) {            removeProc = false;            process = proc->process;            if ( process != 0 ) {               if ( !process->isRunning() ) {#if defined(VK_PROCESS_DEBUG)                  qDebug( "VKProcessManager::sigchldHnd() (PID: %d): process exited (VKProcess available)", proc->pid );#endif                  /* Apparently, there is not consistency among different                     operating systems on how to use FIONREAD.                     FreeBSD, Linux and Solaris all expect the 3rd argument to                     ioctl() to be an int, which is normally 32-bit even on                     64-bit machines.                     IRIX, on the other hand, expects a size_t, which is 64-bit                     on 64-bit machines.                     So, the solution is to use size_t initialized to zero to                     make sure all bits are set to zero, preventing underflow                     with the FreeBSD/Linux/Solaris ioctls. */                  size_t nbytes = 0;                  // read pending data                  if ( proc->socketFDout && ::ioctl(proc->socketFDout, FIONREAD,                                                     (char*)&nbytes)==0 && nbytes>0 ) {#if defined(VK_PROCESS_DEBUG)                     qDebug( "VKProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on FDout(%d)", proc->pid, nbytes, process->getFDout() );#endif                     process->socketRead( proc->socketFDout );                  }                          nbytes = 0;                  if ( proc->socketStdout && ::ioctl(proc->socketStdout, FIONREAD,                                                      (char*)&nbytes)==0 && nbytes>0 ) {#if defined(VK_PROCESS_DEBUG)                     qDebug( "VKProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stdout", proc->pid, nbytes );#endif                     process->socketRead( proc->socketStdout );                  }                  nbytes = 0;                  if ( proc->socketStderr && ::ioctl(proc->socketStderr, FIONREAD,                                                      (char*)&nbytes)==0 && nbytes>0 ) {#if defined(VK_PROCESS_DEBUG)                     qDebug( "VKProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stderr", proc->pid, nbytes );#endif                     process->socketRead( proc->socketStderr );                  }                  /* close filedescriptors if open, and disable the socket notifiers */                  if ( proc->socketFDout ) {                     ::close( proc->socketFDout );                     proc->socketFDout = 0;                     if (process->d->notifierFDout)                        process->d->notifierFDout->setEnabled(false);                  }                  if ( proc->socketStdout ) {                     ::close( proc->socketStdout );                     proc->socketStdout = 0;                     if (process->d->notifierStdout)                        process->d->notifierStdout->setEnabled(false);                  }                  if ( proc->socketStderr ) {                     ::close( proc->socketStderr );                     proc->socketStderr = 0;                     if (process->d->notifierStderr)                        process->d->notifierStderr->setEnabled(false);                  }                  if ( process->notifyOnExit )                     emit process->processExited();                  removeProc = true;               }            } else {               int status;               if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) {#if defined(VK_PROCESS_DEBUG)                  qDebug( "VKProcessManager::sigchldHnd() (PID: %d): process exited (VKProcess not available)", proc->pid );#endif                  removeProc = true;               }            }            if ( removeProc ) {               VKProc *oldproc = proc;               proc = procList->next();               remove( oldproc );            } else {               proc = procList->next();            }         }         if ( sn )            sn->setEnabled( true );      }   /* class VKProcessPrivate ---------------------------------------------------- */   VKProcessManager *VKProcessPrivate::procManager = 0;   VKProcessPrivate::VKProcessPrivate()      {#if defined(VK_PROCESS_DEBUG)         qDebug( "VKProcessPrivate: Constructor" );#endif         fdinBufRead = 0;         stdinBufRead = 0;         notifierFDin = 0;         notifierFDout = 0;         notifierStdin = 0;         notifierStdout = 0;         notifierStderr = 0;         exitValuesCalculated = false;         socketReadCalled = false;         proc = 0;      }   VKProcessPrivate::~VKProcessPrivate()      {#if defined(VK_PROCESS_DEBUG)         qDebug( "VKProcessPrivate: Destructor" );#endif         if ( proc != 0 ) {            if ( proc->socketFDin != 0 ) {               ::close( proc->socketFDin );               proc->socketFDin = 0;            }            if ( proc->socketStdin != 0 ) {               ::close( proc->socketStdin );               proc->socketStdin = 0;            }            proc->process = 0;         }         while ( !fdinBuf.isEmpty() ) {            delete fdinBuf.dequeue();         }         while ( !stdinBuf.isEmpty() ) {            delete stdinBuf.dequeue();         }         if (notifierFDin) {            delete notifierFDin;            notifierFDin = 0;         }         if (notifierStdin) {            delete notifierStdin;            notifierStdin = 0;         }         if (notifierFDout) {            delete notifierFDout;            notifierFDout = 0;         }         if (notifierStdout) {            delete notifierStdout;            notifierStdout = 0;         }         if (notifierStderr) {            delete notifierStderr;            notifierStderr = 0;         }      }   /* Closes all open sockets in the child process that are not needed by      the child process. Otherwise one child may have an open socket on      standard input, etc. of another child. */   void VKProcessPrivate::closeOpenSocketsForChild()      {         if ( procManager != 0 ) {            if ( procManager->sigchldFd[0] != 0 )               ::close( procManager->sigchldFd[0] );            if ( procManager->sigchldFd[1] != 0 )               ::close( procManager->sigchldFd[1] );                // close also the sockets from other VKProcess instances            for ( VKProc *p=procManager->procList->first(); p!=0;                   p=procManager->procList->next() ) {               ::close( p->socketFDin );               ::close( p->socketStdin );               ::close( p->socketFDout );               ::close( p->socketStdout );               ::close( p->socketStderr );            }         }      }   void VKProcessPrivate::newProc( pid_t pid, VKProcess *process )      {         proc = new VKProc( pid, process );         if ( procManager == 0 ) {            procManager = new VKProcessManager;            qAddPostRoutine(vkprocess_cleanup);         }         // the VKProcessManager takes care of deleting the VKProc instances         procManager->append( proc );      }   /* class VKProcess -----------------------------------------------------------      Constructs a VKProcess object. The parent and name parameters are      passed to the QObject constructor. */   VKProcess::VKProcess( QObject* parent, const char* name )      : QObject( parent, name ),       ioRedirection( false ),       notifyOnExit( false ),      wroteToFDinConnected( false ),       wroteToStdinConnected( false ),      readFDoutCalled( false ),       readStdoutCalled( false ),       readStderrCalled( false ),      comms( Stdin|Stdout|Stderr ),      filedesc_in( 0 ),       filedesc_out( 1 ),      disabledStdin( false ),       disabledStdout( false ),       disabledStderr( false )      { init(); }   /* Constructs a VKProcess with arg0 as the command to be executed. The      parent and name parameters are passed to the QObject constructor.      The process is not started. You must call start() or launch() to      start the process. */   VKProcess::VKProcess( const QString& arg0, QObject *parent, const char *name )      : QObject( parent, name ), ioRedirection( false ), notifyOnExit( false ),      wroteToFDinConnected( false ), wroteToStdinConnected( false ),      readFDoutCalled( false ), readStdoutCalled( false ), readStderrCalled( false ),      comms( Stdin|Stdout|Stderr ),      filedesc_in( 0 ), filedesc_out( 1 ),      disabledStdin( false ), disabledStdout( false ), disabledStderr( false )      {         init();         addArgument( arg0 );      }   /* Constructs a VKProcess with args as the arguments of the      process. The first element in the list is the command to be      executed. The other elements in the list are the arguments to this      command. The parent and name parameters are passed to the QObject      constructor.      The process is not started. You must call start() or launch() to      start the process. */   VKProcess::VKProcess( const QStringList& args, QObject *parent, const char *name )      : QObject( parent, name ), ioRedirection( false ), notifyOnExit( false ),      wroteToFDinConnected( false ), wroteToStdinConnected( false ),      readFDoutCalled( false ), readStdoutCalled( false ), readStderrCalled( false ),      comms( Stdin|Stdout|Stderr ),      filedesc_in( 0 ), filedesc_out( 1 ),      disabledStdin( false ), disabledStdout( false ), disabledStderr( false )      {         init();         setArguments( args );      }   /* This private class does basic initialization. */

⌨️ 快捷键说明

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