xref: /aoo41x/main/sal/osl/unx/process.c (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir 
29*cdf0e10cSrcweir /*
30*cdf0e10cSrcweir  *   ToDo:
31*cdf0e10cSrcweir  *      - cleanup of process status things
32*cdf0e10cSrcweir  *      - cleanup of process spawning
33*cdf0e10cSrcweir  *      - cleanup of resource transfer
34*cdf0e10cSrcweir  */
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #if defined(SOLARIS)
37*cdf0e10cSrcweir   // The procfs may only be used without LFS in 32bits.
38*cdf0e10cSrcweir # ifdef _FILE_OFFSET_BITS
39*cdf0e10cSrcweir #   undef   _FILE_OFFSET_BITS
40*cdf0e10cSrcweir # endif
41*cdf0e10cSrcweir #endif
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #ifdef FREEBSD
45*cdf0e10cSrcweir #include <machine/param.h>
46*cdf0e10cSrcweir #endif
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include "system.h"
49*cdf0e10cSrcweir #if defined(SOLARIS)
50*cdf0e10cSrcweir # include <sys/procfs.h>
51*cdf0e10cSrcweir #endif
52*cdf0e10cSrcweir #include <osl/diagnose.h>
53*cdf0e10cSrcweir #include <osl/mutex.h>
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir #ifndef _OSL_CONDITN_H_
56*cdf0e10cSrcweir #include <osl/conditn.h>
57*cdf0e10cSrcweir #endif
58*cdf0e10cSrcweir #include <osl/thread.h>
59*cdf0e10cSrcweir #include <osl/file.h>
60*cdf0e10cSrcweir #include <osl/signal.h>
61*cdf0e10cSrcweir #include <rtl/alloc.h>
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir #include <grp.h>
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir #include "procimpl.h"
66*cdf0e10cSrcweir #include "sockimpl.h"
67*cdf0e10cSrcweir #include "secimpl.h"
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir #define MAX_ARGS        255
71*cdf0e10cSrcweir #define MAX_ENVS        255
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir #if defined(MACOSX) || defined(IORESOURCE_TRANSFER_BSD)
74*cdf0e10cSrcweir #define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(int))
75*cdf0e10cSrcweir #endif
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir /* implemented in file.c */
78*cdf0e10cSrcweir extern oslFileError FileURLToPath( char *, size_t, rtl_uString* );
79*cdf0e10cSrcweir extern oslFileHandle osl_createFileHandleFromFD( int fd );
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir /******************************************************************************
82*cdf0e10cSrcweir  *
83*cdf0e10cSrcweir  *                  Data Type Definition
84*cdf0e10cSrcweir  *
85*cdf0e10cSrcweir  ******************************************************************************/
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir typedef struct {
88*cdf0e10cSrcweir 	int  m_hPipe;
89*cdf0e10cSrcweir 	int  m_hConn;
90*cdf0e10cSrcweir 	sal_Char m_Name[PATH_MAX + 1];
91*cdf0e10cSrcweir } Pipe;
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir typedef struct {
94*cdf0e10cSrcweir 	const sal_Char*  m_pszArgs[MAX_ARGS + 1];
95*cdf0e10cSrcweir 	oslProcessOption m_options;
96*cdf0e10cSrcweir 	const sal_Char*  m_pszDir;
97*cdf0e10cSrcweir 	sal_Char*        m_pszEnv[MAX_ENVS + 1];
98*cdf0e10cSrcweir 	uid_t            m_uid;
99*cdf0e10cSrcweir 	gid_t 		     m_gid;
100*cdf0e10cSrcweir 	sal_Char* 		 m_name;
101*cdf0e10cSrcweir 	oslCondition     m_started;
102*cdf0e10cSrcweir 	oslProcessImpl*  m_pProcImpl;
103*cdf0e10cSrcweir 	oslFileHandle	 *m_pInputWrite;
104*cdf0e10cSrcweir 	oslFileHandle	 *m_pOutputRead;
105*cdf0e10cSrcweir 	oslFileHandle	 *m_pErrorRead;
106*cdf0e10cSrcweir } ProcessData;
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir typedef struct _oslPipeImpl {
109*cdf0e10cSrcweir     int      m_Socket;
110*cdf0e10cSrcweir     sal_Char m_Name[PATH_MAX + 1];
111*cdf0e10cSrcweir } oslPipeImpl;
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir /******************************************************************************
115*cdf0e10cSrcweir  *
116*cdf0e10cSrcweir  *                  Function Declarations
117*cdf0e10cSrcweir  *
118*cdf0e10cSrcweir  *****************************************************************************/
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
121*cdf0e10cSrcweir                                                 sal_Char *pszArguments[],
122*cdf0e10cSrcweir                                                 oslProcessOption Options,
123*cdf0e10cSrcweir                                                 oslSecurity Security,
124*cdf0e10cSrcweir                                                 sal_Char *pszDirectory,
125*cdf0e10cSrcweir                                                 sal_Char *pszEnvironments[],
126*cdf0e10cSrcweir                                                 oslProcess *pProcess,
127*cdf0e10cSrcweir 												oslFileHandle *pInputWrite,
128*cdf0e10cSrcweir 												oslFileHandle *pOutputRead,
129*cdf0e10cSrcweir 												oslFileHandle *pErrorRead );
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir oslProcessError SAL_CALL osl_searchPath_impl(
133*cdf0e10cSrcweir 	const sal_Char* pszName,
134*cdf0e10cSrcweir 	const sal_Char* pszPath,
135*cdf0e10cSrcweir 	sal_Char Separator,
136*cdf0e10cSrcweir 	sal_Char *pszBuffer,
137*cdf0e10cSrcweir 	sal_uInt32 Max);
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir sal_Bool osl_getFullPath(const sal_Char* pszFilename, sal_Char* pszPath, sal_uInt32 MaxLen);
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir static oslProcessImpl* ChildList;
143*cdf0e10cSrcweir static oslMutex        ChildListMutex;
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir /******************************************************************************
146*cdf0e10cSrcweir  Deprecated
147*cdf0e10cSrcweir  Old and buggy implementation of osl_searchPath used only by
148*cdf0e10cSrcweir  osl_psz_executeProcess.
149*cdf0e10cSrcweir  A new implemenation is in file_path_helper.cxx
150*cdf0e10cSrcweir  *****************************************************************************/
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir oslProcessError SAL_CALL osl_searchPath_impl(const sal_Char* pszName, const sal_Char* pszPath,
153*cdf0e10cSrcweir 			       sal_Char Separator, sal_Char *pszBuffer, sal_uInt32 Max)
154*cdf0e10cSrcweir {
155*cdf0e10cSrcweir 	sal_Char path[PATH_MAX + 1];
156*cdf0e10cSrcweir 	sal_Char *pchr;
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir     path[0] = '\0';
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir 	OSL_ASSERT(pszName != NULL);
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 	if ( pszName == 0 )
163*cdf0e10cSrcweir 	{
164*cdf0e10cSrcweir 		return osl_Process_E_NotFound;
165*cdf0e10cSrcweir 	}
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir 	if (pszPath == NULL)
168*cdf0e10cSrcweir 		pszPath = "PATH";
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir 	if (Separator == '\0')
171*cdf0e10cSrcweir 		Separator = ':';
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 	if ( (pchr = getenv(pszPath)) != 0 )
175*cdf0e10cSrcweir 	{
176*cdf0e10cSrcweir 		sal_Char *pstr;
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir 		while (*pchr != '\0')
179*cdf0e10cSrcweir 		{
180*cdf0e10cSrcweir 			pstr = path;
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir 			while ((*pchr != '\0') && (*pchr != Separator))
183*cdf0e10cSrcweir 				*pstr++ = *pchr++;
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir 			if ((pstr > path) && ((*(pstr - 1) != '/')))
186*cdf0e10cSrcweir 				*pstr++ = '/';
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir 			*pstr = '\0';
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 			strcat(path, pszName);
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir 			if (access(path, 0) == 0)
193*cdf0e10cSrcweir 			{
194*cdf0e10cSrcweir                 char szRealPathBuf[PATH_MAX] = "";
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir 				if( NULL == realpath(path, szRealPathBuf) || (strlen(szRealPathBuf) >= (sal_uInt32)Max))
197*cdf0e10cSrcweir 					return osl_Process_E_Unknown;
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 				strcpy(pszBuffer, path);
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir 				return osl_Process_E_None;
202*cdf0e10cSrcweir 			}
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir 			if (*pchr == Separator)
205*cdf0e10cSrcweir 				pchr++;
206*cdf0e10cSrcweir 		}
207*cdf0e10cSrcweir 	}
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 	return osl_Process_E_NotFound;
210*cdf0e10cSrcweir }
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir /******************************************************************************
213*cdf0e10cSrcweir  *
214*cdf0e10cSrcweir  *                  New io resource transfer functions
215*cdf0e10cSrcweir  *
216*cdf0e10cSrcweir  *****************************************************************************/
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir /**********************************************
220*cdf0e10cSrcweir  sendFdPipe
221*cdf0e10cSrcweir  *********************************************/
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir static sal_Bool sendFdPipe(int PipeFD, int SocketFD)
224*cdf0e10cSrcweir {
225*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir     struct iovec	iov[1];
228*cdf0e10cSrcweir     struct msghdr	msg;
229*cdf0e10cSrcweir     char			buf[2];	/* send_fd()/recv_fd() 2-byte protocol */
230*cdf0e10cSrcweir     int nSend;
231*cdf0e10cSrcweir     int RetCode=0;
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir #if defined(IOCHANNEL_TRANSFER_BSD)
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir     OSL_TRACE("IOCHANNEL_TRANSFER_BSD send");
236*cdf0e10cSrcweir /*      OSL_TRACE("sending fd %i\n",SocketFD); */
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir     iov[0].iov_base = buf;
239*cdf0e10cSrcweir     iov[0].iov_len  = sizeof(buf);
240*cdf0e10cSrcweir     msg.msg_iov     = iov;
241*cdf0e10cSrcweir     msg.msg_iovlen  = 1;
242*cdf0e10cSrcweir     msg.msg_name    = NULL;
243*cdf0e10cSrcweir     msg.msg_namelen = 0;
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir     msg.msg_accrights    = (caddr_t) &SocketFD;	/* addr of descriptor */
246*cdf0e10cSrcweir     msg.msg_accrightslen = sizeof(int);		/* pass 1 descriptor */
247*cdf0e10cSrcweir     buf[1] = 0;								/* zero status means OK */
248*cdf0e10cSrcweir     buf[0] = 0;								/* null byte flag to recv_fd() */
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir #else
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir     struct cmsghdr* cmptr = (struct cmsghdr*)malloc(CONTROLLEN);
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir     OSL_TRACE("!!!!!! IOCHANNEL_TRANSFER_BSD_RENO send");
255*cdf0e10cSrcweir /*      OSL_TRACE("sending fd %i\n",SocketFD); */
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir     iov[0].iov_base = buf;
258*cdf0e10cSrcweir     iov[0].iov_len = sizeof(buf);
259*cdf0e10cSrcweir     msg.msg_iov = iov;
260*cdf0e10cSrcweir     msg.msg_iovlen = 1;
261*cdf0e10cSrcweir     msg.msg_name = NULL;
262*cdf0e10cSrcweir     msg.msg_namelen = 0;
263*cdf0e10cSrcweir     msg.msg_control = (caddr_t) cmptr;
264*cdf0e10cSrcweir     msg.msg_controllen = CONTROLLEN;
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir     cmptr->cmsg_level = SOL_SOCKET;
267*cdf0e10cSrcweir     cmptr->cmsg_type = SCM_RIGHTS;
268*cdf0e10cSrcweir     cmptr->cmsg_len = CONTROLLEN;
269*cdf0e10cSrcweir     memcpy(CMSG_DATA(cmptr), &SocketFD, sizeof(int));
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir #endif
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir     if ( ( nSend = sendmsg(PipeFD, &msg, 0) ) > 0 )
274*cdf0e10cSrcweir     {
275*cdf0e10cSrcweir         bRet = sal_True;
276*cdf0e10cSrcweir         OSL_TRACE("sendFdPipe : send '%i' bytes\n",nSend);
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir     }
279*cdf0e10cSrcweir     else
280*cdf0e10cSrcweir     {
281*cdf0e10cSrcweir         OSL_TRACE("sendFdPipe : sending failed (%s)",strerror(errno));
282*cdf0e10cSrcweir     }
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir     nSend=read(PipeFD,&RetCode,sizeof(RetCode));
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     if ( nSend > 0 && RetCode == 1 )
287*cdf0e10cSrcweir     {
288*cdf0e10cSrcweir         OSL_TRACE("sendFdPipe : resource was received\n");
289*cdf0e10cSrcweir     }
290*cdf0e10cSrcweir     else
291*cdf0e10cSrcweir     {
292*cdf0e10cSrcweir         OSL_TRACE("sendFdPipe : resource wasn't received\n");
293*cdf0e10cSrcweir     }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir #if defined(IOCHANNEL_TRANSFER_BSD_RENO)
296*cdf0e10cSrcweir     free(cmptr);
297*cdf0e10cSrcweir #endif
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir     return bRet;
300*cdf0e10cSrcweir }
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir /**********************************************
303*cdf0e10cSrcweir  receiveFdPipe
304*cdf0e10cSrcweir  *********************************************/
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir static oslSocket receiveFdPipe(int PipeFD)
307*cdf0e10cSrcweir {
308*cdf0e10cSrcweir     oslSocket pSocket = 0;
309*cdf0e10cSrcweir     struct msghdr msghdr;
310*cdf0e10cSrcweir     struct iovec iov[1];
311*cdf0e10cSrcweir     char buffer[2];
312*cdf0e10cSrcweir     sal_Int32 nRead;
313*cdf0e10cSrcweir     int newfd=-1;
314*cdf0e10cSrcweir     int nRetCode=0;
315*cdf0e10cSrcweir /*      char *ptr; */
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir #if defined(IOCHANNEL_TRANSFER_BSD)
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir     OSL_TRACE("IOCHANNEL_TRANSFER_BSD receive\n");
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir     iov[0].iov_base = buffer;
322*cdf0e10cSrcweir     iov[0].iov_len = sizeof(buffer);
323*cdf0e10cSrcweir     msghdr.msg_name = NULL;
324*cdf0e10cSrcweir     msghdr.msg_namelen = 0;
325*cdf0e10cSrcweir     msghdr.msg_iov = iov;
326*cdf0e10cSrcweir     msghdr.msg_iovlen = 1;
327*cdf0e10cSrcweir     msghdr.msg_accrights = (caddr_t) &newfd; /* addr of descriptor   */
328*cdf0e10cSrcweir     msghdr.msg_accrightslen = sizeof(int);	 /* receive 1 descriptor */
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir #else
331*cdf0e10cSrcweir     struct cmsghdr* cmptr = (struct cmsghdr*)malloc(CONTROLLEN);
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir     OSL_TRACE(" !!!! IOCHANNEL_TRANSFER_BSD_RENO receive");
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir     iov[0].iov_base = buffer;
336*cdf0e10cSrcweir     iov[0].iov_len = sizeof(buffer);
337*cdf0e10cSrcweir     msghdr.msg_name = NULL;
338*cdf0e10cSrcweir     msghdr.msg_namelen = 0;
339*cdf0e10cSrcweir     msghdr.msg_iov = iov;
340*cdf0e10cSrcweir     msghdr.msg_iovlen = 1;
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir     msghdr.msg_control = (caddr_t) cmptr;
343*cdf0e10cSrcweir     msghdr.msg_controllen = CONTROLLEN;
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir #endif
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir #if defined(IOCHANNEL_TRANSFER_BSD)
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir     if ( ( nRead = recvmsg(PipeFD, &msghdr, 0) ) > 0 )
351*cdf0e10cSrcweir     {
352*cdf0e10cSrcweir         OSL_TRACE("receiveFdPipe : received '%i' bytes\n",nRead);
353*cdf0e10cSrcweir     }
354*cdf0e10cSrcweir #else
355*cdf0e10cSrcweir 
356*cdf0e10cSrcweir     if ( ( ( nRead = recvmsg(PipeFD, &msghdr, 0) ) > 0 ) &&
357*cdf0e10cSrcweir          ( msghdr.msg_controllen == CONTROLLEN ) )
358*cdf0e10cSrcweir     {
359*cdf0e10cSrcweir         OSL_TRACE("receiveFdPipe : received '%i' bytes\n",nRead);
360*cdf0e10cSrcweir         memcpy(&newfd, CMSG_DATA(cmptr), sizeof(int));
361*cdf0e10cSrcweir     }
362*cdf0e10cSrcweir #endif
363*cdf0e10cSrcweir     else
364*cdf0e10cSrcweir     {
365*cdf0e10cSrcweir         OSL_TRACE("receiveFdPipe : receiving failed (%s)",strerror(errno));
366*cdf0e10cSrcweir     }
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir     if ( newfd >= 0 )
369*cdf0e10cSrcweir     {
370*cdf0e10cSrcweir         pSocket = __osl_createSocketImpl(newfd);
371*cdf0e10cSrcweir         nRetCode=1;
372*cdf0e10cSrcweir         OSL_TRACE("received fd %i\n",newfd);
373*cdf0e10cSrcweir     }
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir     OSL_TRACE("receiveFdPipe : writing back %i",nRetCode);
376*cdf0e10cSrcweir     nRead=write(PipeFD,&nRetCode,sizeof(nRetCode));
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir #if defined(IOCHANNEL_TRANSFER_BSD_RENO)
379*cdf0e10cSrcweir     free(cmptr);
380*cdf0e10cSrcweir #endif
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir     return pSocket;
383*cdf0e10cSrcweir }
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir /**********************************************
386*cdf0e10cSrcweir  osl_sendResourcePipe
387*cdf0e10cSrcweir  *********************************************/
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir sal_Bool osl_sendResourcePipe(oslPipe pPipe, oslSocket pSocket)
390*cdf0e10cSrcweir {
391*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir     if ( pSocket == 0 || pPipe == 0 )
394*cdf0e10cSrcweir     {
395*cdf0e10cSrcweir         return sal_False;
396*cdf0e10cSrcweir     }
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir     bRet = sendFdPipe(pPipe->m_Socket,pSocket->m_Socket);
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir     return bRet;
401*cdf0e10cSrcweir }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir /**********************************************
404*cdf0e10cSrcweir  osl_receiveResourcePipe
405*cdf0e10cSrcweir  *********************************************/
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir oslSocket osl_receiveResourcePipe(oslPipe pPipe)
408*cdf0e10cSrcweir {
409*cdf0e10cSrcweir     oslSocket pSocket=0;
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir     if ( pPipe ==  0 )
412*cdf0e10cSrcweir     {
413*cdf0e10cSrcweir         return 0;
414*cdf0e10cSrcweir     }
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir     pSocket = receiveFdPipe(pPipe->m_Socket);
417*cdf0e10cSrcweir 
418*cdf0e10cSrcweir     return (oslSocket) pSocket;
419*cdf0e10cSrcweir }
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir /******************************************************************************
424*cdf0e10cSrcweir  *
425*cdf0e10cSrcweir  *                  Functions for starting a process
426*cdf0e10cSrcweir  *
427*cdf0e10cSrcweir  *****************************************************************************/
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir static void ChildStatusProc(void *pData)
430*cdf0e10cSrcweir {
431*cdf0e10cSrcweir 	pid_t pid = -1;
432*cdf0e10cSrcweir 	int   status = 0;
433*cdf0e10cSrcweir 	int   channel[2];
434*cdf0e10cSrcweir 	ProcessData  data;
435*cdf0e10cSrcweir 	ProcessData *pdata;
436*cdf0e10cSrcweir 	int		stdOutput[2] = { -1, -1 }, stdInput[2] = { -1, -1 }, stdError[2] = { -1, -1 };
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir 	pdata = (ProcessData *)pData;
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir 	/* make a copy of our data, because forking will only copy
441*cdf0e10cSrcweir 	   our local stack of the thread, so the process data will not be accessible
442*cdf0e10cSrcweir 	   in our child process */
443*cdf0e10cSrcweir 	memcpy(&data, pData, sizeof(data));
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir     if (socketpair(AF_UNIX, SOCK_STREAM, 0, channel) == -1)
446*cdf0e10cSrcweir         status = errno;
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir     fcntl(channel[0], F_SETFD, FD_CLOEXEC);
449*cdf0e10cSrcweir     fcntl(channel[1], F_SETFD, FD_CLOEXEC);
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir 	/* Create redirected IO pipes */
452*cdf0e10cSrcweir 	if ( status == 0 && data.m_pInputWrite )
453*cdf0e10cSrcweir 		if (pipe( stdInput ) == -1)
454*cdf0e10cSrcweir 		    status = errno;
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir 	if ( status == 0 && data.m_pOutputRead )
457*cdf0e10cSrcweir 		if (pipe( stdOutput ) == -1)
458*cdf0e10cSrcweir 		    status = errno;
459*cdf0e10cSrcweir 
460*cdf0e10cSrcweir 	if ( status == 0 && data.m_pErrorRead )
461*cdf0e10cSrcweir 		if (pipe( stdError ) == -1)
462*cdf0e10cSrcweir 		    status = errno;
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir     if ( (status == 0) && ((pid = fork()) == 0) )
465*cdf0e10cSrcweir     {
466*cdf0e10cSrcweir 		/* Child */
467*cdf0e10cSrcweir         int chstatus = 0;
468*cdf0e10cSrcweir         sal_Int32 nWrote;
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir 	    if (channel[0] != -1) close(channel[0]);
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir 		if ((data.m_uid != (uid_t)-1) && ((data.m_uid != getuid()) || (data.m_gid != getgid())))
473*cdf0e10cSrcweir 		{
474*cdf0e10cSrcweir 			OSL_ASSERT(geteuid() == 0);		/* must be root */
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir 			if (! INIT_GROUPS(data.m_name, data.m_gid) || (setuid(data.m_uid) != 0))
477*cdf0e10cSrcweir 				OSL_TRACE("Failed to change uid and guid, errno=%d (%s)\n", errno, strerror(errno));
478*cdf0e10cSrcweir #if defined(LINUX) || defined (FREEBSD)
479*cdf0e10cSrcweir 			unsetenv("HOME");
480*cdf0e10cSrcweir #else
481*cdf0e10cSrcweir 			putenv("HOME=");
482*cdf0e10cSrcweir #endif
483*cdf0e10cSrcweir 		}
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir   		if (data.m_pszDir)
486*cdf0e10cSrcweir   			chstatus = chdir(data.m_pszDir);
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir    	    if (chstatus == 0 && ((data.m_uid == (uid_t)-1) || ((data.m_uid == getuid()) && (data.m_gid == getgid()))))
489*cdf0e10cSrcweir 		{
490*cdf0e10cSrcweir             int i;
491*cdf0e10cSrcweir 			for (i = 0; data.m_pszEnv[i] != NULL; i++)
492*cdf0e10cSrcweir             {
493*cdf0e10cSrcweir                 if (strchr(data.m_pszEnv[i], '=') == NULL)
494*cdf0e10cSrcweir                 {
495*cdf0e10cSrcweir                     unsetenv(data.m_pszEnv[i]); /*TODO: check error return*/
496*cdf0e10cSrcweir                 }
497*cdf0e10cSrcweir                 else
498*cdf0e10cSrcweir                 {
499*cdf0e10cSrcweir                     putenv(data.m_pszEnv[i]); /*TODO: check error return*/
500*cdf0e10cSrcweir                 }
501*cdf0e10cSrcweir             }
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir             OSL_TRACE("ChildStatusProc : starting '%s'",data.m_pszArgs[0]);
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir 			/* Connect std IO to pipe ends */
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir 			/* Write end of stdInput not used in child process */
508*cdf0e10cSrcweir 			if (stdInput[1] != -1) close( stdInput[1] );
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir 			/* Read end of stdOutput not used in child process */
511*cdf0e10cSrcweir 			if (stdOutput[0] != -1) close( stdOutput[0] );
512*cdf0e10cSrcweir 
513*cdf0e10cSrcweir 			/* Read end of stdError not used in child process */
514*cdf0e10cSrcweir 			if (stdError[0] != -1) close( stdError[0] );
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir 			/* Redirect pipe ends to std IO */
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir 			if ( stdInput[0] != STDIN_FILENO )
519*cdf0e10cSrcweir 			{
520*cdf0e10cSrcweir 				dup2( stdInput[0], STDIN_FILENO );
521*cdf0e10cSrcweir 				if (stdInput[0] != -1) close( stdInput[0] );
522*cdf0e10cSrcweir 			}
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir 			if ( stdOutput[1] != STDOUT_FILENO )
525*cdf0e10cSrcweir 			{
526*cdf0e10cSrcweir 				dup2( stdOutput[1], STDOUT_FILENO );
527*cdf0e10cSrcweir 				if (stdOutput[1] != -1) close( stdOutput[1] );
528*cdf0e10cSrcweir 			}
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir 			if ( stdError[1] != STDERR_FILENO )
531*cdf0e10cSrcweir 			{
532*cdf0e10cSrcweir 				dup2( stdError[1], STDERR_FILENO );
533*cdf0e10cSrcweir 				if (stdError[1] != -1) close( stdError[1] );
534*cdf0e10cSrcweir 			}
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir 	    	pid=execv(data.m_pszArgs[0], (sal_Char **)data.m_pszArgs);
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir 		}
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir         OSL_TRACE("Failed to exec, errno=%d (%s)\n", errno, strerror(errno));
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir         OSL_TRACE("ChildStatusProc : starting '%s' failed",data.m_pszArgs[0]);
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir 		/* if we reach here, something went wrong */
545*cdf0e10cSrcweir         nWrote = write(channel[1], &errno, sizeof(errno));
546*cdf0e10cSrcweir 		if (nWrote != sizeof(errno))
547*cdf0e10cSrcweir             OSL_TRACE("sendFdPipe : sending failed (%s)",strerror(errno));
548*cdf0e10cSrcweir 
549*cdf0e10cSrcweir 	    if (channel[1] != -1) close(channel[1]);
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir 		_exit(255);
552*cdf0e10cSrcweir     }
553*cdf0e10cSrcweir     else
554*cdf0e10cSrcweir     {   /* Parent  */
555*cdf0e10cSrcweir         int i = -1;
556*cdf0e10cSrcweir 		if (channel[1] != -1) close(channel[1]);
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir 		/* Close unused pipe ends */
559*cdf0e10cSrcweir 		if (stdInput[0] != -1) close( stdInput[0] );
560*cdf0e10cSrcweir 		if (stdOutput[1] != -1) close( stdOutput[1] );
561*cdf0e10cSrcweir 		if (stdError[1] != -1) close( stdError[1] );
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir 		if (pid > 0)
564*cdf0e10cSrcweir 		{
565*cdf0e10cSrcweir 			while (((i = read(channel[0], &status, sizeof(status))) < 0))
566*cdf0e10cSrcweir 			{
567*cdf0e10cSrcweir 				if (errno != EINTR)
568*cdf0e10cSrcweir 					break;
569*cdf0e10cSrcweir 			}
570*cdf0e10cSrcweir 		}
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir 		if (channel[0] != -1) close(channel[0]);
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir 		if ((pid > 0) && (i == 0))
575*cdf0e10cSrcweir 		{
576*cdf0e10cSrcweir 			pid_t	child_pid;
577*cdf0e10cSrcweir 			osl_acquireMutex(ChildListMutex);
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir 			pdata->m_pProcImpl->m_pid = pid;
580*cdf0e10cSrcweir 			pdata->m_pProcImpl->m_pnext = ChildList;
581*cdf0e10cSrcweir 			ChildList = pdata->m_pProcImpl;
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir 			/* Store used pipe ends in data structure */
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir 			if ( pdata->m_pInputWrite )
586*cdf0e10cSrcweir 				*(pdata->m_pInputWrite) = osl_createFileHandleFromFD( stdInput[1] );
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir 			if ( pdata->m_pOutputRead )
589*cdf0e10cSrcweir 				*(pdata->m_pOutputRead) = osl_createFileHandleFromFD( stdOutput[0] );
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir 			if ( pdata->m_pErrorRead )
592*cdf0e10cSrcweir 				*(pdata->m_pErrorRead) = osl_createFileHandleFromFD( stdError[0] );
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir 			osl_releaseMutex(ChildListMutex);
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir 			osl_setCondition(pdata->m_started);
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir 			do
599*cdf0e10cSrcweir 			{
600*cdf0e10cSrcweir 				child_pid = waitpid(pid, &status, 0);
601*cdf0e10cSrcweir 			} while ( 0 > child_pid && EINTR == errno );
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir 			if ( child_pid < 0)
604*cdf0e10cSrcweir 			{
605*cdf0e10cSrcweir 				OSL_TRACE("Failed to wait for child process, errno=%d (%s)\n", errno, strerror(errno));
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir 				/*
608*cdf0e10cSrcweir 				We got an other error than EINTR. Anyway we have to wake up the
609*cdf0e10cSrcweir 				waiting thread under any circumstances */
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir 				child_pid = pid;
612*cdf0e10cSrcweir 			}
613*cdf0e10cSrcweir 
614*cdf0e10cSrcweir 
615*cdf0e10cSrcweir 			if ( child_pid > 0 )
616*cdf0e10cSrcweir 			{
617*cdf0e10cSrcweir 				oslProcessImpl* pChild;
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir 				osl_acquireMutex(ChildListMutex);
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir 				pChild = ChildList;
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir 				/* check if it is one of our child processes */
624*cdf0e10cSrcweir 				while (pChild != NULL)
625*cdf0e10cSrcweir 				{
626*cdf0e10cSrcweir 					if (pChild->m_pid == child_pid)
627*cdf0e10cSrcweir 					{
628*cdf0e10cSrcweir 						if (WIFEXITED(status))
629*cdf0e10cSrcweir 							pChild->m_status = WEXITSTATUS(status);
630*cdf0e10cSrcweir 						else
631*cdf0e10cSrcweir 							pChild->m_status = -1;
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir 						osl_setCondition(pChild->m_terminated);
634*cdf0e10cSrcweir 					}
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir 					pChild = pChild->m_pnext;
637*cdf0e10cSrcweir 				}
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir 				osl_releaseMutex(ChildListMutex);
640*cdf0e10cSrcweir 			}
641*cdf0e10cSrcweir 		}
642*cdf0e10cSrcweir 		else
643*cdf0e10cSrcweir 		{
644*cdf0e10cSrcweir             OSL_TRACE("ChildStatusProc : starting '%s' failed",data.m_pszArgs[0]);
645*cdf0e10cSrcweir 			OSL_TRACE("Failed to launch child process, child reports errno=%d (%s)\n", status, strerror(status));
646*cdf0e10cSrcweir 
647*cdf0e10cSrcweir 			/* Close pipe ends */
648*cdf0e10cSrcweir 			if ( pdata->m_pInputWrite )
649*cdf0e10cSrcweir 				*pdata->m_pInputWrite = NULL;
650*cdf0e10cSrcweir 
651*cdf0e10cSrcweir 			if ( pdata->m_pOutputRead )
652*cdf0e10cSrcweir 				*pdata->m_pOutputRead = NULL;
653*cdf0e10cSrcweir 
654*cdf0e10cSrcweir 			if ( pdata->m_pErrorRead )
655*cdf0e10cSrcweir 				*pdata->m_pErrorRead = NULL;
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir 			if (stdInput[1] != -1) close( stdInput[1] );
658*cdf0e10cSrcweir 			if (stdOutput[0] != -1) close( stdOutput[0] );
659*cdf0e10cSrcweir 			if (stdError[0] != -1) close( stdError[0] );
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir             //if pid > 0 then a process was created, even if it later failed
662*cdf0e10cSrcweir             //e.g. bash searching for a command to execute, and we still
663*cdf0e10cSrcweir             //need to clean it up to avoid "defunct" processes
664*cdf0e10cSrcweir             if (pid > 0)
665*cdf0e10cSrcweir             {
666*cdf0e10cSrcweir                 pid_t child_pid;
667*cdf0e10cSrcweir                 do
668*cdf0e10cSrcweir                 {
669*cdf0e10cSrcweir                     child_pid = waitpid(pid, &status, 0);
670*cdf0e10cSrcweir                 } while ( 0 > child_pid && EINTR == errno );
671*cdf0e10cSrcweir             }
672*cdf0e10cSrcweir 
673*cdf0e10cSrcweir 			/* notify (and unblock) parent thread */
674*cdf0e10cSrcweir 			osl_setCondition(pdata->m_started);
675*cdf0e10cSrcweir 		}
676*cdf0e10cSrcweir 	}
677*cdf0e10cSrcweir }
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir /**********************************************
680*cdf0e10cSrcweir  osl_executeProcess_WithRedirectedIO
681*cdf0e10cSrcweir  *********************************************/
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir oslProcessError SAL_CALL osl_executeProcess_WithRedirectedIO(
684*cdf0e10cSrcweir 											rtl_uString *ustrImageName,
685*cdf0e10cSrcweir 											rtl_uString *ustrArguments[],
686*cdf0e10cSrcweir                                             sal_uInt32   nArguments,
687*cdf0e10cSrcweir 											oslProcessOption Options,
688*cdf0e10cSrcweir 											oslSecurity Security,
689*cdf0e10cSrcweir 											rtl_uString *ustrWorkDir,
690*cdf0e10cSrcweir 											rtl_uString *ustrEnvironment[],
691*cdf0e10cSrcweir                                             sal_uInt32   nEnvironmentVars,
692*cdf0e10cSrcweir 											oslProcess *pProcess,
693*cdf0e10cSrcweir 											oslFileHandle	*pInputWrite,
694*cdf0e10cSrcweir 											oslFileHandle	*pOutputRead,
695*cdf0e10cSrcweir 											oslFileHandle	*pErrorRead
696*cdf0e10cSrcweir 											)
697*cdf0e10cSrcweir {
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir     oslProcessError Error;
700*cdf0e10cSrcweir     sal_Char* pszWorkDir=0;
701*cdf0e10cSrcweir     sal_Char** pArguments=0;
702*cdf0e10cSrcweir     sal_Char** pEnvironment=0;
703*cdf0e10cSrcweir     unsigned int idx;
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir     char szImagePath[PATH_MAX] = "";
706*cdf0e10cSrcweir     char szWorkDir[PATH_MAX] = "";
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir     if ( ustrImageName && ustrImageName->length )
709*cdf0e10cSrcweir     {
710*cdf0e10cSrcweir         FileURLToPath( szImagePath, PATH_MAX, ustrImageName );
711*cdf0e10cSrcweir     }
712*cdf0e10cSrcweir 
713*cdf0e10cSrcweir     if ( ustrWorkDir != 0 && ustrWorkDir->length )
714*cdf0e10cSrcweir     {
715*cdf0e10cSrcweir         FileURLToPath( szWorkDir, PATH_MAX, ustrWorkDir );
716*cdf0e10cSrcweir         pszWorkDir = szWorkDir;
717*cdf0e10cSrcweir     }
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir     if ( pArguments == 0 && nArguments > 0 )
720*cdf0e10cSrcweir     {
721*cdf0e10cSrcweir         pArguments = (sal_Char**) malloc( ( nArguments + 2 ) * sizeof(sal_Char*) );
722*cdf0e10cSrcweir     }
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir     for ( idx = 0 ; idx < nArguments ; ++idx )
726*cdf0e10cSrcweir     {
727*cdf0e10cSrcweir         rtl_String* strArg =0;
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir         rtl_uString2String( &strArg,
731*cdf0e10cSrcweir                             rtl_uString_getStr(ustrArguments[idx]),
732*cdf0e10cSrcweir                             rtl_uString_getLength(ustrArguments[idx]),
733*cdf0e10cSrcweir                             osl_getThreadTextEncoding(),
734*cdf0e10cSrcweir                             OUSTRING_TO_OSTRING_CVTFLAGS );
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir         pArguments[idx]=strdup(rtl_string_getStr(strArg));
737*cdf0e10cSrcweir         rtl_string_release(strArg);
738*cdf0e10cSrcweir 		pArguments[idx+1]=0;
739*cdf0e10cSrcweir     }
740*cdf0e10cSrcweir 
741*cdf0e10cSrcweir     for ( idx = 0 ; idx < nEnvironmentVars ; ++idx )
742*cdf0e10cSrcweir     {
743*cdf0e10cSrcweir         rtl_String* strEnv=0;
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir         if ( pEnvironment == 0 )
746*cdf0e10cSrcweir         {
747*cdf0e10cSrcweir             pEnvironment = (sal_Char**) malloc( ( nEnvironmentVars + 2 ) * sizeof(sal_Char*) );
748*cdf0e10cSrcweir         }
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir         rtl_uString2String( &strEnv,
751*cdf0e10cSrcweir                             rtl_uString_getStr(ustrEnvironment[idx]),
752*cdf0e10cSrcweir                             rtl_uString_getLength(ustrEnvironment[idx]),
753*cdf0e10cSrcweir                             osl_getThreadTextEncoding(),
754*cdf0e10cSrcweir                             OUSTRING_TO_OSTRING_CVTFLAGS );
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir         pEnvironment[idx]=strdup(rtl_string_getStr(strEnv));
757*cdf0e10cSrcweir         rtl_string_release(strEnv);
758*cdf0e10cSrcweir         pEnvironment[idx+1]=0;
759*cdf0e10cSrcweir     }
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir     Error = osl_psz_executeProcess(szImagePath,
763*cdf0e10cSrcweir                                    pArguments,
764*cdf0e10cSrcweir                                    Options,
765*cdf0e10cSrcweir                                    Security,
766*cdf0e10cSrcweir                                    pszWorkDir,
767*cdf0e10cSrcweir                                    pEnvironment,
768*cdf0e10cSrcweir                                    pProcess,
769*cdf0e10cSrcweir 								   pInputWrite,
770*cdf0e10cSrcweir 								   pOutputRead,
771*cdf0e10cSrcweir 								   pErrorRead
772*cdf0e10cSrcweir 								   );
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir     if ( pArguments != 0 )
775*cdf0e10cSrcweir     {
776*cdf0e10cSrcweir         for ( idx = 0 ; idx < nArguments ; ++idx )
777*cdf0e10cSrcweir         {
778*cdf0e10cSrcweir             if ( pArguments[idx] != 0 )
779*cdf0e10cSrcweir             {
780*cdf0e10cSrcweir                 free(pArguments[idx]);
781*cdf0e10cSrcweir             }
782*cdf0e10cSrcweir         }
783*cdf0e10cSrcweir         free(pArguments);
784*cdf0e10cSrcweir     }
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir     if ( pEnvironment != 0 )
787*cdf0e10cSrcweir     {
788*cdf0e10cSrcweir         for ( idx = 0 ; idx < nEnvironmentVars ; ++idx )
789*cdf0e10cSrcweir         {
790*cdf0e10cSrcweir             if ( pEnvironment[idx] != 0 )
791*cdf0e10cSrcweir             {
792*cdf0e10cSrcweir                 free(pEnvironment[idx]);
793*cdf0e10cSrcweir             }
794*cdf0e10cSrcweir         }
795*cdf0e10cSrcweir         free(pEnvironment);
796*cdf0e10cSrcweir     }
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir     return Error;
799*cdf0e10cSrcweir }
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir /**********************************************
802*cdf0e10cSrcweir  osl_executeProcess
803*cdf0e10cSrcweir  *********************************************/
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir oslProcessError SAL_CALL osl_executeProcess(
806*cdf0e10cSrcweir 											rtl_uString *ustrImageName,
807*cdf0e10cSrcweir 											rtl_uString *ustrArguments[],
808*cdf0e10cSrcweir                                             sal_uInt32   nArguments,
809*cdf0e10cSrcweir 											oslProcessOption Options,
810*cdf0e10cSrcweir 											oslSecurity Security,
811*cdf0e10cSrcweir 											rtl_uString *ustrWorkDir,
812*cdf0e10cSrcweir 											rtl_uString *ustrEnvironment[],
813*cdf0e10cSrcweir                                             sal_uInt32   nEnvironmentVars,
814*cdf0e10cSrcweir 											oslProcess *pProcess
815*cdf0e10cSrcweir 											)
816*cdf0e10cSrcweir {
817*cdf0e10cSrcweir 	return osl_executeProcess_WithRedirectedIO(
818*cdf0e10cSrcweir 		ustrImageName,
819*cdf0e10cSrcweir 		ustrArguments,
820*cdf0e10cSrcweir 		nArguments,
821*cdf0e10cSrcweir 		Options,
822*cdf0e10cSrcweir 		Security,
823*cdf0e10cSrcweir 		ustrWorkDir,
824*cdf0e10cSrcweir 		ustrEnvironment,
825*cdf0e10cSrcweir 		nEnvironmentVars,
826*cdf0e10cSrcweir 		pProcess,
827*cdf0e10cSrcweir 		NULL,
828*cdf0e10cSrcweir 		NULL,
829*cdf0e10cSrcweir 		NULL
830*cdf0e10cSrcweir 		);
831*cdf0e10cSrcweir }
832*cdf0e10cSrcweir 
833*cdf0e10cSrcweir /**********************************************
834*cdf0e10cSrcweir  osl_psz_executeProcess
835*cdf0e10cSrcweir  *********************************************/
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir oslProcessError SAL_CALL osl_psz_executeProcess(sal_Char *pszImageName,
838*cdf0e10cSrcweir                                                 sal_Char *pszArguments[],
839*cdf0e10cSrcweir                                                 oslProcessOption Options,
840*cdf0e10cSrcweir                                                 oslSecurity Security,
841*cdf0e10cSrcweir                                                 sal_Char *pszDirectory,
842*cdf0e10cSrcweir                                                 sal_Char *pszEnvironments[],
843*cdf0e10cSrcweir                                                 oslProcess *pProcess,
844*cdf0e10cSrcweir 												oslFileHandle	*pInputWrite,
845*cdf0e10cSrcweir 												oslFileHandle	*pOutputRead,
846*cdf0e10cSrcweir 												oslFileHandle	*pErrorRead
847*cdf0e10cSrcweir 												)
848*cdf0e10cSrcweir {
849*cdf0e10cSrcweir     int     i;
850*cdf0e10cSrcweir 	sal_Char    path[PATH_MAX + 1];
851*cdf0e10cSrcweir 	ProcessData Data;
852*cdf0e10cSrcweir 	oslThread hThread;
853*cdf0e10cSrcweir 
854*cdf0e10cSrcweir     path[0] = '\0';
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir     memset(&Data,0,sizeof(ProcessData));
857*cdf0e10cSrcweir 	Data.m_pInputWrite = pInputWrite;
858*cdf0e10cSrcweir 	Data.m_pOutputRead = pOutputRead;
859*cdf0e10cSrcweir 	Data.m_pErrorRead = pErrorRead;
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir 	if (pszImageName == NULL)
862*cdf0e10cSrcweir 		pszImageName = pszArguments[0];
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir 	OSL_ASSERT(pszImageName != NULL);
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir 	if ( pszImageName == 0 )
867*cdf0e10cSrcweir 	{
868*cdf0e10cSrcweir 		return osl_Process_E_NotFound;
869*cdf0e10cSrcweir 	}
870*cdf0e10cSrcweir 
871*cdf0e10cSrcweir 	if ((Options & osl_Process_SEARCHPATH) &&
872*cdf0e10cSrcweir 		(osl_searchPath_impl(pszImageName, NULL, '\0', path, sizeof(path)) == osl_Process_E_None))
873*cdf0e10cSrcweir 		pszImageName = path;
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir 	Data.m_pszArgs[0] = strdup(pszImageName);
876*cdf0e10cSrcweir 	Data.m_pszArgs[1] = 0;
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir     if ( pszArguments != 0 )
879*cdf0e10cSrcweir     {
880*cdf0e10cSrcweir         for (i = 0; ((i + 2) < MAX_ARGS) && (pszArguments[i] != NULL); i++)
881*cdf0e10cSrcweir             Data.m_pszArgs[i+1] = strdup(pszArguments[i]);
882*cdf0e10cSrcweir         Data.m_pszArgs[i+2] = NULL;
883*cdf0e10cSrcweir     }
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir 	Data.m_options = Options;
886*cdf0e10cSrcweir 	Data.m_pszDir  = (pszDirectory != NULL) ? strdup(pszDirectory) : NULL;
887*cdf0e10cSrcweir 
888*cdf0e10cSrcweir 	if (pszEnvironments != NULL)
889*cdf0e10cSrcweir 	{
890*cdf0e10cSrcweir 		for (i = 0; ((i + 1) < MAX_ENVS) &&  (pszEnvironments[i] != NULL); i++)
891*cdf0e10cSrcweir 			Data.m_pszEnv[i] = strdup(pszEnvironments[i]);
892*cdf0e10cSrcweir 	 	Data.m_pszEnv[i+1] = NULL;
893*cdf0e10cSrcweir 	}
894*cdf0e10cSrcweir 	else
895*cdf0e10cSrcweir 	 	Data.m_pszEnv[0] = NULL;
896*cdf0e10cSrcweir 
897*cdf0e10cSrcweir 	if (Security != NULL)
898*cdf0e10cSrcweir 	{
899*cdf0e10cSrcweir 	    Data.m_uid  = ((oslSecurityImpl*)Security)->m_pPasswd.pw_uid;
900*cdf0e10cSrcweir 	    Data.m_gid  = ((oslSecurityImpl*)Security)->m_pPasswd.pw_gid;
901*cdf0e10cSrcweir 		Data.m_name = ((oslSecurityImpl*)Security)->m_pPasswd.pw_name;
902*cdf0e10cSrcweir 	}
903*cdf0e10cSrcweir 	else
904*cdf0e10cSrcweir 		Data.m_uid = (uid_t)-1;
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir 	Data.m_pProcImpl = (oslProcessImpl*) malloc(sizeof(oslProcessImpl));
907*cdf0e10cSrcweir 	Data.m_pProcImpl->m_pid = 0;
908*cdf0e10cSrcweir 	Data.m_pProcImpl->m_terminated = osl_createCondition();
909*cdf0e10cSrcweir 	Data.m_pProcImpl->m_pnext = NULL;
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir 	if (ChildListMutex == NULL)
912*cdf0e10cSrcweir 		ChildListMutex = osl_createMutex();
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir 	Data.m_started = osl_createCondition();
915*cdf0e10cSrcweir 
916*cdf0e10cSrcweir 	hThread = osl_createThread(ChildStatusProc, &Data);
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir 	osl_waitCondition(Data.m_started, NULL);
919*cdf0e10cSrcweir     osl_destroyCondition(Data.m_started);
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir     for (i = 0; Data.m_pszArgs[i] != NULL; i++)
922*cdf0e10cSrcweir 		  free((void *)Data.m_pszArgs[i]);
923*cdf0e10cSrcweir 
924*cdf0e10cSrcweir     for (i = 0; Data.m_pszEnv[i] != NULL; i++)
925*cdf0e10cSrcweir 		  free((void *)Data.m_pszEnv[i]);
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir     if ( Data.m_pszDir != 0 )
928*cdf0e10cSrcweir     {
929*cdf0e10cSrcweir 		free((void *)Data.m_pszDir);
930*cdf0e10cSrcweir     }
931*cdf0e10cSrcweir 
932*cdf0e10cSrcweir 	osl_destroyThread(hThread);
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir 	if (Data.m_pProcImpl->m_pid != 0)
935*cdf0e10cSrcweir 	{
936*cdf0e10cSrcweir 		*pProcess = Data.m_pProcImpl;
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir 	 	if (Options & osl_Process_WAIT)
939*cdf0e10cSrcweir 			osl_joinProcess(*pProcess);
940*cdf0e10cSrcweir 
941*cdf0e10cSrcweir 		return osl_Process_E_None;
942*cdf0e10cSrcweir     }
943*cdf0e10cSrcweir 
944*cdf0e10cSrcweir 	osl_destroyCondition(Data.m_pProcImpl->m_terminated);
945*cdf0e10cSrcweir 	free(Data.m_pProcImpl);
946*cdf0e10cSrcweir 
947*cdf0e10cSrcweir 	return osl_Process_E_Unknown;
948*cdf0e10cSrcweir }
949*cdf0e10cSrcweir 
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir /******************************************************************************
952*cdf0e10cSrcweir  *
953*cdf0e10cSrcweir  *                  Functions for processes
954*cdf0e10cSrcweir  *
955*cdf0e10cSrcweir  *****************************************************************************/
956*cdf0e10cSrcweir 
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir /**********************************************
959*cdf0e10cSrcweir  osl_terminateProcess
960*cdf0e10cSrcweir  *********************************************/
961*cdf0e10cSrcweir 
962*cdf0e10cSrcweir oslProcessError SAL_CALL osl_terminateProcess(oslProcess Process)
963*cdf0e10cSrcweir {
964*cdf0e10cSrcweir     if (Process == NULL)
965*cdf0e10cSrcweir 	    return osl_Process_E_Unknown;
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir 	if (kill(((oslProcessImpl*)Process)->m_pid, SIGKILL) != 0)
968*cdf0e10cSrcweir 	{
969*cdf0e10cSrcweir 		switch (errno)
970*cdf0e10cSrcweir 		{
971*cdf0e10cSrcweir 			case EPERM:
972*cdf0e10cSrcweir 				return osl_Process_E_NoPermission;
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir 			case ESRCH:
975*cdf0e10cSrcweir 			    return osl_Process_E_NotFound;
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir 			default:
978*cdf0e10cSrcweir 			    return osl_Process_E_Unknown;
979*cdf0e10cSrcweir 		}
980*cdf0e10cSrcweir 	}
981*cdf0e10cSrcweir 
982*cdf0e10cSrcweir 	return osl_Process_E_None;
983*cdf0e10cSrcweir }
984*cdf0e10cSrcweir 
985*cdf0e10cSrcweir /**********************************************
986*cdf0e10cSrcweir  osl_getProcess
987*cdf0e10cSrcweir  *********************************************/
988*cdf0e10cSrcweir 
989*cdf0e10cSrcweir oslProcess SAL_CALL osl_getProcess(oslProcessIdentifier Ident)
990*cdf0e10cSrcweir {
991*cdf0e10cSrcweir 	oslProcessImpl *pProcImpl;
992*cdf0e10cSrcweir 
993*cdf0e10cSrcweir 	if (kill(Ident, 0) != -1)
994*cdf0e10cSrcweir 	{
995*cdf0e10cSrcweir 		oslProcessImpl* pChild;
996*cdf0e10cSrcweir 
997*cdf0e10cSrcweir 		if (ChildListMutex == NULL)
998*cdf0e10cSrcweir 			ChildListMutex = osl_createMutex();
999*cdf0e10cSrcweir 
1000*cdf0e10cSrcweir 		osl_acquireMutex(ChildListMutex);
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir 		pChild = ChildList;
1003*cdf0e10cSrcweir 
1004*cdf0e10cSrcweir 		/* check if it is one of our child processes */
1005*cdf0e10cSrcweir 		while (pChild != NULL)
1006*cdf0e10cSrcweir 		{
1007*cdf0e10cSrcweir 			if (Ident == (sal_uInt32) pChild->m_pid)
1008*cdf0e10cSrcweir 				break;
1009*cdf0e10cSrcweir 
1010*cdf0e10cSrcweir 			pChild = pChild->m_pnext;
1011*cdf0e10cSrcweir 		}
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir 		pProcImpl = (oslProcessImpl*) malloc(sizeof(oslProcessImpl));
1014*cdf0e10cSrcweir 		pProcImpl->m_pid        = Ident;
1015*cdf0e10cSrcweir 		pProcImpl->m_terminated = osl_createCondition();
1016*cdf0e10cSrcweir 
1017*cdf0e10cSrcweir 		if (pChild != NULL)
1018*cdf0e10cSrcweir 		{
1019*cdf0e10cSrcweir 			/* process is a child so insert into list */
1020*cdf0e10cSrcweir 			pProcImpl->m_pnext = pChild->m_pnext;
1021*cdf0e10cSrcweir 			pChild->m_pnext = pProcImpl;
1022*cdf0e10cSrcweir 
1023*cdf0e10cSrcweir 			pProcImpl->m_status = pChild->m_status;
1024*cdf0e10cSrcweir 
1025*cdf0e10cSrcweir 			if (osl_checkCondition(pChild->m_terminated))
1026*cdf0e10cSrcweir 				osl_setCondition(pProcImpl->m_terminated);
1027*cdf0e10cSrcweir 		}
1028*cdf0e10cSrcweir 		else
1029*cdf0e10cSrcweir 			pProcImpl->m_pnext = NULL;
1030*cdf0e10cSrcweir 
1031*cdf0e10cSrcweir 		osl_releaseMutex(ChildListMutex);
1032*cdf0e10cSrcweir 	}
1033*cdf0e10cSrcweir 	else
1034*cdf0e10cSrcweir 		pProcImpl = NULL;
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir 	return (pProcImpl);
1037*cdf0e10cSrcweir }
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir /**********************************************
1040*cdf0e10cSrcweir  osl_freeProcessHandle
1041*cdf0e10cSrcweir  *********************************************/
1042*cdf0e10cSrcweir 
1043*cdf0e10cSrcweir void SAL_CALL osl_freeProcessHandle(oslProcess Process)
1044*cdf0e10cSrcweir {
1045*cdf0e10cSrcweir     if (Process != NULL)
1046*cdf0e10cSrcweir 	{
1047*cdf0e10cSrcweir 		oslProcessImpl *pChild, *pPrev = NULL;
1048*cdf0e10cSrcweir 
1049*cdf0e10cSrcweir 		OSL_ASSERT(ChildListMutex != NULL);
1050*cdf0e10cSrcweir 
1051*cdf0e10cSrcweir 		if ( ChildListMutex == 0 )
1052*cdf0e10cSrcweir 		{
1053*cdf0e10cSrcweir 			return;
1054*cdf0e10cSrcweir 		}
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir 		osl_acquireMutex(ChildListMutex);
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir 		pChild = ChildList;
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir 		/* remove process from child list */
1061*cdf0e10cSrcweir 		while (pChild != NULL)
1062*cdf0e10cSrcweir 		{
1063*cdf0e10cSrcweir 			if (pChild == (oslProcessImpl*)Process)
1064*cdf0e10cSrcweir 			{
1065*cdf0e10cSrcweir 				if (pPrev != NULL)
1066*cdf0e10cSrcweir 					pPrev->m_pnext = pChild->m_pnext;
1067*cdf0e10cSrcweir 				else
1068*cdf0e10cSrcweir 					ChildList = pChild->m_pnext;
1069*cdf0e10cSrcweir 
1070*cdf0e10cSrcweir 				break;
1071*cdf0e10cSrcweir 			}
1072*cdf0e10cSrcweir 
1073*cdf0e10cSrcweir 			pPrev  = pChild;
1074*cdf0e10cSrcweir 			pChild = pChild->m_pnext;
1075*cdf0e10cSrcweir 		}
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir 		osl_releaseMutex(ChildListMutex);
1078*cdf0e10cSrcweir 
1079*cdf0e10cSrcweir 		osl_destroyCondition(((oslProcessImpl*)Process)->m_terminated);
1080*cdf0e10cSrcweir 
1081*cdf0e10cSrcweir 		free(Process);
1082*cdf0e10cSrcweir 	}
1083*cdf0e10cSrcweir }
1084*cdf0e10cSrcweir 
1085*cdf0e10cSrcweir #if defined(LINUX)
1086*cdf0e10cSrcweir struct osl_procStat
1087*cdf0e10cSrcweir {
1088*cdf0e10cSrcweir    /* from 'stat' */
1089*cdf0e10cSrcweir 	pid_t pid;                /* pid */
1090*cdf0e10cSrcweir 	char command[16];         /* 'argv[0]' */ /* mfe: it all right char comm[16] in kernel! */
1091*cdf0e10cSrcweir 	char state;               /* state (running, stopped, ...) */
1092*cdf0e10cSrcweir 	pid_t ppid;               /* parent pid */
1093*cdf0e10cSrcweir 	pid_t pgrp;               /* parent group */
1094*cdf0e10cSrcweir 	int session;              /* session ID */
1095*cdf0e10cSrcweir 	int tty;                  /* no of tty */
1096*cdf0e10cSrcweir 	pid_t tpgid;              /* group of process owning the tty */
1097*cdf0e10cSrcweir 	unsigned long flags;      /* flags dunno */
1098*cdf0e10cSrcweir 	unsigned long minflt;     /* minor page faults */
1099*cdf0e10cSrcweir 	unsigned long cminflt;    /* minor page faults with children */
1100*cdf0e10cSrcweir 	unsigned long majflt;     /* major page faults */
1101*cdf0e10cSrcweir 	unsigned long cmajflt;    /* major page faults with children */
1102*cdf0e10cSrcweir 	unsigned long utime;      /* no of jiffies in user mode */
1103*cdf0e10cSrcweir 	unsigned long stime;      /* no of jiffies in kernel mode */
1104*cdf0e10cSrcweir 	unsigned long cutime;     /* no of jiffies in user mode with children */
1105*cdf0e10cSrcweir 	unsigned long cstime;     /* no of jiffies in kernel mode with children */
1106*cdf0e10cSrcweir 	unsigned long priority;   /* nice value + 15 (kernel scheduling prio)*/
1107*cdf0e10cSrcweir 	long nice;                /* nice value */
1108*cdf0e10cSrcweir 	long timeout;             /* no of jiffies of next process timeout */
1109*cdf0e10cSrcweir 	long itrealvalue;         /* no jiffies before next SIGALRM */
1110*cdf0e10cSrcweir 	unsigned long starttime;  /* process started this no of jiffies after boot */
1111*cdf0e10cSrcweir 	unsigned long vsize;      /* virtual memory size (in bytes) */
1112*cdf0e10cSrcweir 	long rss;                 /* resident set size (in pages) */
1113*cdf0e10cSrcweir 	unsigned long rss_rlim;   /* rss limit (in bytes) */
1114*cdf0e10cSrcweir 	unsigned long startcode;   /* address above program text can run */
1115*cdf0e10cSrcweir 	unsigned long endcode;    /* address below program text can run */
1116*cdf0e10cSrcweir 	unsigned long startstack; /* address of start of stack */
1117*cdf0e10cSrcweir 	unsigned long kstkesp;    /* current value of 'esp' (stack pointer) */
1118*cdf0e10cSrcweir 	unsigned long kstkeip;    /* current value of 'eip' (instruction pointer) */
1119*cdf0e10cSrcweir 	/* mfe: Linux > 2.1.7x have more signals (88) */
1120*cdf0e10cSrcweir /*#ifdef LINUX */
1121*cdf0e10cSrcweir 	char signal[24];          /* pending signals */
1122*cdf0e10cSrcweir 	char blocked[24];         /* blocked signals */
1123*cdf0e10cSrcweir 	char sigignore[24];       /* ignored signals */
1124*cdf0e10cSrcweir 	char sigcatch[24];        /* catched signals */
1125*cdf0e10cSrcweir /*#else*/
1126*cdf0e10cSrcweir /*	long long signal;*/
1127*cdf0e10cSrcweir /*	long long blocked;*/
1128*cdf0e10cSrcweir /*	long long sigignore;*/
1129*cdf0e10cSrcweir /*	long long sigcatch;*/
1130*cdf0e10cSrcweir /*#endif */
1131*cdf0e10cSrcweir 	unsigned long wchan;      /* 'channel' the process is waiting in */
1132*cdf0e10cSrcweir 	unsigned long nswap;      /* ? */
1133*cdf0e10cSrcweir 	unsigned long cnswap;     /* ? */
1134*cdf0e10cSrcweir 
1135*cdf0e10cSrcweir 	/* from 'status' */
1136*cdf0e10cSrcweir 	int ruid;                 /* real uid */
1137*cdf0e10cSrcweir 	int euid;                 /* effective uid */
1138*cdf0e10cSrcweir 	int suid;                 /* saved uid */
1139*cdf0e10cSrcweir 	int fuid;                 /* file access uid */
1140*cdf0e10cSrcweir 	int rgid;                 /* real gid */
1141*cdf0e10cSrcweir 	int egid;                 /* effective gid */
1142*cdf0e10cSrcweir 	int sgid;                 /* saved gid */
1143*cdf0e10cSrcweir 	int fgid;                 /* file access gid */
1144*cdf0e10cSrcweir 	unsigned long vm_size;    /* like vsize but on kb */
1145*cdf0e10cSrcweir 	unsigned long vm_lock;    /* locked pages in kb */
1146*cdf0e10cSrcweir 	unsigned long vm_rss;     /* like rss but in kb */
1147*cdf0e10cSrcweir 	unsigned long vm_data;    /* data size */
1148*cdf0e10cSrcweir 	unsigned long vm_stack;   /* stack size */
1149*cdf0e10cSrcweir 	unsigned long vm_exe;     /* executable size */
1150*cdf0e10cSrcweir 	unsigned long vm_lib;     /* library size */
1151*cdf0e10cSrcweir };
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir /**********************************************
1154*cdf0e10cSrcweir  osl_getProcStat
1155*cdf0e10cSrcweir  *********************************************/
1156*cdf0e10cSrcweir 
1157*cdf0e10cSrcweir sal_Bool osl_getProcStat(pid_t pid, struct osl_procStat* procstat)
1158*cdf0e10cSrcweir {
1159*cdf0e10cSrcweir 	int fd = 0;
1160*cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
1161*cdf0e10cSrcweir 	char name[PATH_MAX + 1];
1162*cdf0e10cSrcweir 	snprintf(name, sizeof(name), "/proc/%u/stat", pid);
1163*cdf0e10cSrcweir 
1164*cdf0e10cSrcweir 	if ((fd = open(name,O_RDONLY)) >=0 )
1165*cdf0e10cSrcweir 	{
1166*cdf0e10cSrcweir 		char* tmp=0;
1167*cdf0e10cSrcweir 		char prstatbuf[512];
1168*cdf0e10cSrcweir 		memset(prstatbuf,0,512);
1169*cdf0e10cSrcweir 		bRet = read(fd,prstatbuf,511) == 511;
1170*cdf0e10cSrcweir 
1171*cdf0e10cSrcweir 		close(fd);
1172*cdf0e10cSrcweir 		/*printf("%s\n\n",prstatbuf);*/
1173*cdf0e10cSrcweir 
1174*cdf0e10cSrcweir 		if (!bRet)
1175*cdf0e10cSrcweir 		    return sal_False;
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir 		tmp = strrchr(prstatbuf, ')');
1178*cdf0e10cSrcweir 		*tmp = '\0';
1179*cdf0e10cSrcweir 		memset(procstat->command, 0, sizeof(procstat->command));
1180*cdf0e10cSrcweir 
1181*cdf0e10cSrcweir 		sscanf(prstatbuf, "%d (%15c", &procstat->pid, procstat->command);
1182*cdf0e10cSrcweir 		sscanf(tmp + 2,
1183*cdf0e10cSrcweir 			   "%c"
1184*cdf0e10cSrcweir 			   "%i %i %i %i %i"
1185*cdf0e10cSrcweir 			   "%lu %lu %lu %lu %lu"
1186*cdf0e10cSrcweir 			   "%lu %lu %lu %lu"
1187*cdf0e10cSrcweir 			   "%lu %li %li %li"
1188*cdf0e10cSrcweir 			   "%lu %lu %li %lu"
1189*cdf0e10cSrcweir 			   "%lu %lu %lu %lu %lu"
1190*cdf0e10cSrcweir 			   "%s %s %s %s"
1191*cdf0e10cSrcweir 			   "%lu %lu %lu",
1192*cdf0e10cSrcweir 			   &procstat->state,
1193*cdf0e10cSrcweir 			   &procstat->ppid,      &procstat->pgrp,    &procstat->session,    &procstat->tty,         &procstat->tpgid,
1194*cdf0e10cSrcweir 			   &procstat->flags,     &procstat->minflt,  &procstat->cminflt,    &procstat->majflt,      &procstat->cmajflt,
1195*cdf0e10cSrcweir 			   &procstat->utime,     &procstat->stime,   &procstat->cutime,     &procstat->cstime,
1196*cdf0e10cSrcweir 			   &procstat->priority,  &procstat->nice,    &procstat->timeout,    &procstat->itrealvalue,
1197*cdf0e10cSrcweir 			   &procstat->starttime, &procstat->vsize,   &procstat->rss,        &procstat->rss_rlim,
1198*cdf0e10cSrcweir 			   &procstat->startcode, &procstat->endcode, &procstat->startstack, &procstat->kstkesp,     &procstat->kstkeip,
1199*cdf0e10cSrcweir 			   procstat->signal,     procstat->blocked,  procstat->sigignore,   procstat->sigcatch,
1200*cdf0e10cSrcweir 			   &procstat->wchan,     &procstat->nswap,   &procstat->cnswap
1201*cdf0e10cSrcweir 			);
1202*cdf0e10cSrcweir 	}
1203*cdf0e10cSrcweir     return bRet;
1204*cdf0e10cSrcweir }
1205*cdf0e10cSrcweir 
1206*cdf0e10cSrcweir /**********************************************
1207*cdf0e10cSrcweir  osl_getProcStatus
1208*cdf0e10cSrcweir  *********************************************/
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir sal_Bool osl_getProcStatus(pid_t pid, struct osl_procStat* procstat)
1211*cdf0e10cSrcweir {
1212*cdf0e10cSrcweir 	int fd = 0;
1213*cdf0e10cSrcweir 	char name[PATH_MAX + 1];
1214*cdf0e10cSrcweir 	snprintf(name, sizeof(name), "/proc/%u/status", pid);
1215*cdf0e10cSrcweir 
1216*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1217*cdf0e10cSrcweir 
1218*cdf0e10cSrcweir 	if ((fd = open(name,O_RDONLY)) >=0 )
1219*cdf0e10cSrcweir 	{
1220*cdf0e10cSrcweir 		char* tmp=0;
1221*cdf0e10cSrcweir 		char prstatusbuf[512];
1222*cdf0e10cSrcweir 		memset(prstatusbuf,0,512);
1223*cdf0e10cSrcweir 		bRet = read(fd,prstatusbuf,511) == 511;
1224*cdf0e10cSrcweir 
1225*cdf0e10cSrcweir 		close(fd);
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir 		/*		printf("\n\n%s\n\n",prstatusbuf);*/
1228*cdf0e10cSrcweir 
1229*cdf0e10cSrcweir 		if (!bRet)
1230*cdf0e10cSrcweir 		    return sal_False;
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir 		tmp = strstr(prstatusbuf,"Uid:");
1233*cdf0e10cSrcweir 		if(tmp)
1234*cdf0e10cSrcweir 		{
1235*cdf0e10cSrcweir 			sscanf(tmp,"Uid:\t%d\t%d\t%d\t%d",
1236*cdf0e10cSrcweir 				   &procstat->ruid, &procstat->euid, &procstat->suid, &procstat->fuid
1237*cdf0e10cSrcweir 				);
1238*cdf0e10cSrcweir 		}
1239*cdf0e10cSrcweir 
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir 		tmp = strstr(prstatusbuf,"Gid:");
1242*cdf0e10cSrcweir 		if(tmp)
1243*cdf0e10cSrcweir 		{
1244*cdf0e10cSrcweir 			sscanf(tmp,"Gid:\t%d\t%d\t%d\t%d",
1245*cdf0e10cSrcweir 				   &procstat->rgid, &procstat->egid, &procstat->sgid, &procstat->fgid
1246*cdf0e10cSrcweir 				);
1247*cdf0e10cSrcweir 		}
1248*cdf0e10cSrcweir 
1249*cdf0e10cSrcweir 		tmp = strstr(prstatusbuf,"VmSize:");
1250*cdf0e10cSrcweir 		if(tmp)
1251*cdf0e10cSrcweir 		{
1252*cdf0e10cSrcweir 			sscanf(tmp,
1253*cdf0e10cSrcweir 				   "VmSize: %lu kB\n"
1254*cdf0e10cSrcweir 				   "VmLck: %lu kB\n"
1255*cdf0e10cSrcweir 				   "VmRSS: %lu kB\n"
1256*cdf0e10cSrcweir 				   "VmData: %lu kB\n"
1257*cdf0e10cSrcweir 				   "VmStk: %lu kB\n"
1258*cdf0e10cSrcweir 				   "VmExe: %lu kB\n"
1259*cdf0e10cSrcweir 				   "VmLib: %lu kB\n",
1260*cdf0e10cSrcweir 				   &procstat->vm_size, &procstat->vm_lock, &procstat->vm_rss, &procstat->vm_data,
1261*cdf0e10cSrcweir 				   &procstat->vm_stack, &procstat->vm_exe, &procstat->vm_lib
1262*cdf0e10cSrcweir 				);
1263*cdf0e10cSrcweir 		}
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir 		tmp = strstr(prstatusbuf,"SigPnd:");
1266*cdf0e10cSrcweir 		if(tmp)
1267*cdf0e10cSrcweir 		{
1268*cdf0e10cSrcweir 			sscanf(tmp, "SigPnd: %s SigBlk: %s SigIgn: %s %*s %s",
1269*cdf0e10cSrcweir 				   procstat->signal, procstat->blocked, procstat->sigignore, procstat->sigcatch
1270*cdf0e10cSrcweir 				);
1271*cdf0e10cSrcweir 		}
1272*cdf0e10cSrcweir 	}
1273*cdf0e10cSrcweir 	return bRet;
1274*cdf0e10cSrcweir }
1275*cdf0e10cSrcweir 
1276*cdf0e10cSrcweir #endif
1277*cdf0e10cSrcweir 
1278*cdf0e10cSrcweir /**********************************************
1279*cdf0e10cSrcweir  osl_getProcessInfo
1280*cdf0e10cSrcweir  *********************************************/
1281*cdf0e10cSrcweir 
1282*cdf0e10cSrcweir oslProcessError SAL_CALL osl_getProcessInfo(oslProcess Process, oslProcessData Fields, oslProcessInfo* pInfo)
1283*cdf0e10cSrcweir {
1284*cdf0e10cSrcweir 	pid_t   pid;
1285*cdf0e10cSrcweir 
1286*cdf0e10cSrcweir     if (Process == NULL)
1287*cdf0e10cSrcweir 		pid = getpid();
1288*cdf0e10cSrcweir 	else
1289*cdf0e10cSrcweir 		pid = ((oslProcessImpl*)Process)->m_pid;
1290*cdf0e10cSrcweir 
1291*cdf0e10cSrcweir 	if (! pInfo || (pInfo->Size != sizeof(oslProcessInfo)))
1292*cdf0e10cSrcweir 		return osl_Process_E_Unknown;
1293*cdf0e10cSrcweir 
1294*cdf0e10cSrcweir 	pInfo->Fields = 0;
1295*cdf0e10cSrcweir 
1296*cdf0e10cSrcweir 	if (Fields & osl_Process_IDENTIFIER)
1297*cdf0e10cSrcweir 	{
1298*cdf0e10cSrcweir 		pInfo->Ident  = pid;
1299*cdf0e10cSrcweir 		pInfo->Fields |= osl_Process_IDENTIFIER;
1300*cdf0e10cSrcweir 	}
1301*cdf0e10cSrcweir 
1302*cdf0e10cSrcweir 	if (Fields & osl_Process_EXITCODE)
1303*cdf0e10cSrcweir 	{
1304*cdf0e10cSrcweir 		if ((Process != NULL) &&
1305*cdf0e10cSrcweir 			osl_checkCondition(((oslProcessImpl*)Process)->m_terminated))
1306*cdf0e10cSrcweir 		{
1307*cdf0e10cSrcweir 			pInfo->Code = ((oslProcessImpl*)Process)->m_status;
1308*cdf0e10cSrcweir 			pInfo->Fields |= osl_Process_EXITCODE;
1309*cdf0e10cSrcweir 		}
1310*cdf0e10cSrcweir 	}
1311*cdf0e10cSrcweir 
1312*cdf0e10cSrcweir 	if (Fields & (osl_Process_HEAPUSAGE | osl_Process_CPUTIMES))
1313*cdf0e10cSrcweir 	{
1314*cdf0e10cSrcweir 
1315*cdf0e10cSrcweir #if defined(SOLARIS)
1316*cdf0e10cSrcweir 
1317*cdf0e10cSrcweir 		int  fd;
1318*cdf0e10cSrcweir 		sal_Char name[PATH_MAX + 1];
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir 		snprintf(name, sizeof(name), "/proc/%u", pid);
1321*cdf0e10cSrcweir 
1322*cdf0e10cSrcweir 		if ((fd = open(name, O_RDONLY)) >= 0)
1323*cdf0e10cSrcweir 		{
1324*cdf0e10cSrcweir 			prstatus_t prstatus;
1325*cdf0e10cSrcweir 
1326*cdf0e10cSrcweir 			if (ioctl(fd, PIOCSTATUS, &prstatus) >= 0)
1327*cdf0e10cSrcweir 			{
1328*cdf0e10cSrcweir 				if (Fields & osl_Process_CPUTIMES)
1329*cdf0e10cSrcweir 				{
1330*cdf0e10cSrcweir 					pInfo->UserTime.Seconds   = prstatus.pr_utime.tv_sec;
1331*cdf0e10cSrcweir 					pInfo->UserTime.Nanosec   = prstatus.pr_utime.tv_nsec;
1332*cdf0e10cSrcweir 					pInfo->SystemTime.Seconds = prstatus.pr_stime.tv_sec;
1333*cdf0e10cSrcweir 					pInfo->SystemTime.Nanosec = prstatus.pr_stime.tv_nsec;
1334*cdf0e10cSrcweir 
1335*cdf0e10cSrcweir 					pInfo->Fields |= osl_Process_CPUTIMES;
1336*cdf0e10cSrcweir 				}
1337*cdf0e10cSrcweir 
1338*cdf0e10cSrcweir 				if (Fields & osl_Process_HEAPUSAGE)
1339*cdf0e10cSrcweir 				{
1340*cdf0e10cSrcweir 					pInfo->HeapUsage = prstatus.pr_brksize;
1341*cdf0e10cSrcweir 
1342*cdf0e10cSrcweir 					pInfo->Fields |= osl_Process_HEAPUSAGE;
1343*cdf0e10cSrcweir 				}
1344*cdf0e10cSrcweir 
1345*cdf0e10cSrcweir 				close(fd);
1346*cdf0e10cSrcweir 
1347*cdf0e10cSrcweir 				return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;
1348*cdf0e10cSrcweir 			}
1349*cdf0e10cSrcweir 			else
1350*cdf0e10cSrcweir 				close(fd);
1351*cdf0e10cSrcweir 		}
1352*cdf0e10cSrcweir 
1353*cdf0e10cSrcweir #elif defined(HPUX)
1354*cdf0e10cSrcweir 
1355*cdf0e10cSrcweir 		struct pst_status prstatus;
1356*cdf0e10cSrcweir 
1357*cdf0e10cSrcweir 		if (pstat_getproc(&prstatus, sizeof(prstatus), (size_t)0, pid) == 1)
1358*cdf0e10cSrcweir 		{
1359*cdf0e10cSrcweir 			if (Fields & osl_Process_CPUTIMES)
1360*cdf0e10cSrcweir 			{
1361*cdf0e10cSrcweir 				pInfo->UserTime.Seconds   = prstatus.pst_utime;
1362*cdf0e10cSrcweir 				pInfo->UserTime.Nanosec   = 500000L;
1363*cdf0e10cSrcweir 				pInfo->SystemTime.Seconds = prstatus.pst_stime;
1364*cdf0e10cSrcweir 				pInfo->SystemTime.Nanosec = 500000L;
1365*cdf0e10cSrcweir 
1366*cdf0e10cSrcweir 				pInfo->Fields |= osl_Process_CPUTIMES;
1367*cdf0e10cSrcweir 			}
1368*cdf0e10cSrcweir 
1369*cdf0e10cSrcweir 			if (Fields & osl_Process_HEAPUSAGE)
1370*cdf0e10cSrcweir 			{
1371*cdf0e10cSrcweir 				pInfo->HeapUsage = prstatus.pst_vdsize*PAGESIZE;
1372*cdf0e10cSrcweir 
1373*cdf0e10cSrcweir 				pInfo->Fields |= osl_Process_HEAPUSAGE;
1374*cdf0e10cSrcweir 			}
1375*cdf0e10cSrcweir 
1376*cdf0e10cSrcweir 			return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;
1377*cdf0e10cSrcweir 		}
1378*cdf0e10cSrcweir 
1379*cdf0e10cSrcweir #elif defined(LINUX)
1380*cdf0e10cSrcweir 
1381*cdf0e10cSrcweir 		if ( (Fields & osl_Process_CPUTIMES) || (Fields & osl_Process_HEAPUSAGE) )
1382*cdf0e10cSrcweir 		{
1383*cdf0e10cSrcweir     		struct osl_procStat procstat;
1384*cdf0e10cSrcweir     		memset(&procstat,0,sizeof(procstat));
1385*cdf0e10cSrcweir 
1386*cdf0e10cSrcweir     		if ( (Fields & osl_Process_CPUTIMES) && osl_getProcStat(pid, &procstat) )
1387*cdf0e10cSrcweir     		{
1388*cdf0e10cSrcweir     			/*
1389*cdf0e10cSrcweir     			 *  mfe:
1390*cdf0e10cSrcweir     			 *  We calculate only time of the process proper.
1391*cdf0e10cSrcweir     			 *  Threads are processes, we do not consider their time here!
1392*cdf0e10cSrcweir     			 *  (For this, cutime and cstime should be used, it seems not
1393*cdf0e10cSrcweir     			 *   to work in 2.0.36)
1394*cdf0e10cSrcweir     			 */
1395*cdf0e10cSrcweir 
1396*cdf0e10cSrcweir                 long clktck;
1397*cdf0e10cSrcweir                 unsigned long hz;
1398*cdf0e10cSrcweir                 unsigned long userseconds;
1399*cdf0e10cSrcweir                 unsigned long systemseconds;
1400*cdf0e10cSrcweir 
1401*cdf0e10cSrcweir                 clktck = sysconf(_SC_CLK_TCK);
1402*cdf0e10cSrcweir                 if (clktck < 0) {
1403*cdf0e10cSrcweir                     return osl_Process_E_Unknown;
1404*cdf0e10cSrcweir                 }
1405*cdf0e10cSrcweir                 hz = (unsigned long) clktck;
1406*cdf0e10cSrcweir 
1407*cdf0e10cSrcweir                 userseconds = procstat.utime/hz;
1408*cdf0e10cSrcweir                 systemseconds = procstat.stime/hz;
1409*cdf0e10cSrcweir 
1410*cdf0e10cSrcweir      			pInfo->UserTime.Seconds   = userseconds;
1411*cdf0e10cSrcweir     			pInfo->UserTime.Nanosec   = procstat.utime - (userseconds * hz);
1412*cdf0e10cSrcweir     			pInfo->SystemTime.Seconds = systemseconds;
1413*cdf0e10cSrcweir     			pInfo->SystemTime.Nanosec = procstat.stime - (systemseconds * hz);
1414*cdf0e10cSrcweir 
1415*cdf0e10cSrcweir     			pInfo->Fields |= osl_Process_CPUTIMES;
1416*cdf0e10cSrcweir     		}
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir     		if ( (Fields & osl_Process_HEAPUSAGE) && osl_getProcStatus(pid, &procstat) )
1419*cdf0e10cSrcweir     		{
1420*cdf0e10cSrcweir     			/*
1421*cdf0e10cSrcweir     			 *  mfe:
1422*cdf0e10cSrcweir     			 *  vm_data (found in status) shows the size of the data segment
1423*cdf0e10cSrcweir     			 *  it a rough approximation of the core heap size
1424*cdf0e10cSrcweir     			 */
1425*cdf0e10cSrcweir     			pInfo->HeapUsage = procstat.vm_data*1024;
1426*cdf0e10cSrcweir 
1427*cdf0e10cSrcweir     			pInfo->Fields |= osl_Process_HEAPUSAGE;
1428*cdf0e10cSrcweir     		}
1429*cdf0e10cSrcweir     	}
1430*cdf0e10cSrcweir 
1431*cdf0e10cSrcweir 		return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;
1432*cdf0e10cSrcweir #endif
1433*cdf0e10cSrcweir 
1434*cdf0e10cSrcweir 	}
1435*cdf0e10cSrcweir 
1436*cdf0e10cSrcweir 	return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;
1437*cdf0e10cSrcweir }
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir 
1440*cdf0e10cSrcweir /***********************************************
1441*cdf0e10cSrcweir  helper function for osl_joinProcessWithTimeout
1442*cdf0e10cSrcweir  **********************************************/
1443*cdf0e10cSrcweir 
1444*cdf0e10cSrcweir static int is_timeout(const struct timeval* tend)
1445*cdf0e10cSrcweir {
1446*cdf0e10cSrcweir 	struct timeval tcurrent;
1447*cdf0e10cSrcweir 	gettimeofday(&tcurrent, NULL);
1448*cdf0e10cSrcweir 	return (tcurrent.tv_sec >= tend->tv_sec);
1449*cdf0e10cSrcweir }
1450*cdf0e10cSrcweir 
1451*cdf0e10cSrcweir /**********************************************
1452*cdf0e10cSrcweir  kill(pid, 0) is usefull for checking if a
1453*cdf0e10cSrcweir  process is still alive, but remember that
1454*cdf0e10cSrcweir  kill even returns 0 if the process is already
1455*cdf0e10cSrcweir  a zombie.
1456*cdf0e10cSrcweir  *********************************************/
1457*cdf0e10cSrcweir 
1458*cdf0e10cSrcweir static int is_process_dead(pid_t pid)
1459*cdf0e10cSrcweir {
1460*cdf0e10cSrcweir 	return ((-1 == kill(pid, 0)) && (ESRCH == errno));
1461*cdf0e10cSrcweir }
1462*cdf0e10cSrcweir 
1463*cdf0e10cSrcweir /**********************************************
1464*cdf0e10cSrcweir  osl_joinProcessWithTimeout
1465*cdf0e10cSrcweir  *********************************************/
1466*cdf0e10cSrcweir 
1467*cdf0e10cSrcweir oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const TimeValue* pTimeout)
1468*cdf0e10cSrcweir {
1469*cdf0e10cSrcweir 	oslProcessImpl* pChild    = ChildList;
1470*cdf0e10cSrcweir 	oslProcessError osl_error = osl_Process_E_None;
1471*cdf0e10cSrcweir 
1472*cdf0e10cSrcweir     OSL_PRECOND(Process, "osl_joinProcess: Invalid parameter");
1473*cdf0e10cSrcweir     OSL_ASSERT(ChildListMutex);
1474*cdf0e10cSrcweir 
1475*cdf0e10cSrcweir     if (NULL == Process || 0 == ChildListMutex)
1476*cdf0e10cSrcweir         return osl_Process_E_Unknown;
1477*cdf0e10cSrcweir 
1478*cdf0e10cSrcweir 	osl_acquireMutex(ChildListMutex);
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir 	/* check if process is a child of ours */
1481*cdf0e10cSrcweir 	while (pChild != NULL)
1482*cdf0e10cSrcweir 	{
1483*cdf0e10cSrcweir 		if (pChild == (oslProcessImpl*)Process)
1484*cdf0e10cSrcweir 			break;
1485*cdf0e10cSrcweir 
1486*cdf0e10cSrcweir 		pChild = pChild->m_pnext;
1487*cdf0e10cSrcweir 	}
1488*cdf0e10cSrcweir 
1489*cdf0e10cSrcweir 	osl_releaseMutex(ChildListMutex);
1490*cdf0e10cSrcweir 
1491*cdf0e10cSrcweir 	if (pChild != NULL)
1492*cdf0e10cSrcweir 	{
1493*cdf0e10cSrcweir 		oslConditionResult cond_res = osl_waitCondition(pChild->m_terminated, pTimeout);
1494*cdf0e10cSrcweir 
1495*cdf0e10cSrcweir 		if (osl_cond_result_timeout == cond_res)
1496*cdf0e10cSrcweir 		    osl_error = osl_Process_E_TimedOut;
1497*cdf0e10cSrcweir 		else if (osl_cond_result_ok != cond_res)
1498*cdf0e10cSrcweir 		    osl_error = osl_Process_E_Unknown;
1499*cdf0e10cSrcweir 	}
1500*cdf0e10cSrcweir 	else /* alien process; StatusThread will not be able
1501*cdf0e10cSrcweir 	   		to set the condition terminated */
1502*cdf0e10cSrcweir 	{
1503*cdf0e10cSrcweir 		pid_t pid = ((oslProcessImpl*)Process)->m_pid;
1504*cdf0e10cSrcweir 
1505*cdf0e10cSrcweir 		if (pTimeout)
1506*cdf0e10cSrcweir 		{
1507*cdf0e10cSrcweir 			int timeout = 0;
1508*cdf0e10cSrcweir 			struct timeval tend;
1509*cdf0e10cSrcweir 
1510*cdf0e10cSrcweir 			gettimeofday(&tend, NULL);
1511*cdf0e10cSrcweir 
1512*cdf0e10cSrcweir 			tend.tv_sec += pTimeout->Seconds;
1513*cdf0e10cSrcweir 
1514*cdf0e10cSrcweir 			while (!is_process_dead(pid) && ((timeout = is_timeout(&tend)) == 0))
1515*cdf0e10cSrcweir 				sleep(1);
1516*cdf0e10cSrcweir 
1517*cdf0e10cSrcweir 			if (timeout)
1518*cdf0e10cSrcweir 				osl_error = osl_Process_E_TimedOut;
1519*cdf0e10cSrcweir 		}
1520*cdf0e10cSrcweir 		else /* infinite */
1521*cdf0e10cSrcweir 		{
1522*cdf0e10cSrcweir 			while (!is_process_dead(pid))
1523*cdf0e10cSrcweir 				sleep(1);
1524*cdf0e10cSrcweir 		}
1525*cdf0e10cSrcweir 	}
1526*cdf0e10cSrcweir 	return osl_error;
1527*cdf0e10cSrcweir }
1528*cdf0e10cSrcweir 
1529*cdf0e10cSrcweir /**********************************************
1530*cdf0e10cSrcweir  osl_joinProcess
1531*cdf0e10cSrcweir  *********************************************/
1532*cdf0e10cSrcweir 
1533*cdf0e10cSrcweir oslProcessError SAL_CALL osl_joinProcess(oslProcess Process)
1534*cdf0e10cSrcweir {
1535*cdf0e10cSrcweir     return osl_joinProcessWithTimeout(Process, NULL);
1536*cdf0e10cSrcweir }
1537