📄 stafprocess.cpp
字号:
*errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } else if (!S_ISEXE(fileinfo.st_mode)) { if (osRC) *osRC = EACCES; // permission denied if (errorBuffer) { STAFString errMsg = STAFString("Cannot execute command: ") + command + "\nIt does not have the necessary permissions."; *errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } } // Check workdir (if any) is a directory file and has execute perms if (startData->workdir != 0) { if (stat(STAFString(startData->workdir).toCurrentCodePage()->buffer(), &fileinfo) == -1) { systemErrorCode = errno; if (osRC) *osRC = systemErrorCode; // set by stat if (errorBuffer) { STAFString errMsg = STAFString("Invalid working directory: ") + startData->workdir + "\nOS RC " + systemErrorCode; *errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } else if (!S_ISDIR(fileinfo.st_mode)) { if (osRC) *osRC = ENOTDIR; // not a directory if (errorBuffer) { STAFString errMsg = STAFString("Working directory is not ") + "a directory: " + startData->workdir; *errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } else if (!S_ISEXE(fileinfo.st_mode)) { if (osRC) *osRC = EACCES; // permission denied if (errorBuffer) { STAFString errMsg = STAFString("Working directory ") + startData->workdir + " does not have the necessary permissions."; *errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } } // Note: These descriptors are closed in ProcessMonitorThread() int child_stdin = dup(0); int child_stdout = dup(1); int child_stderr = dup(2); // change stdin if appropriate if (startData->stdinMode == kSTAFProcessIOReadFile) { close(child_stdin); child_stdin = open(STAFString(startData->stdinRedirect) .toCurrentCodePage()->buffer(), O_RDONLY); if (child_stdin == -1) { systemErrorCode = errno; close(child_stdout); close(child_stderr); if (osRC) *osRC = systemErrorCode; if (errorBuffer) { STAFString errMsg = STAFString("Error opening stdin file ") + startData->stdinRedirect + " as readonly.\nOS RC " + systemErrorCode; *errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } } // change stdout if appropriate if (startData->stdoutMode != kSTAFProcessIONoRedirect) { int outFlags = O_CREAT | O_WRONLY; if (startData->stdoutMode == kSTAFProcessIOAppendFile) outFlags |= O_APPEND; else outFlags |= O_TRUNC; close(child_stdout); child_stdout = open(STAFString(startData->stdoutRedirect) .toCurrentCodePage()->buffer(), outFlags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (child_stdout == -1) { systemErrorCode = errno; close(child_stdin); close(child_stderr); if (osRC) *osRC = systemErrorCode; if (errorBuffer) { STAFString errMsg = STAFString("Error opening stdout file: ") + startData->stdoutRedirect + "\nOS RC " + systemErrorCode; *errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } } // change stderr if appropriate if (startData->stderrMode == kSTAFProcessIOStdout) { close(child_stderr); child_stderr = dup(child_stdout); } else if (startData->stderrMode != kSTAFProcessIONoRedirect) { int errFlags = O_CREAT | O_WRONLY; if (startData->stderrMode == kSTAFProcessIOAppendFile) errFlags |= O_APPEND; else errFlags |= O_TRUNC; close(child_stderr); child_stderr = open(STAFString(startData->stderrRedirect) .toCurrentCodePage()->buffer(), errFlags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (child_stderr == -1) { systemErrorCode = errno; close(child_stdin); close(child_stdout); if (osRC) *osRC = systemErrorCode; if (errorBuffer) { STAFString errMsg = STAFString("Error opening stderr file: ") + startData->stderrRedirect + "\nOS RC " + systemErrorCode; *errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } } // determine what to do with authentication based on the following // variables: authMode, default username/password, request user - // name/password, and operating system bool mustValidate = true; if (startData->authMode == kSTAFProcessAuthDisabled) { mustValidate = false; if (startData->disabledAuthAction == kSTAFProcessDisabledAuthError) { if (startData->username != 0) { if (osRC) *osRC = EACCES; if (errorBuffer) { STAFString errMsg = STAFString( "Process authentication denied. You cannot specify a " "userid when process authentication is disabled and " "the process authentication disabled action is set " "to 'Error'."); *errorBuffer = errMsg.adoptImpl(); } return kSTAFProcessAuthenticationDenied; } } } STAFUserID_t usrID = sOurUID; STAFGroupID_t grpID = sOurGID; unsigned int validUser = UserAuthenticate(usrID, grpID, STAFString(startData->username), STAFString(startData->password), mustValidate, osRC); if (!validUser || ((sOurUID != 0) && (sOurUID != usrID))) { if (errorBuffer) { STAFString errMsg = STAFString("Error during process ") + "authentication for user name " + startData->username; *errorBuffer = errMsg.adoptImpl(); } return kSTAFProcessAuthenticationDenied; } STAFString buffer = startData->command; if (startData->parms != 0) buffer += STAFString(" ") + startData->parms; // create argument table from the command and parameters passed. argv is // allocated by parseCommandParms and it must be deleted from this point // on before any return or thrown exception char **argv = 0; unsigned int argc = 4; if (startData->commandType == kSTAFProcessCommand) { argc = ParseCommandParms(buffer, &argv); if (argc == 0) { if (osRC) *osRC = EINVAL; // invalid argument delete[] argv; if (errorBuffer) { STAFString errMsg = STAFString("Parsing command arguments ") + "failed. Invalid command: " + buffer; *errorBuffer = errMsg.adoptImpl(); } return kSTAFBaseOSError; } } else { // startData->commandType == kSTAFProcessShell STAFString commandString; STAFString output; if (startData->shellCommand != 0) { // Substitute the command and possibly other data commandString = startData->shellCommand; STAFProcessShellSubstitutionData subData; subData.command = buffer; subData.title = startData->title; subData.workload = startData->workload; subData.username = startData->username; subData.password = startData->password; if (startData->stdinMode == kSTAFProcessIOReadFile) subData.stdinfile = "< " + STAFString(startData->stdinRedirect); if (startData->stdoutMode != kSTAFProcessIONoRedirect) { if (startData->stdoutMode == kSTAFProcessIOAppendFile) subData.stdoutfile = ">> " + STAFString(startData->stdoutRedirect); else subData.stdoutfile = "> " + STAFString(startData->stdoutRedirect); } if (startData->stderrMode == kSTAFProcessIOStdout) { subData.stdoutfile = subData.stdoutfile + " 2>&1"; } else if (startData->stderrMode != kSTAFProcessIONoRedirect) { if (startData->stderrMode == kSTAFProcessIOAppendFile) subData.stderrfile = "2>> " + STAFString(startData->stderrRedirect); else subData.stderrfile = "2> " + STAFString(startData->stderrRedirect); } int rc = STAFProcessReplaceShellSubstitutionChars(commandString, subData, output); if (rc != kSTAFOk) { if (errorBuffer) { STAFString errMsg = STAFString("Invalid shell command") + " value: " + startData->shellCommand; *errorBuffer = errMsg.adoptImpl(); } return rc; } buffer = output; } argv = new char *[4]; argv[0] = new char [3]; argv[1] = new char [3]; argv[2] = new char [buffer.toCurrentCodePage()->length() + 1]; argv[3] = 0; strcpy(argv[0], "sh"); strcpy(argv[1], "-c"); strcpy(argv[2], buffer.toCurrentCodePage()->buffer()); } // create environment table if appropriate (this block requires 2 passes // of the memory block, one pass to count number of variables so that we // can allocate the correct amount of memory for the table, and a second // pass to initialize the table to point to string in the memory block. // NOTE: this block allocates memory for the envp table. the memory gets // deleted before any return point in the parent process, whereas in the // child process it gets overwritten by execve int i = 0; char **envp = 0; int envc = 0; char *envstr = startData->environment; if (envstr != 0) { // count number of entries while (*envstr) { envc++; envstr += strlen(envstr) + 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -