📄 process.cpp
字号:
} else if (result < 0) { if (EGET() == ECHILD) { // // The process died but we missed to // call the waitpid() at the time. // logWarning("Process::parseStatus::waitpid", EGET()); return 1; } logError("Process::parseStatus::waitpid", EGET()); return -1; } return 0;}int Process::exitStatus(int result){ logTrace("Process::exitStatus"); exit(result);}int Process::start(){ logTrace("Process::start"); int childIn[2] = { -1, -1 }; int childOut[2] = { -1, -1 }; int childErr[2] = { -1, -1 }; // // We either have 2 parameters and this process // will exec() a new command, or we have one or // none and this process will yield control to // a function. // if (function_ == NULL && (parameters_[0] == NULL || parameters_[1] == NULL)) { logTest("Process::start", "Can't start the process " "without a command or function"); logError("Process::start", ESET(EPERM)); return -1; } #ifdef TEST if (function_ == NULL) { logTest("Process::start", "Executing command '%s'", parameters_[0]); for (int i = 1; i < parametersLimit_ && parameters_[i] != NULL; i++) { logTest("Process::start", "Parameter [%d] is '%s'", i, parameters_[i]); } } else { logTest("Process::start", "Executing function at %p", function_); logTest("Process::start", "Passing data as %p", parameters_[0]); } for (int i = 0; i < environmentLimit_ && environment_[i] != NULL; i++) { logTest("Process::start", "Environment [%d] is '%s'", i, environment_[i]); } #endif // // Create the pipes that will be used to replace // the standard descriptors. // if ((in_ == -1 && pipe(childIn) != 0) || (out_ == -1 && pipe(childOut) != 0) || (err_ == -1 && pipe(childErr) != 0)) { logError("Process::start::pipe", EGET()); return -1; } switch (pid_ = fork()) { case -1: { // // An error was encountered. // logError("Process::start::fork", EGET()); if (in_ == -1) { close(childIn[0]); close(childIn[1]); } if (out_ == -1) { close(childOut[0]); close(childOut[1]); } if (err_ == -1) { close(childErr[0]); close(childErr[1]); } return -1; } case 0: { // // We are the child process. // logTest("Process::start", "Child running with pid %d", getpid()); // // Drop the privileges. // if (privileged_ != 1) { logTest("Process::start", "Child dropping the permissions"); setgid(getgid()); setuid(getuid()); } // // Let the input descriptor inherited from the // parent replace the standard descriptors. The // descriptor can be either the one set by the // parent or our end of the pipe we created be- // fore forking. // // Handle the standard input. // if (in_ == -1) { logTest("Process::start", "Child replacing pipe " "%d and %d for input", childIn[0], childIn[1]); if (childIn[0] != 0) { dup2(childIn[0], 0); close(childIn[0]); } close(childIn[1]); } else if (in_ != 0) { logTest("Process::start", "Child replacing input %d", in_); dup2(in_, 0); if (in_ != out_ && in_ != err_) { close(in_); } } else { logTest("Process::start", "Child inherited input"); } in_ = 0; // // Handle the standard output. // if (out_ == -1) { logTest("Process::start", "Child replacing pipe " "%d and %d for output", childOut[0], childOut[1]); if (childOut[1] != 1) { dup2(childOut[1], 1); close(childOut[1]); } close(childOut[0]); } else if (out_ != 1) { logTest("Process::start", "Child replacing output %d", out_); dup2(out_, 1); if (out_ != err_) { close(out_); } } else { logTest("Process::start", "Child inherited output"); } out_ = 1; // // Handle the standard error. // if (err_ == -1) { logTest("Process::start", "Child replacing pipe " "%d and %d for error", childErr[0], childErr[1]); if (childErr[1] != 2) { dup2(childErr[1], 2); close(childErr[1]); } close(childErr[0]); } else if (err_ != 2) { logTest("Process::start", "Child replacing error %d", err_); dup2(err_, 2); close(err_); } else { logTest("Process::start", "Child inherited error"); } err_ = 2; // // Let the pid be our own pid. // pid_ = getpid(); logTest("Process::start", "Child has descriptors " "%d, %d, %d and pid %d", in_, out_, err_, pid_); // // Set the new environment for the process. // for (int i = 0; i < environmentLimit_ && environment_[i] != NULL; i++) { putenv(environment_[i]); } // // Either execute the requested command or // yield control to the function. // if (parameters_[1] != NULL) { if (execvp(parameters_[0], parameters_ + 1) == -1) { logTest("Process::start", "Child failed to execute the command"); logError("Process::start::execvp", EGET()); } exitStatus(-1); } else { int result = function_((void *) parameters_[0]); exitStatus(result); } } default: { // // We are the parent process. // logTest("Process::start", "Parent started child with pid %d", pid_); if (in_ == -1) { close(childIn[0]); in_ = childIn[1]; } if (out_ == -1) { close(childOut[1]); out_ = childOut[0]; } if (err_ == -1) { close(childErr[1]); err_ = childErr[0]; } logTest("Process::start", "Parent using descriptors %d, %d, %d", in_, out_, err_); return 1; } }}int Process::end(){ logTrace("Process::end"); if (pid_ == -1) { return 0; } if (in_ != 0) { if (inStream_ != NULL) { logTest("Process::end", "Closing the input stream"); fclose(inStream_); inStream_ = NULL; in_ = -1; } else if (in_ != -1) { logTest("Process::end", "Closing the input descriptor"); close(in_); in_ = -1; } } else { logTest("Process::end", "Input is the standard descriptor"); } if (out_ != 1) { if (outStream_ != NULL) { logTest("Process::end", "Closing the output stream"); fclose(outStream_); outStream_ = NULL; out_ = -1; } else if (out_ != -1) { logTest("Process::end", "Closing the output descriptor"); close(out_); out_ = -1; } } else { logTest("Process::end", "Output is the standard descriptor"); } if (err_ != 2) { if (errStream_ != NULL) { logTest("Process::end", "Closing the error stream"); fclose(errStream_); errStream_ = NULL; err_ = -1; } else if (err_ != -1) { logTest("Process::end", "Closing the error descriptor"); close(err_); err_ = -1; } } else { logTest("Process::end", "Error is the standard descriptor"); } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -