Exemple #1
0
/*
 * Function: mkAnonPipe
 *
 * Purpose:  create an anonymous pipe with read and write ends being
 *           optionally (non-)inheritable.
 */
static BOOL
mkAnonPipe (HANDLE* pHandleIn, BOOL isInheritableIn, 
	    HANDLE* pHandleOut, BOOL isInheritableOut)
{
	HANDLE hTemporaryIn  = NULL;
	HANDLE hTemporaryOut = NULL;

	/* Create the anon pipe with both ends inheritable */
	if (!CreatePipe(&hTemporaryIn, &hTemporaryOut, NULL, 0))
	{
		maperrno();
		*pHandleIn  = NULL;
		*pHandleOut = NULL;
		return FALSE;
	}

	if (isInheritableIn) {
            // SetHandleInformation requires at least Win2k
            if (!SetHandleInformation(hTemporaryIn,
                                      HANDLE_FLAG_INHERIT, 
                                      HANDLE_FLAG_INHERIT))
            {
                maperrno();
                *pHandleIn  = NULL;
                *pHandleOut = NULL;
                CloseHandle(hTemporaryIn);
                CloseHandle(hTemporaryOut);
                return FALSE;
            }
	}
        *pHandleIn = hTemporaryIn;

	if (isInheritableOut) {
            if (!SetHandleInformation(hTemporaryOut,
                                      HANDLE_FLAG_INHERIT, 
                                      HANDLE_FLAG_INHERIT))
            {
                maperrno();
                *pHandleIn  = NULL;
                *pHandleOut = NULL;
                CloseHandle(hTemporaryIn);
                CloseHandle(hTemporaryOut);
                return FALSE;
            }
        }
        *pHandleOut = hTemporaryOut;
        
	return TRUE;
}
Exemple #2
0
int
waitForProcess (ProcHandle handle)
{
    DWORD retCode;

    if (WaitForSingleObject((HANDLE) handle, INFINITE) == WAIT_OBJECT_0)
    {
	if (GetExitCodeProcess((HANDLE) handle, &retCode) == 0)
	{
	    maperrno();
	    return -1;
	}
	return retCode;
    }
    
    maperrno();
    return -1;
}
Exemple #3
0
int
terminateProcess (ProcHandle handle)
{
    if (!TerminateProcess((HANDLE) handle, 1)) {
	maperrno();
	return -1;
    }
    return 0;
}
Exemple #4
0
int
getProcessExitCode (ProcHandle handle, int *pExitCode)
{
    *pExitCode = 0;

    if (WaitForSingleObject((HANDLE) handle, 1) == WAIT_OBJECT_0)
    {
	if (GetExitCodeProcess((HANDLE) handle, (DWORD *) pExitCode) == 0)
	{
	    maperrno();
	    return -1;
	}
	return 1;
    }
    
    return 0;
}
Exemple #5
0
ProcHandle
runProcess (char *cmd, char *workingDirectory, void *environment,
	    int fdStdInput, int fdStdOutput, int fdStdError)
{
	STARTUPINFO sInfo;
	PROCESS_INFORMATION pInfo;
	DWORD flags;

	ZeroMemory(&sInfo, sizeof(sInfo));
	sInfo.cb = sizeof(sInfo);	
	sInfo.hStdInput = (HANDLE) _get_osfhandle(fdStdInput);
	sInfo.hStdOutput= (HANDLE) _get_osfhandle(fdStdOutput);
	sInfo.hStdError = (HANDLE) _get_osfhandle(fdStdError);

	if (sInfo.hStdInput == INVALID_HANDLE_VALUE)
		sInfo.hStdInput = NULL;
	if (sInfo.hStdOutput == INVALID_HANDLE_VALUE)
		sInfo.hStdOutput = NULL;
	if (sInfo.hStdError == INVALID_HANDLE_VALUE)
		sInfo.hStdError = NULL;

	if (sInfo.hStdInput || sInfo.hStdOutput || sInfo.hStdError)
		sInfo.dwFlags = STARTF_USESTDHANDLES;

	if (sInfo.hStdInput  != GetStdHandle(STD_INPUT_HANDLE)  &&
	    sInfo.hStdOutput != GetStdHandle(STD_OUTPUT_HANDLE) &&
	    sInfo.hStdError  != GetStdHandle(STD_ERROR_HANDLE))
		flags = CREATE_NO_WINDOW;   // Run without console window only when both output and error are redirected
	else
		flags = 0;

	if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, environment, workingDirectory, &sInfo, &pInfo))
	{
		maperrno();
		return -1;
	}

	CloseHandle(pInfo.hThread);
	return (ProcHandle)pInfo.hProcess;
}
Exemple #6
0
ProcHandle
runInteractiveProcess (wchar_t *cmd, wchar_t *workingDirectory, 
                       void *environment,
                       int fdStdIn, int fdStdOut, int fdStdErr,
		       int *pfdStdInput, int *pfdStdOutput, int *pfdStdError,
                       int close_fds)
{
	STARTUPINFO sInfo;
	PROCESS_INFORMATION pInfo;
	HANDLE hStdInputRead   = INVALID_HANDLE_VALUE;
        HANDLE hStdInputWrite  = INVALID_HANDLE_VALUE;
	HANDLE hStdOutputRead  = INVALID_HANDLE_VALUE;
        HANDLE hStdOutputWrite = INVALID_HANDLE_VALUE;
	HANDLE hStdErrorRead   = INVALID_HANDLE_VALUE;
        HANDLE hStdErrorWrite  = INVALID_HANDLE_VALUE;
	DWORD flags;
	BOOL status;
        BOOL inherit;

	ZeroMemory(&sInfo, sizeof(sInfo));
	sInfo.cb = sizeof(sInfo);
	sInfo.dwFlags = STARTF_USESTDHANDLES;

	if (fdStdIn == -1) {
            if (!mkAnonPipe(&hStdInputRead,  TRUE, &hStdInputWrite,  FALSE))
                goto cleanup_err;
            sInfo.hStdInput = hStdInputRead;
        } else if (fdStdIn == 0) {
            // Don't duplicate stdin, as console handles cannot be
            // duplicated and inherited. urg.
            sInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
        } else {
            // The handle might not be inheritable, so duplicate it
            status = DuplicateHandle(GetCurrentProcess(), 
                                     (HANDLE) _get_osfhandle(fdStdIn),
                                     GetCurrentProcess(), &hStdInputRead,
                                     0,
                                     TRUE, /* inheritable */
                                     DUPLICATE_SAME_ACCESS);
            if (!status) goto cleanup_err;
            sInfo.hStdInput = hStdInputRead;
        }

	if (fdStdOut == -1) {
            if (!mkAnonPipe(&hStdOutputRead,  FALSE, &hStdOutputWrite,  TRUE))
                goto cleanup_err;
            sInfo.hStdOutput = hStdOutputWrite;
        } else if (fdStdOut == 1) {
            // Don't duplicate stdout, as console handles cannot be
            // duplicated and inherited. urg.
            sInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
        } else {
            // The handle might not be inheritable, so duplicate it
            status = DuplicateHandle(GetCurrentProcess(), 
                                     (HANDLE) _get_osfhandle(fdStdOut),
                                     GetCurrentProcess(), &hStdOutputWrite,
                                     0,
                                     TRUE, /* inheritable */
                                     DUPLICATE_SAME_ACCESS);
            if (!status) goto cleanup_err;
            sInfo.hStdOutput = hStdOutputWrite;
        }

	if (fdStdErr == -1) {
            if (!mkAnonPipe(&hStdErrorRead,  TRUE, &hStdErrorWrite,  TRUE))
                goto cleanup_err;
            sInfo.hStdError = hStdErrorWrite;
        } else if (fdStdErr == 2) {
            // Don't duplicate stderr, as console handles cannot be
            // duplicated and inherited. urg.
            sInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
        } else {
            /* The handle might not be inheritable, so duplicate it */
            status = DuplicateHandle(GetCurrentProcess(), 
                                     (HANDLE) _get_osfhandle(fdStdErr),
                                     GetCurrentProcess(), &hStdErrorWrite,
                                     0,
                                     TRUE, /* inheritable */
                                     DUPLICATE_SAME_ACCESS);
            if (!status) goto cleanup_err;
            sInfo.hStdError = hStdErrorWrite;
        }

	if (sInfo.hStdInput  != GetStdHandle(STD_INPUT_HANDLE)  &&
	    sInfo.hStdOutput != GetStdHandle(STD_OUTPUT_HANDLE) &&
	    sInfo.hStdError  != GetStdHandle(STD_ERROR_HANDLE))
		flags = CREATE_NO_WINDOW;   // Run without console window only when both output and error are redirected
	else
		flags = 0;

        // See #3231
        if (close_fds && fdStdIn == 0 && fdStdOut == 1 && fdStdErr == 2) {
            inherit = FALSE;
        } else {
            inherit = TRUE;
        }

	if (!CreateProcess(NULL, cmd, NULL, NULL, inherit, flags, environment, workingDirectory, &sInfo, &pInfo))
	{
                goto cleanup_err;
	}
	CloseHandle(pInfo.hThread);

	// Close the ends of the pipes that were inherited by the
	// child process.  This is important, otherwise we won't see
	// EOF on these pipes when the child process exits.
        if (hStdInputRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdInputRead);
        if (hStdOutputWrite != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputWrite);
        if (hStdErrorWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorWrite);

	*pfdStdInput  = _open_osfhandle((intptr_t) hStdInputWrite, _O_WRONLY);
	*pfdStdOutput = _open_osfhandle((intptr_t) hStdOutputRead, _O_RDONLY);
  	*pfdStdError  = _open_osfhandle((intptr_t) hStdErrorRead,  _O_RDONLY);

  	return (int) pInfo.hProcess;

cleanup_err:
        if (hStdInputRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdInputRead);
        if (hStdInputWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdInputWrite);
        if (hStdOutputRead  != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputRead);
        if (hStdOutputWrite != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputWrite);
        if (hStdErrorRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorRead);
        if (hStdErrorWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorWrite);
        maperrno();
        return -1;
}
Exemple #7
0
ProcHandle
runInteractiveProcess (char *cmd, char *workingDirectory, void *environment,
		       int *pfdStdInput, int *pfdStdOutput, int *pfdStdError)
{
	STARTUPINFO sInfo;
	PROCESS_INFORMATION pInfo;
	HANDLE hStdInputRead,  hStdInputWrite;
	HANDLE hStdOutputRead, hStdOutputWrite;
	HANDLE hStdErrorRead,  hStdErrorWrite;

	if (!mkAnonPipe(&hStdInputRead,  TRUE, &hStdInputWrite,  FALSE))
		return -1;

	if (!mkAnonPipe(&hStdOutputRead, FALSE, &hStdOutputWrite, TRUE))
	{
		CloseHandle(hStdInputRead);
		CloseHandle(hStdInputWrite);
		return -1;
	}

	if (!mkAnonPipe(&hStdErrorRead,  FALSE, &hStdErrorWrite,  TRUE))
	{
		CloseHandle(hStdInputRead);
		CloseHandle(hStdInputWrite);
		CloseHandle(hStdOutputRead);
		CloseHandle(hStdOutputWrite);
		return -1;
	}

	ZeroMemory(&sInfo, sizeof(sInfo));
	sInfo.cb = sizeof(sInfo);
	sInfo.dwFlags = STARTF_USESTDHANDLES;
	sInfo.hStdInput = hStdInputRead;
	sInfo.hStdOutput= hStdOutputWrite;
	sInfo.hStdError = hStdErrorWrite;

	if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, environment, workingDirectory, &sInfo, &pInfo))
	{
		maperrno();
		CloseHandle(hStdInputRead);
		CloseHandle(hStdInputWrite);
		CloseHandle(hStdOutputRead);
		CloseHandle(hStdOutputWrite);
		CloseHandle(hStdErrorRead);
		CloseHandle(hStdErrorWrite);
		return -1;
	}
	CloseHandle(pInfo.hThread);

	// Close the ends of the pipes that were inherited by the
	// child process.  This is important, otherwise we won't see
	// EOF on these pipes when the child process exits.
	CloseHandle(hStdInputRead);
	CloseHandle(hStdOutputWrite);
	CloseHandle(hStdErrorWrite);

	*pfdStdInput  = _open_osfhandle((intptr_t) hStdInputWrite, _O_WRONLY);
	*pfdStdOutput = _open_osfhandle((intptr_t) hStdOutputRead, _O_RDONLY);
  	*pfdStdError  = _open_osfhandle((intptr_t) hStdErrorRead, _O_RDONLY);

  	return (int) pInfo.hProcess;
}
Exemple #8
0
/*
 * Function: mkAnonPipe
 *
 * Purpose:  create an anonymous pipe with read and write ends being
 *           optionally (non-)inheritable.
 */
static BOOL
mkAnonPipe (HANDLE* pHandleIn, BOOL isInheritableIn, 
	    HANDLE* pHandleOut, BOOL isInheritableOut)
{
	HANDLE hTemporaryIn  = NULL;
	HANDLE hTemporaryOut = NULL;
	BOOL status;
	SECURITY_ATTRIBUTES sec_attrs;

	/* Create inheritable security attributes */
	sec_attrs.nLength = sizeof(SECURITY_ATTRIBUTES);
	sec_attrs.lpSecurityDescriptor = NULL;
	sec_attrs.bInheritHandle = TRUE;

	/* Create the anon pipe with both ends inheritable */
	if (!CreatePipe(&hTemporaryIn, &hTemporaryOut, &sec_attrs, 0))
	{
		maperrno();
		*pHandleIn  = NULL;
		*pHandleOut = NULL;
		return FALSE;
	}

	if (isInheritableIn)
		*pHandleIn = hTemporaryIn;
	else
	{
		/* Make the read end non-inheritable */
		status = DuplicateHandle(GetCurrentProcess(), hTemporaryIn,
			      GetCurrentProcess(), pHandleIn,
			      0,
			      FALSE, /* non-inheritable */
			      DUPLICATE_SAME_ACCESS);
		CloseHandle(hTemporaryIn);
		if (!status)
		{
			maperrno();
			*pHandleIn  = NULL;
			*pHandleOut = NULL;
			CloseHandle(hTemporaryOut);
			return FALSE;
		}
	}

	if (isInheritableOut)
		*pHandleOut = hTemporaryOut;
	else
	{
		/* Make the write end non-inheritable */
		status = DuplicateHandle(GetCurrentProcess(), hTemporaryOut,
			      GetCurrentProcess(), pHandleOut,
			      0,
			      FALSE, /* non-inheritable */
			      DUPLICATE_SAME_ACCESS);
		CloseHandle(hTemporaryOut);
		if (!status)
		{
			maperrno();
			*pHandleIn  = NULL;
			*pHandleOut = NULL;
			CloseHandle(*pHandleIn);
      		return FALSE;
    	}
	}

	return TRUE;
}