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

📄 vk_process.cpp

📁 Linux平台下的内核及程序调试器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      the environment variable LD_LIBRARY_PATH, then this variable is      inherited from the starting process; under Windows the same applies      for the environment variable PATH.      Returns true if the process could be started; otherwise returns      false.      You can write data to the process's standard input with      writeToStdin(). You can close standard input with closeStdin() and      you can terminate the process with tryTerminate(), or with kill().      You can call this function even if you've used this instance to      create a another process which is still running. In such cases,      VKProcess closes the old process's standard input and deletes      pending data, i.e., you lose all control over the old process, but      the old process is not terminated. This applies also if the process      could not be started. (On operating systems that have zombie      processes, Qt will also wait() on the old process.) */   bool VKProcess::start( QStringList *env )      {#if defined(VK_PROCESS_DEBUG)         qDebug( "VKProcess::start()" );#endif         reset();         int sFDin[2];         int sStdin[2];         int sFDout[2];         int sStdout[2];         int sStderr[2];         // open sockets for piping#ifndef Q_OS_QNX6         if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) {#else            if ( (comms & Stdin) && qnx6SocketPairReplacement(sStdin) == -1 ) {#endif               return false;            }#ifndef Q_OS_QNX6            if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) {#else               if ( (comms & Stderr) && qnx6SocketPairReplacement(sStderr) == -1 ) {#endif                  if ( comms & Stdin ) {                     ::close( sStdin[0] );                     ::close( sStdin[1] );                  }                  return false;               }#ifndef Q_OS_QNX6               if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) {#else                  if ( (comms & Stdout) && qnx6SocketPairReplacement(sStdout) == -1 ) {#endif                     if ( comms & Stdin ) {                        ::close( sStdin[0] );                        ::close( sStdin[1] );                     }                     if ( comms & Stderr ) {                        ::close( sStderr[0] );                        ::close( sStderr[1] );                     }                     return false;                  }#ifndef Q_OS_QNX6                  if ( (comms & FDin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sFDin ) == -1 ) {#else                     if ( (comms & FDin) && qnx6SocketPairReplacement(sFDin) == -1 ) {#endif                        if ( comms & Stdin ) {                           ::close( sStdin[0] );                           ::close( sStdin[1] );                        }                        if ( comms & Stderr ) {                           ::close( sStderr[0] );                           ::close( sStderr[1] );                        }                        if ( comms & Stdout ) {                           ::close( sStdout[0] );                           ::close( sStdout[1] );                        }                        return false;                     }#ifndef Q_OS_QNX6                     if ( (comms & FDout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sFDout ) == -1 ) {#else                        if ( (comms & FDout) && qnx6SocketPairReplacement(sFDout) == -1 ) {#endif                           if ( comms & Stdin ) {                              ::close( sStdin[0] );                              ::close( sStdin[1] );                           }                           if ( comms & Stderr ) {                              ::close( sStderr[0] );                              ::close( sStderr[1] );                           }                           if ( comms & Stdout ) {                              ::close( sStdout[0] );                              ::close( sStdout[1] );                           }                           if ( comms & FDin ) {                              ::close( sFDin[0] );                              ::close( sFDin[1] );                           }                           return false;                        }                          /* the following pipe is only used to determine if the process could                           be started */                        int fd[2];                        if ( pipe( fd ) < 0 ) {                           // non critical error, go on                           fd[0] = 0;                           fd[1] = 0;                        }                        // construct the arguments for exec                        QCString *arglistQ = new QCString[ _arguments.count() + 1 ];                        const char** arglist = new const char*[ _arguments.count() + 1 ];                        int i = 0;                        for ( QStringList::Iterator it = _arguments.begin();                               it != _arguments.end(); ++it ) {                           arglistQ[i] = (*it).local8Bit();                           arglist[i] = arglistQ[i];#if defined(VK_PROCESS_DEBUG)                           qDebug( "VKProcess::start(): arg %d = %s", i, arglist[i] );#endif                           i++;                        }#ifdef Q_OS_MACX                        if(i) {                           QCString arg_bundle = arglistQ[0];                           QFileInfo fi(arg_bundle);                           if(fi.exists() && fi.isDir() && arg_bundle.right(4) == ".app") {                              QCString exe = arg_bundle;                              int lslash = exe.findRev('/');                              if(lslash != -1)                                 exe = exe.mid(lslash+1);                              exe = QCString(arg_bundle + "/Contents/MacOS/" + exe);                              exe = exe.left(exe.length() - 4); //chop off the .app                              if(QFile::exists(exe)) {                                 arglistQ[0] = exe;                                 arglist[0] = arglistQ[0];                              }                           }                        }#endif                        arglist[i] = 0;                        /* Must make sure signal handlers are installed before exec'ing in                           case the process exits quickly. */                        if ( d->procManager == 0 ) {                           d->procManager = new VKProcessManager;                           qAddPostRoutine(vkprocess_cleanup);                        }                        // fork and exec                        QApplication::flushX();                        pid_t pid = fork();                        if ( pid == 0 ) {                           // child                           d->closeOpenSocketsForChild();                           if ( comms & FDin ) {                              ::close( sFDin[1] );                              ::dup2( sFDin[0], filedesc_in );                           }                           if ( comms & FDout ) {                              ::close( sFDout[0] );                              ::dup2( sFDout[1], filedesc_out );                           }                           if ( comms & Stdin ) {                              ::close( sStdin[1] );                              ::dup2( sStdin[0], STDIN_FILENO );                           }                           if ( comms & Stdout ) {                              ::close( sStdout[0] );                              ::dup2( sStdout[1], STDOUT_FILENO );                           }                           if ( comms & Stderr ) {                              ::close( sStderr[0] );                              ::dup2( sStderr[1], STDERR_FILENO );                           }                           if ( comms & DupStderr ) {                              ::dup2( STDOUT_FILENO, STDERR_FILENO );                           }                           ::chdir( workingDir.absPath().latin1() );                           if ( fd[0] )                              ::close( fd[0] );                           if ( fd[1] )                              ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess                               if ( env == 0 ) { // inherit environment and start process                              QString command = _arguments[0];#if defined(Q_OS_MACX) //look in a bundle                              const QString mac_bundle_suffix = ".app/Contents/MacOS/";                              if(!QFile::exists(command) && QFile::exists(command + mac_bundle_suffix)) {                                 QString exec = command;                                 int lslash = command.findRev('/');                                 if(lslash != -1)                                    exec = command.mid(lslash+1);                                 QFileInfo fileInfo( command + mac_bundle_suffix + exec );                                 if ( fileInfo.isExecutable() )                                    command = fileInfo.absFilePath().local8Bit();                              }#endif#ifndef Q_OS_QNX4                              ::execvp( command, (char*const*)arglist ); // ### cast not nice#else                              ::execvp( command, (char const*const*)arglist ); // ### cast not nice#endif                           } else { // start process with environment settins as specified in env                              // construct the environment for exec                              int numEntries = env->count();#if defined(Q_OS_MACX)                              QString ld_library_path("DYLD_LIBRARY_PATH");#else                              QString ld_library_path("LD_LIBRARY_PATH");#endif                              bool setLibraryPath =                                 env->grep( QRegExp( "^" + ld_library_path + "=" ) ).empty() &&                                 getenv( ld_library_path ) != 0;                              if ( setLibraryPath )                                 numEntries++;                              QCString *envlistQ = new QCString[ numEntries + 1 ];                              const char** envlist = new const char*[ numEntries + 1 ];                              int i = 0;                              if ( setLibraryPath ) {                                 envlistQ[i] = QString( ld_library_path + "=%1" ).arg( getenv( ld_library_path ) ).local8Bit();                                 envlist[i] = envlistQ[i];                                 i++;                              }                              for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) {                                 envlistQ[i] = (*it).local8Bit();                                 envlist[i] = envlistQ[i];                                 i++;                              }                              envlist[i] = 0;                                    // look for the executable in the search path                              if ( _arguments.count()>0 && getenv("PATH")!=0 ) {                                 QString command = _arguments[0];                                 if ( !command.contains( '/' ) ) {                                    QStringList pathList = QStringList::split( ':', getenv( "PATH" ) );                                    for (QStringList::Iterator it = pathList.begin();                                          it != pathList.end(); ++it ) {                                       QString dir = *it;#if defined(Q_OS_MACX) //look in a bundle                                       if ( !QFile::exists(dir + "/" + command) &&                                             QFile::exists(dir + "/" + command + ".app") )                                          dir += "/" + command + ".app/Contents/MacOS";#endif                                       QFileInfo fileInfo( dir, command );                                       if ( fileInfo.isExecutable() ) {#if defined(Q_OS_MACX)                                          arglistQ[0] = fileInfo.absFilePath().local8Bit();#else                                          arglistQ[0] = fileInfo.filePath().local8Bit();#endif                                          arglist[0] = arglistQ[0];                                          break;                                       }                                    }                                 }                              }#if defined(Q_OS_MACX)                              if ( ! QFile::exists( arglist[0] ) ) {                                 QString command = arglist[0];                                 const QString mac_bundle_suffix = ".app/Contents/MacOS/";                                 if ( QFile::exists(command + mac_bundle_suffix ) ) {                                    QString exec = command;                                    int lslash = command.findRev('/');                                    if(lslash != -1)                                       exec = command.mid(lslash+1);                                    QFileInfo fileInfo( command + mac_bundle_suffix + exec );                                    if ( fileInfo.isExecutable() ) {                                       arglistQ[0] = fileInfo.absFilePath().local8Bit();                                       arglist[0] = arglistQ[0];                                    }                                 }                              }#endif#ifndef Q_OS_QNX4                              ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice#else                              ::execve( arglist[0], (char const*const*)arglist,(char const*const*)envlist ); // ### casts not nice#endif                           }                           if ( fd[1] ) {                              char buf = 0;                              ::write( fd[1], &buf, 1 );                              ::close( fd[1] );                           }                           ::_exit( -1 );                        } else if ( pid == -1 ) {                           // error forking                           goto error;                        }                        // test if exec was successful                        if ( fd[1] )                           ::close( fd[1] );                        if ( fd[0] ) {                           char buf;                           for ( ;; ) {                              int n = ::read( fd[0], &buf, 1 );                              if ( n==1 ) {                                 // socket was not closed => error                                 if ( ::waitpid( pid, 0, WNOHANG ) != pid ) {                                    /* The wait did not succeed yet, so try again when we get                                       the sigchild (to avoid zombies). */                                    d->newProc( pid, 0 );                                 }                                 d->proc = 0;                                 goto error;                              } else if ( n==-1 ) {                                 if ( errno==EAGAIN || errno==EINTR )                                    // try it again                                    continue;                              }                              break;                           }                           ::close( fd[0] );                        }                          d->newProc( pid, this );                          if ( comms & FDin ) {                           ::close( sFDin[0] );                           d->proc->socketFDin = sFDin[1];                           // Select non-blocking mode                           int originalFlags = fcntl(d->proc->socketFDin, F_GETFL, 0);                           fcntl(d->proc->socketFDin, F_SETFL, originalFlags | O_NONBLOCK);                           d->notifierFDin = new QSocketNotifier( sFDin[1], QSocketNotifier::Write );                           connect( d->notifierFDin, SIGNAL(activated(int)),                                    this, SLOT(socketWrite(int)) );                           // setup notifiers for the sockets                           if ( !d->fdinBuf.isEmpty() ) {                              d->notifierFDin->setEnabled( true );                           }                        }                        if ( comms & Stdin ) {                           ::close( sStdin[0] );                           d->proc->socketStdin = sStdin[1];                           // Select non-blocking mode                           int originalFlags = fcntl(d->proc->socketStdin, F_GETFL, 0);                           fcntl(d->proc->socketStdin, F_SETFL, originalFlags | O_NONBLOCK);                               d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write );                           connect( d->notifierStdin, SIGNAL(activated(int)),                                    this, SLOT(socketWrite(int)) );                           // setup notifiers fo

⌨️ 快捷键说明

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