📄 process_unix.cpp
字号:
//// Process_UNIX.cpp//// $Id: //poco/1.2/Foundation/src/Process_UNIX.cpp#2 $//// Library: Foundation// Package: Processes// Module: Process//// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.// and Contributors.//// Permission is hereby granted, free of charge, to any person or organization// obtaining a copy of the software and accompanying documentation covered by// this license (the "Software") to use, reproduce, display, distribute,// execute, and transmit the Software, and to prepare derivative works of the// Software, and to permit third-parties to whom the Software is furnished to// do so, all subject to the following:// // The copyright notices in the Software and this entire statement, including// the above license grant, this restriction and the following disclaimer,// must be included in all copies of the Software, in whole or in part, and// all derivative works of the Software, unless such copies or derivative// works are solely in the form of machine-executable object code generated by// a source language processor.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE.//#include "Poco/Process_UNIX.h"#include "Poco/Exception.h"#include "Poco/NumberFormatter.h"#include "Poco/Pipe.h"#include <errno.h>#include <signal.h>#include <sys/time.h>#include <sys/types.h>#include <sys/resource.h>#include <sys/wait.h>#if defined(__QNX__)#include <process.h>#include <spawn.h>#include <string.h>#endifnamespace Poco {//// ProcessHandleImpl//ProcessHandleImpl::ProcessHandleImpl(pid_t pid): _pid(pid){}ProcessHandleImpl::~ProcessHandleImpl(){}pid_t ProcessHandleImpl::id() const{ return _pid;}int ProcessHandleImpl::wait() const{ int status; int rc; do { rc = waitpid(_pid, &status, 0); } while (rc < 0 && errno == EINTR); if (rc != _pid) throw SystemException("Cannot wait for process", NumberFormatter::format(_pid)); return WEXITSTATUS(status);}//// ProcessImpl//ProcessImpl::PIDImpl ProcessImpl::idImpl(){ return getpid();}void ProcessImpl::timesImpl(long& userTime, long& kernelTime){ struct rusage usage; getrusage(RUSAGE_SELF, &usage); userTime = usage.ru_utime.tv_sec; kernelTime = usage.ru_stime.tv_sec;}ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe){#if defined(__QNX__) /// use QNX's spawn system call which is more efficient than fork/exec. char** argv = new char*[args.size() + 2]; int i = 0; argv[i++] = const_cast<char*>(command.c_str()); for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it) argv[i++] = const_cast<char*>(it->c_str()); argv[i] = NULL; struct inheritance inherit; memset(&inherit, 0, sizeof(inherit)); inherit.flags = SPAWN_ALIGN_DEFAULT | SPAWN_CHECK_SCRIPT | SPAWN_SEARCH_PATH; int fdmap[3]; fdmap[0] = inPipe ? inPipe->readHandle() : 0; fdmap[1] = outPipe ? outPipe->writeHandle() : 1; fdmap[2] = errPipe ? errPipe->writeHandle() : 2; int pid = spawn(command.c_str(), 3, fdmap, &inherit, argv, NULL); delete [] argv; if (pid == -1) throw SystemException("cannot spawn", command);#else int pid = fork(); if (pid < 0) { throw SystemException("Cannot fork process for", command); } else if (pid == 0) { // setup redirection if (inPipe) { dup2(inPipe->readHandle(), STDIN_FILENO); inPipe->close(Pipe::CLOSE_BOTH); } // outPipe and errPipe may be the same, so we dup first and close later if (outPipe) dup2(outPipe->writeHandle(), STDOUT_FILENO); if (errPipe) dup2(errPipe->writeHandle(), STDERR_FILENO); if (outPipe) outPipe->close(Pipe::CLOSE_BOTH); if (errPipe) errPipe->close(Pipe::CLOSE_BOTH); // close all open file descriptors other than stdin, stdout, stderr for (int i = 3; i < getdtablesize(); ++i) close(i); char** argv = new char*[args.size() + 2]; int i = 0; argv[i++] = const_cast<char*>(command.c_str()); for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it) argv[i++] = const_cast<char*>(it->c_str()); argv[i] = NULL; execvp(command.c_str(), argv); _exit(72); }#endif if (inPipe) inPipe->close(Pipe::CLOSE_READ); if (outPipe) outPipe->close(Pipe::CLOSE_WRITE); if (errPipe) errPipe->close(Pipe::CLOSE_WRITE); return new ProcessHandleImpl(pid);}void ProcessImpl::killImpl(PIDImpl pid){ if (kill(pid, SIGKILL) != 0) { switch (errno) { case ESRCH: throw NotFoundException("cannot kill process"); case EPERM: throw NoPermissionException("cannot kill process"); default: throw SystemException("cannot kill process"); } }}void ProcessImpl::requestTerminationImpl(PIDImpl pid){ if (kill(pid, SIGINT) != 0) { switch (errno) { case ESRCH: throw NotFoundException("cannot terminate process"); case EPERM: throw NoPermissionException("cannot terminate process"); default: throw SystemException("cannot terminate process"); } }}} // namespace Poco
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -