source: XMLIO_V2/external/src/POCO/Foundation.save/Process_UNIX.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 5.3 KB
Line 
1//
2// Process_UNIX.cpp
3//
4// $Id: //poco/1.3/Foundation/src/Process_UNIX.cpp#2 $
5//
6// Library: Foundation
7// Package: Processes
8// Module:  Process
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35
36
37#include "Poco/Process_UNIX.h"
38#include "Poco/Exception.h"
39#include "Poco/NumberFormatter.h"
40#include "Poco/Pipe.h"
41#include <errno.h>
42#include <signal.h>
43#include <sys/time.h>
44#include <sys/types.h>
45#include <sys/resource.h>
46#include <sys/wait.h>
47
48
49#if defined(__QNX__)
50#include <process.h>
51#include <spawn.h>
52#include <cstring>
53#endif
54
55
56namespace Poco {
57
58
59//
60// ProcessHandleImpl
61//
62ProcessHandleImpl::ProcessHandleImpl(pid_t pid):
63        _pid(pid)
64{
65}
66
67
68ProcessHandleImpl::~ProcessHandleImpl()
69{
70}
71
72
73pid_t ProcessHandleImpl::id() const
74{
75        return _pid;
76}
77
78
79int ProcessHandleImpl::wait() const
80{
81        int status;
82        int rc;
83        do
84        {
85                rc = waitpid(_pid, &status, 0);
86        }
87        while (rc < 0 && errno == EINTR);
88        if (rc != _pid)
89                throw SystemException("Cannot wait for process", NumberFormatter::format(_pid));
90        return WEXITSTATUS(status);
91}
92
93
94//
95// ProcessImpl
96//
97ProcessImpl::PIDImpl ProcessImpl::idImpl()
98{
99        return getpid();
100}
101
102
103void ProcessImpl::timesImpl(long& userTime, long& kernelTime)
104{
105        struct rusage usage;
106        getrusage(RUSAGE_SELF, &usage);
107        userTime   = usage.ru_utime.tv_sec;
108        kernelTime = usage.ru_stime.tv_sec;
109}
110
111
112ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe)
113{
114#if defined(__QNX__)
115        /// use QNX's spawn system call which is more efficient than fork/exec.
116        char** argv = new char*[args.size() + 2];
117        int i = 0;
118        argv[i++] = const_cast<char*>(command.c_str());
119        for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it) 
120                argv[i++] = const_cast<char*>(it->c_str());
121        argv[i] = NULL;
122        struct inheritance inherit;
123        std::memset(&inherit, 0, sizeof(inherit));
124        inherit.flags = SPAWN_ALIGN_DEFAULT | SPAWN_CHECK_SCRIPT | SPAWN_SEARCH_PATH;
125        int fdmap[3];
126        fdmap[0] = inPipe  ? inPipe->readHandle()   : 0;
127        fdmap[1] = outPipe ? outPipe->writeHandle() : 1;
128        fdmap[2] = errPipe ? errPipe->writeHandle() : 2;
129        int pid = spawn(command.c_str(), 3, fdmap, &inherit, argv, NULL);
130        delete [] argv;
131        if (pid == -1) throw SystemException("cannot spawn", command);
132#else
133        int pid = fork();
134        if (pid < 0)
135        {
136                throw SystemException("Cannot fork process for", command);             
137        }
138        else if (pid == 0)
139        {
140                // setup redirection
141                if (inPipe)
142                {
143                        dup2(inPipe->readHandle(), STDIN_FILENO);
144                        inPipe->close(Pipe::CLOSE_BOTH);
145                }
146                // outPipe and errPipe may be the same, so we dup first and close later
147                if (outPipe) dup2(outPipe->writeHandle(), STDOUT_FILENO);
148                if (errPipe) dup2(errPipe->writeHandle(), STDERR_FILENO);
149                if (outPipe) outPipe->close(Pipe::CLOSE_BOTH);
150                if (errPipe) errPipe->close(Pipe::CLOSE_BOTH);
151                // close all open file descriptors other than stdin, stdout, stderr
152                for (int i = 3; i < getdtablesize(); ++i)
153                        close(i);
154                       
155                char** argv = new char*[args.size() + 2];
156                int i = 0;
157                argv[i++] = const_cast<char*>(command.c_str());
158                for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it) 
159                        argv[i++] = const_cast<char*>(it->c_str());
160                argv[i] = NULL;
161                execvp(command.c_str(), argv);
162                _exit(72);
163        }
164#endif
165        if (inPipe)  inPipe->close(Pipe::CLOSE_READ);
166        if (outPipe) outPipe->close(Pipe::CLOSE_WRITE);
167        if (errPipe) errPipe->close(Pipe::CLOSE_WRITE);
168        return new ProcessHandleImpl(pid);
169}
170
171
172void ProcessImpl::killImpl(PIDImpl pid)
173{
174        if (kill(pid, SIGKILL) != 0)
175        {
176                switch (errno)
177                {
178                case ESRCH:
179                        throw NotFoundException("cannot kill process");
180                case EPERM:
181                        throw NoPermissionException("cannot kill process");
182                default:
183                        throw SystemException("cannot kill process");
184                }
185        }
186}
187
188
189void ProcessImpl::requestTerminationImpl(PIDImpl pid)
190{
191        if (kill(pid, SIGINT) != 0)
192        {
193                switch (errno)
194                {
195                case ESRCH:
196                        throw NotFoundException("cannot terminate process");
197                case EPERM:
198                        throw NoPermissionException("cannot terminate process");
199                default:
200                        throw SystemException("cannot terminate process");
201                }
202        }
203}
204
205
206} // namespace Poco
Note: See TracBrowser for help on using the repository browser.