| | 945 | #elif defined( WIN32 ) |
|---|
| | 946 | SECURITY_ATTRIBUTES saAttr; |
|---|
| | 947 | PROCESS_INFORMATION piProcInfo; |
|---|
| | 948 | STARTUPINFO siStartInfo; |
|---|
| | 949 | BOOL bFuncRetn = FALSE; |
|---|
| | 950 | HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr; |
|---|
| | 951 | DWORD i_status; |
|---|
| | 952 | char *psz_cmd, *p_env, *p; |
|---|
| | 953 | char **ppsz_parser; |
|---|
| | 954 | int i_size; |
|---|
| | 955 | |
|---|
| | 956 | /* Set the bInheritHandle flag so pipe handles are inherited. */ |
|---|
| | 957 | saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); |
|---|
| | 958 | saAttr.bInheritHandle = TRUE; |
|---|
| | 959 | saAttr.lpSecurityDescriptor = NULL; |
|---|
| | 960 | |
|---|
| | 961 | /* Create a pipe for the child process's STDOUT. */ |
|---|
| | 962 | if ( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0 ) ) |
|---|
| | 963 | { |
|---|
| | 964 | msg_Err( p_object, "stdout pipe creation failed" ); |
|---|
| | 965 | return -1; |
|---|
| | 966 | } |
|---|
| | 967 | |
|---|
| | 968 | /* Ensure the read handle to the pipe for STDOUT is not inherited. */ |
|---|
| | 969 | SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0 ); |
|---|
| | 970 | |
|---|
| | 971 | /* Create a pipe for the child process's STDIN. */ |
|---|
| | 972 | if ( !CreatePipe( &hChildStdinRd, &hChildStdinWr, &saAttr, 0 ) ) |
|---|
| | 973 | { |
|---|
| | 974 | msg_Err( p_object, "stdin pipe creation failed" ); |
|---|
| | 975 | return -1; |
|---|
| | 976 | } |
|---|
| | 977 | |
|---|
| | 978 | /* Ensure the write handle to the pipe for STDIN is not inherited. */ |
|---|
| | 979 | SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0 ); |
|---|
| | 980 | |
|---|
| | 981 | /* Set up members of the PROCESS_INFORMATION structure. */ |
|---|
| | 982 | ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); |
|---|
| | 983 | |
|---|
| | 984 | /* Set up members of the STARTUPINFO structure. */ |
|---|
| | 985 | ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); |
|---|
| | 986 | siStartInfo.cb = sizeof(STARTUPINFO); |
|---|
| | 987 | siStartInfo.hStdError = hChildStdoutWr; |
|---|
| | 988 | siStartInfo.hStdOutput = hChildStdoutWr; |
|---|
| | 989 | siStartInfo.hStdInput = hChildStdinRd; |
|---|
| | 990 | siStartInfo.dwFlags |= STARTF_USESTDHANDLES; |
|---|
| | 991 | |
|---|
| | 992 | /* Set up the command line. */ |
|---|
| | 993 | psz_cmd = malloc(32768); |
|---|
| | 994 | psz_cmd[0] = '\0'; |
|---|
| | 995 | i_size = 32768; |
|---|
| | 996 | ppsz_parser = &ppsz_argv[0]; |
|---|
| | 997 | while ( ppsz_parser[0] != NULL && i_size > 0 ) |
|---|
| | 998 | { |
|---|
| | 999 | /* Protect the last argument with quotes ; the other arguments |
|---|
| | 1000 | * are supposed to be already protected because they have been |
|---|
| | 1001 | * passed as a command-line option. */ |
|---|
| | 1002 | if ( ppsz_parser[1] == NULL ) |
|---|
| | 1003 | { |
|---|
| | 1004 | strncat( psz_cmd, "\"", i_size ); |
|---|
| | 1005 | i_size--; |
|---|
| | 1006 | } |
|---|
| | 1007 | strncat( psz_cmd, *ppsz_parser, i_size ); |
|---|
| | 1008 | i_size -= strlen( *ppsz_parser ); |
|---|
| | 1009 | if ( ppsz_parser[1] == NULL ) |
|---|
| | 1010 | { |
|---|
| | 1011 | strncat( psz_cmd, "\"", i_size ); |
|---|
| | 1012 | i_size--; |
|---|
| | 1013 | } |
|---|
| | 1014 | strncat( psz_cmd, " ", i_size ); |
|---|
| | 1015 | i_size--; |
|---|
| | 1016 | ppsz_parser++; |
|---|
| | 1017 | } |
|---|
| | 1018 | |
|---|
| | 1019 | /* Set up the environment. */ |
|---|
| | 1020 | p = p_env = malloc(32768); |
|---|
| | 1021 | i_size = 32768; |
|---|
| | 1022 | ppsz_parser = &ppsz_env[0]; |
|---|
| | 1023 | while ( *ppsz_parser != NULL && i_size > 0 ) |
|---|
| | 1024 | { |
|---|
| | 1025 | memcpy( p, *ppsz_parser, |
|---|
| | 1026 | __MIN((int)(strlen(*ppsz_parser) + 1), i_size) ); |
|---|
| | 1027 | p += strlen(*ppsz_parser) + 1; |
|---|
| | 1028 | i_size -= strlen(*ppsz_parser) + 1; |
|---|
| | 1029 | ppsz_parser++; |
|---|
| | 1030 | } |
|---|
| | 1031 | *p = '\0'; |
|---|
| | 1032 | |
|---|
| | 1033 | /* Create the child process. */ |
|---|
| | 1034 | bFuncRetn = CreateProcess( NULL, |
|---|
| | 1035 | psz_cmd, // command line |
|---|
| | 1036 | NULL, // process security attributes |
|---|
| | 1037 | NULL, // primary thread security attributes |
|---|
| | 1038 | TRUE, // handles are inherited |
|---|
| | 1039 | 0, // creation flags |
|---|
| | 1040 | p_env, |
|---|
| | 1041 | psz_cwd, |
|---|
| | 1042 | &siStartInfo, // STARTUPINFO pointer |
|---|
| | 1043 | &piProcInfo ); // receives PROCESS_INFORMATION |
|---|
| | 1044 | |
|---|
| | 1045 | free( psz_cmd ); |
|---|
| | 1046 | free( p_env ); |
|---|
| | 1047 | |
|---|
| | 1048 | if ( bFuncRetn == 0 ) |
|---|
| | 1049 | { |
|---|
| | 1050 | msg_Err( p_object, "child creation failed" ); |
|---|
| | 1051 | return -1; |
|---|
| | 1052 | } |
|---|
| | 1053 | |
|---|
| | 1054 | /* Read from a file and write its contents to a pipe. */ |
|---|
| | 1055 | while ( i_in > 0 && !p_object->b_die ) |
|---|
| | 1056 | { |
|---|
| | 1057 | DWORD i_written; |
|---|
| | 1058 | if ( !WriteFile( hChildStdinWr, p_in, i_in, &i_written, NULL ) ) |
|---|
| | 1059 | break; |
|---|
| | 1060 | i_in -= i_written; |
|---|
| | 1061 | p_in += i_written; |
|---|
| | 1062 | } |
|---|
| | 1063 | |
|---|
| | 1064 | /* Close the pipe handle so the child process stops reading. */ |
|---|
| | 1065 | CloseHandle(hChildStdinWr); |
|---|
| | 1066 | |
|---|
| | 1067 | /* Close the write end of the pipe before reading from the |
|---|
| | 1068 | * read end of the pipe. */ |
|---|
| | 1069 | CloseHandle(hChildStdoutWr); |
|---|
| | 1070 | |
|---|
| | 1071 | /* Read output from the child process. */ |
|---|
| | 1072 | *pi_data = 0; |
|---|
| | 1073 | *pp_data = malloc( 1025 ); /* +1 for \0 */ |
|---|
| | 1074 | |
|---|
| | 1075 | while ( !p_object->b_die ) |
|---|
| | 1076 | { |
|---|
| | 1077 | DWORD i_read; |
|---|
| | 1078 | if ( !ReadFile( hChildStdoutRd, &(*pp_data)[*pi_data], 1024, &i_read, |
|---|
| | 1079 | NULL ) |
|---|
| | 1080 | || i_read == 0 ) |
|---|
| | 1081 | break; |
|---|
| | 1082 | *pi_data += i_read; |
|---|
| | 1083 | *pp_data = realloc( *pp_data, *pi_data + 1025 ); |
|---|
| | 1084 | } |
|---|
| | 1085 | |
|---|
| | 1086 | while ( !p_object->b_die |
|---|
| | 1087 | && !GetExitCodeProcess( piProcInfo.hProcess, &i_status ) |
|---|
| | 1088 | && i_status != STILL_ACTIVE ) |
|---|
| | 1089 | msleep( 10000 ); |
|---|
| | 1090 | |
|---|
| | 1091 | CloseHandle(piProcInfo.hProcess); |
|---|
| | 1092 | CloseHandle(piProcInfo.hThread); |
|---|
| | 1093 | |
|---|
| | 1094 | if ( i_status ) |
|---|
| | 1095 | msg_Warn( p_object, |
|---|
| | 1096 | "child %s returned with error code %ld", |
|---|
| | 1097 | ppsz_argv[0], i_status ); |
|---|
| | 1098 | |
|---|