📄 process.cpp
字号:
/***************************************************************************//* *//* Copyright (c) 2005, 2006 2X Software Ltd, http://www.2X.com., NoMachine *//* *//* NXCOMP, NX protocol compression and NX extensions to this software *//* are copyright of Nomachine. Redistribution and use of the present *//* software is allowed according to terms specified in the file LICENSE *//* which comes in the source distribution. *//* *//* NX and NoMachine are trademarks of Medialogic S.p.A. *//* *//* 2X is a trademark of 2X Software Ltd. *//* *//* All rights reserved. *//* *//***************************************************************************/#include <sys/types.h>#include <sys/socket.h>#include <sys/wait.h>#include <unistd.h>#include <signal.h>#define PANIC#define WARNING#define TEST#define DEBUG#include "Misc.h"#include "Logger.h"#include "Timestamp.h"#include "Process.h"char *Process::nullStreamName_ = "/dev/null";FILE *Process::nullStream_ = NULL;Process::Process(){ logTrace("Process::Process"); pid_ = -1; status_ = -1; privileged_ = -1; for (int i = 0; i < 256; i++) { parameters_[i] = NULL; environment_[i] = NULL; } nextEnvironment_ = 0; nextParameter_ = 0; function_ = NULL; in_ = -1; out_ = -1; err_ = -1; inStream_ = NULL; outStream_ = NULL; errStream_ = NULL; nullStream_ = NULL;}Process::~Process(){ logTrace("Process::~Process"); // // Close all the descriptors. // end(); if (nullStream_ != NULL) { logTest("Process::~Process", "Closing the null stream"); fclose(nullStream_); nullStream_ = NULL; } // // Free memory from the heap. // if (function_ == NULL) { for (int i = 0; i < nextParameter_; i++) { delete [] parameters_[i]; } } for (int i = 0; i < nextEnvironment_; i++) { delete [] environment_[i]; }}int Process::setCommand(const char *command){ logTrace("Process::setCommand"); if (setValue(parameters_[0], command) && setValue(parameters_[1], command)) { nextParameter_ = 2; return 1; } return -1;}int Process::setFunction(int (*function)(void *), void *parameter){ logTrace("Process::setFunction"); if (function_ != NULL || parameters_[0] != NULL) { logError("Process::setFunction", ESET(EPERM)); return -1; } function_ = function; parameters_[0] = (char *) parameter; nextParameter_ = 1; return 1;}int Process::setPrivileged(int value){ logTrace("Process::setPrivileged"); if (pid_ != -1) { logError("Process::setPrivileged", ESET(EPERM)); return -1; } privileged_ = value; return 1;}int Process::setDescriptor(int &std, int fd){ logTrace("Process::setDescriptor"); if (pid_ != -1) { logError("Process::setDescriptor", ESET(EPERM)); return -1; } std = fd; return 1;}FILE *Process::setDescriptorStream(int &fd, FILE *&stream, char *mode){ logTrace("Process::setDescriptorStream"); if ((stream = fdopen(fd, mode)) == NULL) { logError("Process::setDescriptorStream::fdopen", EGET()); logTest("Process::setDescriptorStream", "Can't create " "stream for descriptor %d", fd); return getNullStream(); } return stream;}FILE *Process::getNullStream(){ logTrace("Process::getNullStream"); if (nullStream_ == NULL) { logTest("Process::getNullStream", "Creating a " "fake stream as '%s'", nullStreamName_); if ((nullStream_ = fopen(nullStreamName_, "a+")) == NULL) { logError("Process::getNullStream::fopen", EGET()); logTest("Process::getNullStream", "Can't create " "a fake stream as '%s'", nullStreamName_); } } return nullStream_;}int Process::addParameter(const char *parameter){ logTrace("Process::addParameter"); if (function_ != NULL) { logTest("Process::addParameter", "Can't add a parameter " "to a function"); logError("Process::addParameter", ESET(EPERM)); return -1; } else if (nextParameter_ < 2) { logTest("Process::addParameter", "Can't add a parameter " "without a command"); logError("Process::addParameter", ESET(EPERM)); return -1; } if (nextParameter_ < parametersLimit_) { if (setValue(parameters_[nextParameter_], parameter) > 0) { nextParameter_++; return 1; } } else { logTest("Process::addParameter", "No space left in the " "parameter table"); logError("Process::addParameter", ESET(ENOMEM)); } return -1;}int Process::addEnvironment(const char *environment){ logTrace("Process::addEnvironment"); if (nextEnvironment_ < environmentLimit_) { if (setValue(environment_[nextEnvironment_], environment) > 0) { nextEnvironment_++; return 1; } } else { logTest("Process::addEnvironment", "No space left in the " "environment table"); logError("Process::addEnvironment", ESET(ENOMEM)); } return -1;}int Process::isRunning(){ logTrace("Process::isRunning"); if (pid_ < 0) { return 0; } int status; int options = WNOHANG | WUNTRACED; int result = waitpid(pid_, &status, options); return (parseStatus(result, status) <= 0);}int Process::isSuccess(){ logTrace("Process::isSuccess"); if (status_ == -1) { logTest("Process::isSuccess", "Child %d is " "still running", pid_); logWarning("Process::isSuccess", ESET(EPERM)); return 0; } if (WIFEXITED(status_)) { return (WEXITSTATUS(status_) == 0); } return 0;}int Process::kill(int signal){ logTrace("Process::kill"); logTest("Process::kill", "Sending signal %d to process %d", signal, pid_); if (::kill(pid_, signal) < 0 && EGET() != ESRCH) { logError("Process::kill::kill", EGET()); return -1; } return 1;}int Process::wait(){ logTrace("Process::wait"); if (pid_ < 0) { logError("Process::wait", ESET(ECHILD)); return -1; } int status; int options = WUNTRACED; int result = waitpid(pid_, &status, options); return parseStatus(result, status);}int Process::wait(const T_timestamp timeout){ logTrace("Process::wait"); if (pid_ < 0) { logError("Process::wait", ESET(ECHILD)); return 1; } // // Wait for the process until the timeout. // int status; int options = WUNTRACED; setTimer(timeout); int result; if ((result = waitpid(pid_, &status, options)) == -1) { if (EGET() == EINTR) { logTest("Process::wait", "Timeout raised waiting " "for pid %d", pid_); return 0; } else { logError("Process::wait", EGET()); return -1; } } resetTimer(); result = parseStatus(result, status); return result;}int Process::parseStatus(int result, int status){ logTrace("Process::parseStatus"); if (result > 0) { if (WIFSTOPPED(status)) { logTest("Process::parseStatus", "Child %d was stopped " "with signal %d", pid_, (WSTOPSIG(status))); } else { #ifdef TEST if (WIFEXITED(status)) { logTest("Process::parseStatus", "Child %d exited " "with status %d", pid_, (WEXITSTATUS(status))); } else if (WIFSIGNALED(status)) { logTest("Process::parseStatus", "Child %d died " "because of signal %d", pid_, (WTERMSIG(status))); } #endif status_ = status; return 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -