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