FreeRDP/winpr/libwinpr/thread/test/TestThreadCreateProcess.c
Bernhard Miklautz 72f13aeacb CreateProcess: add stdin/out/err redirection
When launching a new process stdin/stdout/stderr can be redirected by
passing the corresponding HANDLEs in the passed lpStartupInfo structure.
This is required for example if a pipe should be used as stdin/stdout.

If set in lpStartupInfo the file descriptor of the passed handle is
now used. The test was updated accordingly.
2015-08-28 10:41:23 +02:00

155 lines
3.6 KiB
C

#include <stdio.h>
#include <winpr/crt.h>
#include <winpr/tchar.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/environment.h>
#include <winpr/pipe.h>
#define TESTENV "TEST_PROCESS=oyeah"
int TestThreadCreateProcess(int argc, char* argv[])
{
BOOL status;
DWORD exitCode;
LPCTSTR lpApplicationName;
LPTSTR lpCommandLine;
LPSECURITY_ATTRIBUTES lpProcessAttributes;
LPSECURITY_ATTRIBUTES lpThreadAttributes;
BOOL bInheritHandles;
DWORD dwCreationFlags;
LPVOID lpEnvironment;
LPCTSTR lpCurrentDirectory;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
LPTCH lpszEnvironmentBlock;
HANDLE pipe_read = NULL;
HANDLE pipe_write = NULL;
char buf[255];
DWORD read_bytes;
int ret = 0;
lpszEnvironmentBlock = GetEnvironmentStrings();
lpApplicationName = NULL;
//lpCommandLine = _T("ls -l /");
#ifdef _WIN32
lpCommandLine = _T("env");
#else
lpCommandLine = _T("printenv");
#endif
lpProcessAttributes = NULL;
lpThreadAttributes = NULL;
bInheritHandles = FALSE;
dwCreationFlags = 0;
lpEnvironment = NULL;
lpEnvironment = lpszEnvironmentBlock;
lpCurrentDirectory = NULL;
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
status = CreateProcess(lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
&StartupInfo,
&ProcessInformation);
if (!status)
{
printf("CreateProcess failed. error=%d\n", GetLastError());
return 1;
}
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
exitCode = 0;
status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);
printf("GetExitCodeProcess status: %d\n", status);
printf("Process exited with code: 0x%08X\n", exitCode);
CloseHandle(ProcessInformation.hProcess);
CloseHandle(ProcessInformation.hThread);
FreeEnvironmentStrings(lpszEnvironmentBlock);
/* Test stdin,stdout,stderr redirection */
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
if (!CreatePipe(&pipe_read, &pipe_write, NULL, 0))
{
printf("Pipe creation failed. error=%d\n", GetLastError());
return 1;
}
StartupInfo.hStdOutput = pipe_write;
StartupInfo.hStdError = pipe_write;
lpEnvironment = calloc(1, sizeof(TESTENV) + 1);
strncpy(lpEnvironment, TESTENV, strlen(TESTENV));
lpCommandLine = _T("printenv");
status = CreateProcess(lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
&StartupInfo,
&ProcessInformation);
free(lpEnvironment);
if (!status)
{
CloseHandle(pipe_read);
CloseHandle(pipe_write);
printf("CreateProcess failed. error=%d\n", GetLastError());
return 1;
}
if (WaitForSingleObject(pipe_read, 200) != WAIT_OBJECT_0)
{
printf("pipe wait failed.\n");
ret = 1;
}
else
{
ReadFile(pipe_read, buf, 255, &read_bytes, NULL);
if (read_bytes < strlen(TESTENV))
{
printf("pipe read problem?!\n");
ret = 1;
}
}
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
CloseHandle(pipe_read);
CloseHandle(pipe_write);
exitCode = 0;
status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);
printf("GetExitCodeProcess status: %d\n", status);
printf("Process exited with code: 0x%08X\n", exitCode);
CloseHandle(ProcessInformation.hProcess);
CloseHandle(ProcessInformation.hThread);
return ret;
}