Пример #1
0
oslProcess SAL_CALL osl_getProcess(oslProcessIdentifier Ident)
{
	oslProcessImpl *pProcImpl;

	if (kill(Ident, 0) != -1)
	{
		oslProcessImpl* pChild;

		if (ChildListMutex == NULL)
			ChildListMutex = osl_createMutex();

		osl_acquireMutex(ChildListMutex);

		pChild = ChildList;

		/* check if it is one of our child processes */
		while (pChild != NULL)
		{
			if (Ident == (sal_uInt32) pChild->m_pid)
				break;

			pChild = pChild->m_pnext;
		}

		pProcImpl = (oslProcessImpl*) malloc(sizeof(oslProcessImpl));
		pProcImpl->m_pid        = Ident;
		pProcImpl->m_terminated = osl_createCondition();

		if (pChild != NULL)
		{
			/* process is a child so insert into list */
			pProcImpl->m_pnext = pChild->m_pnext;
			pChild->m_pnext = pProcImpl;

			pProcImpl->m_status = pChild->m_status;

			if (osl_checkCondition(pChild->m_terminated))
				osl_setCondition(pProcImpl->m_terminated);
		}
		else
			pProcImpl->m_pnext = NULL;

		osl_releaseMutex(ChildListMutex);
	}
	else
		pProcImpl = NULL;

	return (pProcImpl);
}
Пример #2
0
rtl_TextEncoding SAL_CALL osl_getTextEncodingFromLocale( rtl_Locale * pLocale )
{
    struct EnumLocalesParams params = { L"", L"", 0 };

    /* initialise global TLS id */
    if( (DWORD) -1 == g_dwTLSLocaleEncId )
    {
        oslMutex globalMutex = * osl_getGlobalMutex();

        /* initializing must be thread save */
        osl_acquireMutex( globalMutex );

        if( (DWORD) -1 == g_dwTLSLocaleEncId )
            g_dwTLSLocaleEncId = TlsAlloc();

        osl_releaseMutex( globalMutex );
    }

    /* if pLocale is NULL, use process locale as default */
    if( NULL == pLocale )
        osl_getProcessLocale( &pLocale );

    /* copy in parameters to structure */
    if( pLocale && pLocale->Language && pLocale->Language->length < ELP_LANGUAGE_FIELD_LENGTH )
    {
        wcscpy( params.Language, pLocale->Language->buffer );

        if( pLocale->Country && pLocale->Country->length < ELP_COUNTRY_FIELD_LENGTH )
            wcscpy( params.Country, pLocale->Country->buffer );

        /* save pointer to local structure in TLS */
        TlsSetValue( g_dwTLSLocaleEncId, &params );

        /* enum all locales known to Windows */
        EnumSystemLocalesA( EnumLocalesProcA, LCID_SUPPORTED );

        /* use the LCID found in iteration */
        return GetTextEncodingFromLCID( params.Locale );
    }

    return RTL_TEXTENCODING_DONTKNOW;
}
Пример #3
0
void SAL_CALL osl_freeProcessHandle(oslProcess Process)
{
    if (Process != NULL)
	{
		oslProcessImpl *pChild, *pPrev = NULL;

		OSL_ASSERT(ChildListMutex != NULL);

		if ( ChildListMutex == 0 )
		{
			return;
		}

		osl_acquireMutex(ChildListMutex);

		pChild = ChildList;

		/* remove process from child list */
		while (pChild != NULL)
		{
			if (pChild == (oslProcessImpl*)Process)
			{
				if (pPrev != NULL)
					pPrev->m_pnext = pChild->m_pnext;
				else
					ChildList = pChild->m_pnext;

				break;
			}

			pPrev  = pChild;
			pChild = pChild->m_pnext;
		}

		osl_releaseMutex(ChildListMutex);

		osl_destroyCondition(((oslProcessImpl*)Process)->m_terminated);

		free(Process);
	}
}
Пример #4
0
static void ChildStatusProc(void *pData)
{
	pid_t pid = -1;
	int   status = 0;
	int   channel[2];
	ProcessData  data;
	ProcessData *pdata;
	int		stdOutput[2] = { -1, -1 }, stdInput[2] = { -1, -1 }, stdError[2] = { -1, -1 };

	pdata = (ProcessData *)pData;

	/* make a copy of our data, because forking will only copy
	   our local stack of the thread, so the process data will not be accessible
	   in our child process */
	memcpy(&data, pData, sizeof(data));

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, channel) == -1)
        status = errno;

    fcntl(channel[0], F_SETFD, FD_CLOEXEC);
    fcntl(channel[1], F_SETFD, FD_CLOEXEC);

	/* Create redirected IO pipes */
	if ( status == 0 && data.m_pInputWrite )
		if (pipe( stdInput ) == -1)
		    status = errno;

	if ( status == 0 && data.m_pOutputRead )
		if (pipe( stdOutput ) == -1)
		    status = errno;

	if ( status == 0 && data.m_pErrorRead )
		if (pipe( stdError ) == -1)
		    status = errno;

    if ( (status == 0) && ((pid = fork()) == 0) )
    {
		/* Child */
        int chstatus = 0;
        sal_Int32 nWrote;

	    if (channel[0] != -1) close(channel[0]);

		if ((data.m_uid != (uid_t)-1) && ((data.m_uid != getuid()) || (data.m_gid != getgid())))
		{
			OSL_ASSERT(geteuid() == 0);		/* must be root */

			if (! INIT_GROUPS(data.m_name, data.m_gid) || (setuid(data.m_uid) != 0))
				OSL_TRACE("Failed to change uid and guid, errno=%d (%s)\n", errno, strerror(errno));
#if defined(LINUX) || defined (FREEBSD)
			unsetenv("HOME");
#else
			putenv("HOME=");
#endif
		}

  		if (data.m_pszDir)
  			chstatus = chdir(data.m_pszDir);

   	    if (chstatus == 0 && ((data.m_uid == (uid_t)-1) || ((data.m_uid == getuid()) && (data.m_gid == getgid()))))
		{
            int i;
			for (i = 0; data.m_pszEnv[i] != NULL; i++)
            {
                if (strchr(data.m_pszEnv[i], '=') == NULL)
                {
                    unsetenv(data.m_pszEnv[i]); /*TODO: check error return*/
                }
                else
                {
                    putenv(data.m_pszEnv[i]); /*TODO: check error return*/
                }
            }

            OSL_TRACE("ChildStatusProc : starting '%s'",data.m_pszArgs[0]);
     
			/* Connect std IO to pipe ends */

			/* Write end of stdInput not used in child process */
			if (stdInput[1] != -1) close( stdInput[1] );

			/* Read end of stdOutput not used in child process */
			if (stdOutput[0] != -1) close( stdOutput[0] );

			/* Read end of stdError not used in child process */
			if (stdError[0] != -1) close( stdError[0] );

			/* Redirect pipe ends to std IO */

			if ( stdInput[0] != STDIN_FILENO )
			{
				dup2( stdInput[0], STDIN_FILENO );
				if (stdInput[0] != -1) close( stdInput[0] );
			}

			if ( stdOutput[1] != STDOUT_FILENO )
			{
				dup2( stdOutput[1], STDOUT_FILENO );
				if (stdOutput[1] != -1) close( stdOutput[1] );
			}

			if ( stdError[1] != STDERR_FILENO )
			{
				dup2( stdError[1], STDERR_FILENO );
				if (stdError[1] != -1) close( stdError[1] );
			}

	    	pid=execv(data.m_pszArgs[0], (sal_Char **)data.m_pszArgs);

		}

        OSL_TRACE("Failed to exec, errno=%d (%s)\n", errno, strerror(errno));

        OSL_TRACE("ChildStatusProc : starting '%s' failed",data.m_pszArgs[0]);
        
		/* if we reach here, something went wrong */
        nWrote = write(channel[1], &errno, sizeof(errno));
		if (nWrote != sizeof(errno))
            OSL_TRACE("sendFdPipe : sending failed (%s)",strerror(errno));

	    if (channel[1] != -1) close(channel[1]);

		_exit(255);
    }
    else
    {   /* Parent  */
        int i = -1;
		if (channel[1] != -1) close(channel[1]);

		/* Close unused pipe ends */
		if (stdInput[0] != -1) close( stdInput[0] );
		if (stdOutput[1] != -1) close( stdOutput[1] );
		if (stdError[1] != -1) close( stdError[1] );

		if (pid > 0)
		{
			while (((i = read(channel[0], &status, sizeof(status))) < 0))
			{
				if (errno != EINTR)
					break;
			}
		}

		if (channel[0] != -1) close(channel[0]);

		if ((pid > 0) && (i == 0))
		{
			pid_t	child_pid;
			osl_acquireMutex(ChildListMutex);

			pdata->m_pProcImpl->m_pid = pid;
			pdata->m_pProcImpl->m_pnext = ChildList;
			ChildList = pdata->m_pProcImpl;

			/* Store used pipe ends in data structure */

			if ( pdata->m_pInputWrite )
				*(pdata->m_pInputWrite) = osl_createFileHandleFromFD( stdInput[1] );
				
			if ( pdata->m_pOutputRead )
				*(pdata->m_pOutputRead) = osl_createFileHandleFromFD( stdOutput[0] );
				
			if ( pdata->m_pErrorRead )
				*(pdata->m_pErrorRead) = osl_createFileHandleFromFD( stdError[0] );

			osl_releaseMutex(ChildListMutex);

			osl_setCondition(pdata->m_started);
            
			do
			{
				child_pid = waitpid(pid, &status, 0);
			} while ( 0 > child_pid && EINTR == errno );

			if ( child_pid < 0)
			{
				OSL_TRACE("Failed to wait for child process, errno=%d (%s)\n", errno, strerror(errno));

				/* 
				We got an other error than EINTR. Anyway we have to wake up the
				waiting thread under any circumstances */

				child_pid = pid;
			}

			
			if ( child_pid > 0 )
			{
				oslProcessImpl* pChild;

				osl_acquireMutex(ChildListMutex);

				pChild = ChildList;

				/* check if it is one of our child processes */
				while (pChild != NULL)
				{
					if (pChild->m_pid == child_pid)
					{
						if (WIFEXITED(status))
							pChild->m_status = WEXITSTATUS(status);
						else
							pChild->m_status = -1;

						osl_setCondition(pChild->m_terminated);
					}

					pChild = pChild->m_pnext;
				}

				osl_releaseMutex(ChildListMutex);
			}
		}
		else
		{
            OSL_TRACE("ChildStatusProc : starting '%s' failed",data.m_pszArgs[0]);            
			OSL_TRACE("Failed to launch child process, child reports errno=%d (%s)\n", status, strerror(status));

			/* Close pipe ends */
			if ( pdata->m_pInputWrite )
				*pdata->m_pInputWrite = NULL;

			if ( pdata->m_pOutputRead )
				*pdata->m_pOutputRead = NULL;

			if ( pdata->m_pErrorRead )
				*pdata->m_pErrorRead = NULL;

			if (stdInput[1] != -1) close( stdInput[1] );
			if (stdOutput[0] != -1) close( stdOutput[0] );
			if (stdError[0] != -1) close( stdError[0] );

            //if pid > 0 then a process was created, even if it later failed
            //e.g. bash searching for a command to execute, and we still
            //need to clean it up to avoid "defunct" processes
            if (pid > 0)
            {
                pid_t child_pid;
                do
                {
                    child_pid = waitpid(pid, &status, 0);
                } while ( 0 > child_pid && EINTR == errno );
            }

			/* notify (and unblock) parent thread */
			osl_setCondition(pdata->m_started);
		}
	}
}
Пример #5
0
oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const TimeValue* pTimeout)
{
	oslProcessImpl* pChild    = ChildList;
	oslProcessError osl_error = osl_Process_E_None;
		
    OSL_PRECOND(Process, "osl_joinProcess: Invalid parameter");
    OSL_ASSERT(ChildListMutex);
    
    if (NULL == Process || 0 == ChildListMutex)
        return osl_Process_E_Unknown;
            	 	
	osl_acquireMutex(ChildListMutex);
	
	/* check if process is a child of ours */
	while (pChild != NULL)
	{
		if (pChild == (oslProcessImpl*)Process)
			break;

		pChild = pChild->m_pnext;
	}

	osl_releaseMutex(ChildListMutex);
        
	if (pChild != NULL)
	{
		oslConditionResult cond_res = osl_waitCondition(pChild->m_terminated, pTimeout);
		
		if (osl_cond_result_timeout == cond_res)
		    osl_error = osl_Process_E_TimedOut;
		else if (osl_cond_result_ok != cond_res)
		    osl_error = osl_Process_E_Unknown;		    
	}
	else /* alien process; StatusThread will not be able
	   		to set the condition terminated */
	{
		pid_t pid = ((oslProcessImpl*)Process)->m_pid;
		
		if (pTimeout)
		{
			int timeout = 0;
			struct timeval tend;		
				
			gettimeofday(&tend, NULL);									
			
			tend.tv_sec += pTimeout->Seconds;			
												
			while (!is_process_dead(pid) && ((timeout = is_timeout(&tend)) == 0))
				sleep(1);
				
			if (timeout)
				osl_error = osl_Process_E_TimedOut;
		}
		else /* infinite */
		{
			while (!is_process_dead(pid))
				sleep(1);
		}				
	}
	return osl_error;	
}