diff options
Diffstat (limited to 'src/pal/tests/palsuite/threading/CreateProcessA')
10 files changed, 830 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateProcessA/CMakeLists.txt new file mode 100644 index 0000000000..ef14ea5352 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +add_subdirectory(test1) +add_subdirectory(test2) + diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateProcessA/test1/CMakeLists.txt new file mode 100644 index 0000000000..67e53edccd --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test1/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(TESTSOURCES + parentProcess.c +) + +add_executable(paltest_createprocessa_test1 + ${TESTSOURCES} +) + +add_dependencies(paltest_createprocessa_test1 coreclrpal) + +target_link_libraries(paltest_createprocessa_test1 + pthread + m + coreclrpal +) + + +set(HELPERSOURCES + childProcess.c +) + +add_executable(paltest_createprocessa_test1_child + ${HELPERSOURCES} +) + +add_dependencies(paltest_createprocessa_test1_child coreclrpal) + +target_link_libraries(paltest_createprocessa_test1_child + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.c b/src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.c new file mode 100644 index 0000000000..ccbb050c04 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.c @@ -0,0 +1,131 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Source: CreateProcessA/test1/childprocess.c +** +** Purpose: Test to ensure CreateProcessA starts a new process. This test +** launches a child process, and examines a file written by the child. +** This code is the child code. +** +** Dependencies: GetCurrentDirectory +** strlen +** fopen +** fclose +** fprintf +** + +** +**=========================================================*/ + +#include <palsuite.h> + +const char *szCommonFileA = "childdata.tmp"; + +const char *szPathDelimA = "\\"; + +const char *szCommonStringA = "058d2d057111a313aa82401c2e856002\0"; + +/* + * Take two wide strings representing file and directory names + * (dirName, fileName), join the strings with the appropriate path + * delimiter and populate a wide character buffer (absPathName) with + * the resulting string. + * + * Returns: The number of wide characters in the resulting string. + * 0 is returned on Error. + */ +int +mkAbsoluteFilenameA ( + LPSTR dirName, + DWORD dwDirLength, + LPCSTR fileName, + DWORD dwFileLength, + LPSTR absPathName ) +{ + extern const char *szPathDelimA; + + DWORD sizeDN, sizeFN, sizeAPN; + + sizeDN = strlen( dirName ); + sizeFN = strlen( fileName ); + sizeAPN = (sizeDN + 1 + sizeFN + 1); + + /* insure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */ + if ( sizeAPN > _MAX_PATH ) + { + return ( 0 ); + } + + strncpy(absPathName, dirName, dwDirLength +1); + strncpy(absPathName, szPathDelimA, 2); + strncpy(absPathName, fileName, dwFileLength +1); + + return (sizeAPN); + +} + +int __cdecl main( int argc, char **argv ) +{ + + static FILE * fp; + + DWORD dwFileLength; + DWORD dwDirLength; + DWORD dwSize; + + char szDirNameA[_MAX_DIR]; + char szAbsPathNameA[_MAX_PATH]; + + if(0 != (PAL_Initialize(argc, argv))) + { + return ( FAIL ); + } + + dwDirLength = GetCurrentDirectory( _MAX_PATH, szDirNameA ); + + if (0 == dwDirLength) + { + Fail ("GetCurrentDirectory call failed. Could not get " + "current working directory\n. Exiting.\n"); + } + + dwFileLength = strlen( szCommonFileA ); + + dwSize = mkAbsoluteFilenameA( szDirNameA, dwDirLength, szCommonFileA, + dwFileLength, szAbsPathNameA ); + + if (0 == dwSize) + { + Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could " + "not build absolute path name to file\n. Exiting.\n"); + } + + if ( NULL == ( fp = fopen ( szAbsPathNameA , "w+" ) ) ) + { + /* + * A return value of NULL indicates an error condition or an + * EOF condition + */ + Fail ("%s unable to open %s for writing. Exiting.\n", argv[0] + , szAbsPathNameA ); + } + + if ( 0 >= ( fprintf ( fp, "%s", szCommonStringA ))) + { + Fail("%s unable to write to %s. Exiting.\n", argv[0] + , szAbsPathNameA ); + } + + if (0 != (fclose ( fp ))) + { + Fail ("%s unable to close file %s. Pid may not be " + "written to file. Exiting.\n", argv[0], szAbsPathNameA ); + } + + PAL_Terminate(); + return ( PASS ); + +} diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.c b/src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.c new file mode 100644 index 0000000000..b0c5808a7e --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.c @@ -0,0 +1,201 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Source: CreateProcessA/test1/parentprocess.c +** +** Purpose: Test to ensure CreateProcessA starts a new process. This test +** launches a child process, and examines a file written by the child. +** This process (the parent process) reads the file created by the child and +** compares the value the child wrote to the file. (a const char *) +** +** Dependencies: GetCurrentDirectory +** strlen +** WaitForSingleObject +** fopen +** fclose +** Fail +** + +** +**=========================================================*/ + +#include <palsuite.h> + +const char *szCommonFileA = "childdata.tmp"; + +const char *szChildFileA = "paltest_createprocessa_test1_child"; + +const char *szPathDelimA = "\\"; + +const char *szCommonStringA = "058d2d057111a313aa82401c2e856002\0"; + +/* + * Take two wide strings representing file and directory names + * (dirName, fileName), join the strings with the appropriate path + * delimiter and populate a wide character buffer (absPathName) with + * the resulting string. + * + * Returns: The number of wide characters in the resulting string. + * 0 is returned on Error. + */ +int +mkAbsoluteFilenameA ( + LPSTR dirName, + DWORD dwDirLength, + LPCSTR fileName, + DWORD dwFileLength, + LPSTR absPathName ) +{ + extern const char *szPathDelimA; + + DWORD sizeDN, sizeFN, sizeAPN; + + sizeDN = strlen( dirName ); + sizeFN = strlen( fileName ); + sizeAPN = (sizeDN + 1 + sizeFN + 1); + + /* insure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */ + if ( sizeAPN > _MAX_PATH ) + { + return ( 0 ); + } + + strncpy(absPathName, dirName, dwDirLength +1); + strncpy(absPathName, szPathDelimA, 2); + strncpy(absPathName, fileName, dwFileLength +1); + + return (sizeAPN); + +} + +int __cdecl main( int argc, char **argv ) + +{ + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + static FILE * fp; + + DWORD dwFileLength; + DWORD dwDirLength; + DWORD dwSize; + + size_t cslen; + + char szReadStringA[256]; + + char szDirNameA[_MAX_DIR]; + char absPathBuf[_MAX_PATH]; + char *szAbsPathNameA; + + + if(0 != (PAL_Initialize(argc, argv))) + { + return ( FAIL ); + } + + ZeroMemory ( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory ( &pi, sizeof(pi) ); + + szAbsPathNameA=&absPathBuf[0]; + dwFileLength = strlen( szChildFileA ); + + dwDirLength = GetCurrentDirectory(_MAX_PATH, szDirNameA); + + if (0 == dwDirLength) + { + Fail ("GetCurrentDirectory call failed. Could not get " + "current working directory\n. Exiting.\n"); + } + + dwSize = mkAbsoluteFilenameA( szDirNameA, dwDirLength, szChildFileA, + dwFileLength, szAbsPathNameA ); + + if (0 == dwSize) + { + Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could " + "not build absolute path name to file\n. Exiting.\n"); + } + + if ( !CreateProcessA ( NULL, + szAbsPathNameA, + NULL, + NULL, + FALSE, + CREATE_NEW_CONSOLE, + NULL, + NULL, + &si, + &pi ) + ) + { + Fail ( "CreateProcess call failed. GetLastError returned %d\n", + GetLastError() ); + } + + WaitForSingleObject ( pi.hProcess, INFINITE ); + + szAbsPathNameA=&absPathBuf[0]; + + dwFileLength = strlen( szCommonFileA ); + + dwSize = mkAbsoluteFilenameA( szDirNameA, dwDirLength, szCommonFileA, + dwFileLength, szAbsPathNameA ); + + /* set the string length for the open call*/ + + if (0 == dwSize) + { + Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could " + "not build absolute path name to file\n. Exiting.\n"); + } + + if ( NULL == ( fp = fopen ( szAbsPathNameA , "r" ) ) ) + { + Fail ("%s\nunable to open %s\nfor reading. Exiting.\n", argv[0], + szAbsPathNameA ); + } + + cslen = strlen ( szCommonStringA ); + + if ( NULL == fgets( szReadStringA, (cslen + 1), fp )) + { + /* + * A return value of NULL indicates an error condition or an + * EOF condition + */ + Fail ("%s\nunable to read file\n%s\nszReadStringA is %s\n" + "Exiting.\n", argv[0], szAbsPathNameA, + szReadStringA ); + + } + if ( 0 != strncmp( szReadStringA, szCommonStringA, cslen )) + { + Fail ("string comparison failed.\n szReadStringA is %s and\n" + "szCommonStringA is %s\n", szReadStringA, + szCommonStringA ); + } + else + { + Trace ("string comparison passed.\n"); + } + + if (0 != (fclose ( fp ))) + { + Trace ("%s unable to close file %s. This may cause a file pointer " + "leak. Continuing.\n", argv[0], szAbsPathNameA ); + } + + /* Close process and thread handle */ + CloseHandle ( pi.hProcess ); + CloseHandle ( pi.hThread ); + + PAL_Terminate(); + return ( PASS ); + +} diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test1/testinfo.dat b/src/pal/tests/palsuite/threading/CreateProcessA/test1/testinfo.dat new file mode 100644 index 0000000000..02c25444fe --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test1/testinfo.dat @@ -0,0 +1,17 @@ +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. + +Version = 1.0 +Section = threading +Function = CreateProcessA +Name = Positive Test for CreateProcessA +TYPE = DEFAULT +EXE1 = parentprocess +EXE2 = childprocess +Description += Test the CreateProcessA function. The test executes the childprocess += program. The childprocess program launches and writes a const char string += to a file childdata. The parent waits for the completion of childprocess += and then reads the string from the childdata file. If the string in the += file matches it's copy of the const char string, then the test succeeds. diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateProcessA/test2/CMakeLists.txt new file mode 100644 index 0000000000..b81ea2e978 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test2/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(TESTSOURCES + parentprocess.c +) + +add_executable(paltest_createprocessa_test2 + ${TESTSOURCES} +) + +add_dependencies(paltest_createprocessa_test2 coreclrpal) + +target_link_libraries(paltest_createprocessa_test2 + pthread + m + coreclrpal +) + + +set(HELPERSOURCES + childprocess.c +) + +add_executable(paltest_createprocessa_test2_child + ${HELPERSOURCES} +) + +add_dependencies(paltest_createprocessa_test2_child coreclrpal) + +target_link_libraries(paltest_createprocessa_test2_child + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.c b/src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.c new file mode 100644 index 0000000000..baa20c2d3c --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.c @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Source: createprocessa/test2/childprocess.c +** +** Purpose: This child process reads a string from stdin +** and writes it out to stdout & stderr +** +** Dependencies: memset +** fgets +** gputs +** + +** +**=========================================================*/ + +#include <palsuite.h> +#include "test2.h" + + + +int __cdecl main( int argc, char **argv ) +{ + int iRetCode = EXIT_OK_CODE; /* preset exit code to OK */ + char szBuf[BUF_LEN]; + + + if(0 != (PAL_Initialize(argc, argv))) + { + return FAIL; + } + + if (argc != 4) + { + return EXIT_ERR_CODE3; + } + + if (strcmp(argv[1], szArg1) != 0 + || strcmp(argv[2], szArg2) != 0 + || strcmp(argv[3], szArg3) != 0) + { + return EXIT_ERR_CODE4; + } + + + memset(szBuf, 0, BUF_LEN); + + /* Read the string that was written by the parent */ + if (fgets(szBuf, BUF_LEN, stdin) == NULL) + { + return EXIT_ERR_CODE1; + } + + /* Write the string out to the stdout & stderr pipes */ + if (fputs(szBuf, stdout) == EOF + || fputs(szBuf, stderr) == EOF) + { + return EXIT_ERR_CODE2; + } + + /* The exit code will indicate success or failure */ + PAL_TerminateEx(iRetCode); + + /* Return special exit code to indicate success or failure */ + return iRetCode; +} diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.c b/src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.c new file mode 100644 index 0000000000..ef3340c5d9 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.c @@ -0,0 +1,243 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Source: createprocessa/test2/parentprocess.c +** +** Purpose: Test the following features of CreateProcessA: +** - Check to see if hProcess & hThread are set in +** return PROCESS_INFORMATION structure +** - Check to see if stdin, stdout, & stderr handles +** are used when STARTF_USESTDHANDLES is specified +** in STARUPINFO flags and bInheritHandles = TRUE +** - Check to see that proper arguments are passed to +** child process +** +** Dependencies: CreatePipe +** strcpy, strlen, strncmp, memset +** WaitForSingleObject +** WriteFile, ReadFile +** GetExitCodeProcess +** + +** +**=========================================================*/ + +#include <palsuite.h> +#include "test2.h" + + + +int __cdecl main( int argc, char **argv ) +{ + + /******************************************* + * Declarations + *******************************************/ + STARTUPINFO si; + PROCESS_INFORMATION pi; + + HANDLE hTestStdInR = NULL; + HANDLE hTestStdInW = NULL; + HANDLE hTestStdOutR = NULL; + HANDLE hTestStdOutW = NULL; + HANDLE hTestStdErrR = NULL; + HANDLE hTestStdErrW = NULL; + + BOOL bRetVal = FALSE; + DWORD dwBytesWritten = 0; + DWORD dwBytesRead = 0; + DWORD dwExitCode = 0; + + SECURITY_ATTRIBUTES pipeAttributes; + + char szStdOutBuf[BUF_LEN]; + char szStdErrBuf[BUF_LEN]; + char szFullPathNameA[_MAX_PATH]; + + + /******************************************* + * Initialization + *******************************************/ + + if(0 != (PAL_Initialize(argc, argv))) + { + return ( FAIL ); + } + + /*Setup SECURITY_ATTRIBUTES structure for CreatePipe*/ + pipeAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + pipeAttributes.lpSecurityDescriptor = NULL; + pipeAttributes.bInheritHandle = TRUE; + + + /*Create a StdIn pipe for child*/ + bRetVal = CreatePipe(&hTestStdInR, /* read handle*/ + &hTestStdInW, /* write handle */ + &pipeAttributes, /* security attributes*/ + 1024); /* pipe size*/ + + if (bRetVal == FALSE) + { + Fail("ERROR: %ld :Unable to create stdin pipe\n", GetLastError()); + } + + + /*Create a StdOut pipe for child*/ + bRetVal = CreatePipe(&hTestStdOutR, /* read handle*/ + &hTestStdOutW, /* write handle */ + &pipeAttributes, /* security attributes*/ + 0); /* pipe size*/ + + if (bRetVal == FALSE) + { + Fail("ERROR: %ld :Unable to create stdout pipe\n", GetLastError()); + } + + + /*Create a StdErr pipe for child*/ + bRetVal = CreatePipe(&hTestStdErrR, /* read handle*/ + &hTestStdErrW, /* write handle */ + &pipeAttributes, /* security attributes*/ + 0); /* pipe size*/ + + if (bRetVal == FALSE) + { + Fail("ERROR: %ld :Unable to create stderr pipe\n", GetLastError()); + } + + /* Zero the data structure space */ + ZeroMemory ( &pi, sizeof(pi) ); + ZeroMemory ( &si, sizeof(si) ); + + /* Set the process flags and standard io handles */ + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = hTestStdInR; + si.hStdOutput = hTestStdOutW; + si.hStdError = hTestStdErrW; + + strcpy(szFullPathNameA, szChildFileA); + strcat(szFullPathNameA, szArgs); + + /******************************************* + * Start Testing + *******************************************/ + + /* Launch the child */ + if ( !CreateProcessA (NULL, szFullPathNameA, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi )) + { + Fail("ERROR: CreateProcess call failed. GetLastError returned %d\n", + GetLastError() ); + } + + /* Check the returned process information for validity */ + if (pi.hProcess == 0 || pi.hThread == 0) + { + Fail("ERROR: CreateProcess Error: Process Handle = %u, Thread Handle = %u\n", + pi.hProcess, pi.hThread); + } + + /* Write the Constructed string to stdin pipe for the child process */ + if (WriteFile(hTestStdInW, szTestString, strlen(szTestString), &dwBytesWritten, NULL) == FALSE + || WriteFile(hTestStdInW, "\n", strlen("\n"), &dwBytesWritten, NULL) == FALSE) + { + Fail("ERROR: %ld :unable to write to write pipe handle " + "hTestStdInW=0x%lx\n", GetLastError(), hTestStdInW); + } + + /* Wait for the child to finish, Max 20 seconds */ + dwExitCode = WaitForSingleObject(pi.hProcess, 20000); + + /* If the child failed then whole thing fails */ + if (dwExitCode != WAIT_OBJECT_0) + { + TerminateProcess(pi.hProcess, 0); + Fail("ERROR: The child failed to run properly.\n"); + } + + /* Check for problems in the child process */ + if (GetExitCodeProcess(pi.hProcess, &dwExitCode) == FALSE) + { + Fail("ERROR: Call to GetExitCodeProcess failed.\n"); + } + else if (dwExitCode == EXIT_ERR_CODE1) + { + Fail("ERROR: The Child process could not reead the string " + "written to the stdin pipe.\n"); + } + else if (dwExitCode == EXIT_ERR_CODE2) + { + Fail("ERROR: The Child process could not write the string " + "the stdout pipe or stderr pipe.\n"); + } + else if (dwExitCode == EXIT_ERR_CODE3) + { + Fail("ERROR: The Child received the wrong number of " + "command line arguments.\n"); + } + else if (dwExitCode == EXIT_ERR_CODE4) + { + Fail("ERROR: The Child received the wrong " + "command line arguments.\n"); + } + else if (dwExitCode != EXIT_OK_CODE) + { + Fail("ERROR: Unexpected exit code returned: %u. Child process " + "did not complete its part of the test.\n", dwExitCode); + } + + + /* The child ran ok, so check to see if we received the proper */ + /* strings through the pipes. */ + + /* clear our buffers */ + memset(szStdOutBuf, 0, BUF_LEN); + memset(szStdErrBuf, 0, BUF_LEN); + + /* Read the data back from the child process stdout */ + bRetVal = ReadFile(hTestStdOutR, /* handle to read pipe*/ + szStdOutBuf, /* buffer to write to*/ + BUF_LEN, /* number of bytes to read*/ + &dwBytesRead, /* number of bytes read*/ + NULL); /* overlapped buffer*/ + + /*Read the data back from the child process stderr */ + bRetVal = ReadFile(hTestStdErrR, /* handle to read pipe*/ + szStdErrBuf, /* buffer to write to*/ + BUF_LEN, /* number of bytes to read*/ + &dwBytesRead, /* number of bytes read*/ + NULL); /* overlapped buffer*/ + + + /* Confirm that we recieved the same string that we originally */ + /* wrote to the child and was received on both stdout & stderr.*/ + if (strncmp(szTestString, szStdOutBuf, strlen(szTestString)) != 0 + || strncmp(szTestString, szStdErrBuf, strlen(szTestString)) != 0) + { + Fail("ERROR: The data read back from child does not match " + "what was written. STDOUT: %s STDERR: %s\n", + szStdOutBuf, szStdErrBuf); + } + + + /******************************************* + * Clean Up + *******************************************/ + + /* Close process and thread handle */ + CloseHandle ( pi.hProcess ); + CloseHandle ( pi.hThread ); + + CloseHandle(hTestStdInR); + CloseHandle(hTestStdInW); + CloseHandle(hTestStdOutR); + CloseHandle(hTestStdOutW); + CloseHandle(hTestStdErrR); + CloseHandle(hTestStdErrW); + + PAL_Terminate(); + return ( PASS ); +} diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test2/test2.h b/src/pal/tests/palsuite/threading/CreateProcessA/test2/test2.h new file mode 100644 index 0000000000..8cdff3b939 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test2/test2.h @@ -0,0 +1,72 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Source: test2.h +** + +** +**===========================================================*/ + + +const char *szChildFileA = "paltest_createprocessa_test2_child"; +const char *szArgs = " A B C"; +const char *szArg1 = "A"; +const char *szArg2 = "B"; +const char *szArg3 = "C"; + +const char *szPathDelimA = "\\"; + +const char *szTestString = "Copyright (c) Microsoft"; + +const DWORD EXIT_OK_CODE = 100; +const DWORD EXIT_ERR_CODE1 = 101; +const DWORD EXIT_ERR_CODE2 = 102; +const DWORD EXIT_ERR_CODE3 = 103; +const DWORD EXIT_ERR_CODE4 = 104; +const DWORD EXIT_ERR_CODE5 = 105; + +#define BUF_LEN 64 + +/* + * Take two wide strings representing file and directory names + * (dirName, fileName), join the strings with the appropriate path + * delimiter and populate a wide character buffer (absPathName) with + * the resulting string. + * + * Returns: The number of wide characters in the resulting string. + * 0 is returned on Error. + */ +int +mkAbsoluteFilenameA ( + LPSTR dirName, + DWORD dwDirLength, + LPCSTR fileName, + DWORD dwFileLength, + LPSTR absPathName ) +{ + extern const char *szPathDelimA; + + DWORD sizeDN; + DWORD sizeFN; + DWORD sizeAPN; + + sizeDN = strlen( dirName ); + sizeFN = strlen( fileName ); + sizeAPN = (sizeDN + 1 + sizeFN + 1); + + /* insure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */ + if ( sizeAPN > _MAX_PATH ) + { + return ( 0 ); + } + + strncpy(absPathName, dirName, dwDirLength +1); + strcat(absPathName, szPathDelimA); + strcat(absPathName, fileName); + + return (sizeAPN); + +} diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test2/testinfo.dat b/src/pal/tests/palsuite/threading/CreateProcessA/test2/testinfo.dat new file mode 100644 index 0000000000..23fcdf93ae --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateProcessA/test2/testinfo.dat @@ -0,0 +1,20 @@ +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. + +Version = 1.0 +Section = threading +Function = CreateProcessA +Name = PROCESS_INFORMATION and HANDLE Inheritance +TYPE = DEFAULT +EXE1 = parentprocess +EXE2 = childprocess +Description += Test the following features of CreateProcessA: += - Check to see if hProcess & hThread are set in += return PROCESS_INFORMATION structure += - Check to see if stdin, stdout, & stderr handles += are used when STARTF_USESTDHANDLES is specified += in STARUPINFO flags and bInheritHandles = TRUE += - Check to see that proper arguments are passed to += child process |