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

📄 stafprocess.cpp

📁 Software Testing Automation Framework (STAF)的开发代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                STAFProcessID_t nextFGPID = fgPIDList.front();                fgPIDList.pop_front();                if (tcsetpgrp(theTTY, nextFGPID) < 0)                {                    STAFString errorMessage("STAFProcess::"                                            "processMonitorThread: Error on "                                            "tcsetpgrp(), errno: ");                    errorMessage += errno;                    STAFTrace::trace(kSTAFTraceError, errorMessage);                }                if (kill(nextFGPID, SIGCONT) < 0)                {                    STAFString errorMessage("STAFProcess::"                                            "processMonitorThread: "                                            "Error continuing PID: ");                    errorMessage += nextFGPID;                    errorMessage += ", errno: ";                    errorMessage += errno;                    STAFTrace::trace(kSTAFTraceError, errorMessage);                }            }            // If no process was found, lets go to sleep for some time,            // unless we get posted meaning we need to create a process            if (!foundProcess)            {                // if posted, create the process indicated in fProcessCreateInfo                if (!sProcessThread.wait(MONITOR_SLEEP_SECONDS * 1000))                {#ifndef STAF_OS_NAME_ZOS                    // create the new process                    if ((sProcessCreateInfo.pid = STAF_FORK()) == 0)                    {                        // child process                        // setgid must be done first, as if we change the uid                        // first then we are not able to change the gid since                        // we may no longer have enough privilege to do that.                        if (setgid(sProcessCreateInfo.gid) < 0)                        {                            STAFTrace::trace(kSTAFTraceError,                                STAFString("STAFProcess::"                                           "processMonitorThread: Child could "                                           "not set child's gid: ") + errno);                            _exit(1);                        }                        if (setuid(sProcessCreateInfo.uid) < 0)                        {                            STAFTrace::trace(kSTAFTraceError,                                STAFString("STAFProcess::"                                           "processMonitorThread: Child could "                                           "not set child's uid: ") + errno);                            _exit(1);                        }                        if (setpgid(0, 0) < 0)                        {                            STAFTrace::trace(kSTAFTraceInfo,                                STAFString("STAFProcess::"                                           "processMonitorThread: Child could "                                           "not set child's pgid: ") + errno);                            _exit(1);                        }                        close(0);                        dup(sProcessCreateInfo.child_stdin);                        close(sProcessCreateInfo.child_stdin);                        close(1);                        dup(sProcessCreateInfo.child_stdout);                        close(sProcessCreateInfo.child_stdout);                        close(2);                        dup(sProcessCreateInfo.child_stderr);                        close(sProcessCreateInfo.child_stderr);                        // change working directory if appropriate                        if (sProcessCreateInfo.workdir->length() != 0)                        {                            chdir(sProcessCreateInfo.workdir->buffer());                        }                                                if (sProcessCreateInfo.envp == 0)                        {                            // overwrite memory with new process image                            if (execv((sProcessCreateInfo.commandType ==                                       kSTAFProcessCommand) ?                                          sProcessCreateInfo.command->buffer() :                                          "/bin/sh",                                      sProcessCreateInfo.argv))                            {                                STAFTrace::trace(kSTAFTraceError,                                                  STAFString("STAFProcess::"                                                 "processMonitorThread: Could "                                                 "not start process (execve):") +                                                 errno);                                _exit(1);  // this is the child process                            }                        }                        else                        {                            // overwrite memory with new process image                            if (execve((sProcessCreateInfo.commandType ==                                        kSTAFProcessCommand) ?                                           sProcessCreateInfo.command->buffer() :                                           "/bin/sh",                                       sProcessCreateInfo.argv,                                       sProcessCreateInfo.envp))                            {                                STAFTrace::trace(kSTAFTraceError,                                                  STAFString("STAFProcess::"                                                 "processMonitorThread: Could "                                                 "not start process (execve):") +                                                 errno);                                _exit(1);  // this is the child process                            }                        }                    }                    // parent process                    if (setpgid(sProcessCreateInfo.pid,                                sProcessCreateInfo.pid) < 0)                    {                        STAFTrace::trace(kSTAFTraceInfo,                            STAFString("STAFProcess::"                                       "processMonitorThread: Parent could not "                                       "set child's pgid: ") + errno);                    }#else // STAF_OS_NAME_ZOS                    struct __inheritance inherit;                    // Set inheritance flags to create a new process group                    inherit.flags = SPAWN_SETGROUP;                    inherit.pgroup = SPAWN_NEWPGROUP;                    int fd_count = 3;                    int fd_map[3] = { sProcessCreateInfo.child_stdin,                                      sProcessCreateInfo.child_stdout,                                      sProcessCreateInfo.child_stderr };                    //Set working directory                    if (sProcessCreateInfo.workdir->length() != 0) {                        inherit.flags |= SPAWN_SETCWD;                        inherit.cwdptr = const_cast<char *>(                                         sProcessCreateInfo.workdir->buffer());                        inherit.cwdlen = sProcessCreateInfo.workdir->length();                    }                    //Set userid                    if (sProcessCreateInfo.uid != getuid())                    {                        inherit.flags |= SPAWN_SETUSERID;                        // Note: The length of the inherit.userid buffer is                        //       eight.  Thus, we don't want to overwrite                        //       anything after it.                        strncpy(inherit.userid,                                sProcessCreateInfo.userName->buffer(), 8);                        inherit.userid[8] = 0;                    }                    // create the new process                    sProcessCreateInfo.pid = __spawn2(                        (sProcessCreateInfo.commandType == kSTAFProcessCommand)                            ? sProcessCreateInfo.command->buffer()                            : "/bin/sh",                        fd_count, fd_map, &inherit,                        (const char**) sProcessCreateInfo.argv,                        (const char**) ((sProcessCreateInfo.envp == 0) ?                                        environ : sProcessCreateInfo.envp));                    // parent process                    if (sProcessCreateInfo.pid == -1)                    {                        STAFTrace::trace(kSTAFTraceError,                                          STAFString("STAFProcess::"                                         "processMonitorThread(): Could "                                         "not start process: ") + errno);                    }#endif                    //Close file descriptors in the parent                    close(sProcessCreateInfo.child_stdin);                    close(sProcessCreateInfo.child_stdout);                    close(sProcessCreateInfo.child_stderr);                    {   // acquire lock                        STAFMutexSemLock lock(sMonitorDataSem);                                        // add new process to list                        sMonitorMap[sProcessCreateInfo.pid].push_back(                            ProcessMonitorInfo(sProcessCreateInfo.pid,                                               sProcessCreateInfo.pid,                                                sProcessCreateInfo.callback));                    }   // release lock                    // reset this thread's sem and post the process manager                    // so that it can deallocate any used resources                    sProcessThread.reset();                    sProcessCreated.post();                }  // if process thread was posted during wait            }  // if not process found by waitpid        } // try block        catch (STAFException &se)        {            se.trace("STAFProcess::ProcessMonitorThread()");        }        catch (...)        {            STAFTrace::trace(                kSTAFTraceError,                "Caught unknown exception in "                "STAFProcess::ProcessMonitorThread()");        }    }  // endless loop}STAFRC_t STAFProcessStart(STAFProcessID_t *pid, STAFProcessHandle_t *procHandle,                          void *data, unsigned int startDataLevel,                          unsigned int *osRC){    STAFString_t errorBuffer = 0;    return STAFProcessStart2(pid, procHandle, data, startDataLevel,                             osRC, &errorBuffer);}STAFRC_t STAFProcessStart2(STAFProcessID_t *pid, STAFProcessHandle_t *procHandle,                           void *data, unsigned int startDataLevel,                           unsigned int *osRC, STAFString_t *errorBuffer){    if (data == 0)    {        if (errorBuffer)        {            STAFString errMsg = STAFString(                "Invalid data provided to STAFProcessStart2()");            *errorBuffer = errMsg.adoptImpl();        }        return kSTAFInvalidValue;    }    if (startDataLevel != 1)    {        if (errorBuffer)        {            STAFString errMsg = STAFString(                "Invalid level provided to STAFProcessStart2(): ") +                startDataLevel;            *errorBuffer = errMsg.adoptImpl();        }        return kSTAFInvalidValue;    }    unsigned int systemErrorCode = 0;    STAFProcessStartInfoLevel1 *startData =        reinterpret_cast<STAFProcessStartInfoLevel1 *>(data);    InitProcessManager();    STAFString command(startData->command);    struct stat fileinfo;    if (startData->commandType == kSTAFProcessShell)        command = command.subWord(0, 1);    // Since a shell command could be "date; grep abc abc", cannot verify    // that the first word (e.g. date;) is a valid command so only do this    // check that the command is valid if not a shell command.    if (startData->commandType != kSTAFProcessShell)    {        // Note: this checking is due to stat which requires a path'd file        if (command.find(kUTF8_SLASH) == STAFString::kNPos)        {            STAFString_t path;            // If no slashes found, resolve the command to form its path'd name            // Note: getFilePath will always return a path that does not term-            // inate with "/"            STAFRC_t rc = STAFUtilUnixGetFilePath(command.getImpl(), &path,                                                  osRC);            if (rc != kSTAFOk)            {                if (rc == kSTAFDoesNotExist)                {                    if (osRC) *osRC = ENOENT;                    if (errorBuffer)                    {                        STAFString errMsg = STAFString(                            "Command does not exist: ") + command;                        *errorBuffer = errMsg.adoptImpl();                    }                    return kSTAFBaseOSError;                }                if (errorBuffer)                {                    STAFString errMsg = STAFString("Invalid command: ") +                        command;                    *errorBuffer = errMsg.adoptImpl();                }                return rc;            }            // Command contains path of startData->command (from getFilePath             // call), so here we construct something like "/usr/bin" + "/" +             // "ls" = "/usr/bin/ls"            // ???: This used to end with startData->command, not just command.            //      This messed things up when SHELL was added.  There doesn't            //      seem to be a reason why startData->command was used instead            //      of just command.            command = STAFString(path, STAFString::kShallow) +                      STAFString("/") + command;        }        // Check if command is a regular file and has execute perms        if (stat(command.toCurrentCodePage()->buffer(), &fileinfo) == -1)        {            systemErrorCode = errno;            if (osRC) *osRC = systemErrorCode;  // set by stat            if (errorBuffer)            {                STAFString errMsg = STAFString("Invalid command: ") + command +                    "\nThe command is not a file or does not have execute "                    "permissions.\nOS RC " + systemErrorCode;                *errorBuffer = errMsg.adoptImpl();            }            return kSTAFBaseOSError;         }        else if (!S_ISREG(fileinfo.st_mode))        {            if (osRC) *osRC = ENOEXEC; // exec format error            if (errorBuffer)            {                STAFString errMsg = STAFString("Invalid command: ") +                    command + "\nThe command is not a valid executable.";

⌨️ 快捷键说明

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