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