1 /* libc replacement functions for win32.
3 Copyright (C) 1998, 99 Free Software Foundation, Inc.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 This does make sense only under WIN32.
22 - win32_system() rewritten
27 #include <kpathsea/config.h>
28 #include <kpathsea/c-proto.h>
29 #include <kpathsea/win32lib.h>
30 #include <kpathsea/lib.h>
34 extern void *parse_cmdline(char *line, char **input, char **output);
35 extern char *build_cmdline(char ***cmd, char *input, char *output);
38 It has been proven that system() fails to retrieve exit codes
39 under Win9x. This is a workaround for this bug.
42 int __cdecl win32_system(const char *cmd, int async)
45 PROCESS_INFORMATION pi;
47 HANDLE hIn, hOut, hPipeIn, hPipeOut;
48 SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
51 char *app_name, *new_cmd;
52 char *red_input, *red_output, ***cmd_pipe;
57 /* Admittedly, the command interpreter will allways be found. */
61 fprintf(stderr, "system: (null) command.\n");
66 if (look_for_cmd(cmd, &app_name, &new_cmd) == FALSE) {
67 /* Failed to find the command or malformed cmd */
70 fprintf(stderr, "system: failed to find command.\n");
75 cmd_pipe = parse_cmdline(new_cmd, &red_input, &red_output);
77 for (i = 0; cmd_pipe[i]; i++) {
79 /* free the cmd and build the current one */
80 if (new_cmd) free(new_cmd);
82 new_cmd = build_cmdline(&cmd_pipe[i], NULL, NULL);
84 /* First time, use red_input if available */
87 hIn = CreateFile(red_input,
89 FILE_SHARE_READ | FILE_SHARE_WRITE,
92 FILE_ATTRIBUTE_NORMAL,
94 if (hIn == INVALID_HANDLE_VALUE) {
96 fprintf(stderr, "system: failed to open hIn (%s) with error %d.\n", red_input, GetLastError());
103 hIn = GetStdHandle(STD_INPUT_HANDLE);
106 /* Last time, use red_output if available */
107 if (cmd_pipe[i+1] == NULL) {
109 hOut = CreateFile(red_output,
111 FILE_SHARE_READ | FILE_SHARE_WRITE,
114 FILE_ATTRIBUTE_NORMAL,
116 if (hOut == INVALID_HANDLE_VALUE) {
118 fprintf(stderr, "system: failed to open hOut (%s) with error %d.\n", red_output, GetLastError());
125 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
130 /* FIXME : implement pipes !!! */
133 ZeroMemory( &si, sizeof(STARTUPINFO) );
134 si.cb = sizeof(STARTUPINFO);
135 si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
136 si.wShowWindow = SW_SHOW;
138 si.hStdOutput = hOut;
139 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
142 fprintf(stderr, "Executing: %s\n", new_cmd);
144 if (CreateProcess(app_name,
154 fprintf(stderr, "win32_system(%s) call failed (Error %d).\n", cmd, GetLastError());
158 /* Only the process handle is needed */
159 CloseHandle(pi.hThread);
162 if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_OBJECT_0) {
163 if (GetExitCodeProcess(pi.hProcess, &ret) == 0) {
164 fprintf(stderr, "Failed to retrieve exit code: %s (Error %d)\n", cmd, GetLastError());
169 fprintf(stderr, "Failed to wait for process termination: %s (Error %d)\n", cmd, GetLastError());
174 CloseHandle(pi.hProcess);
176 if (red_input) CloseHandle(hIn);
177 if (red_output) CloseHandle(hOut);
180 if (new_cmd) free(new_cmd);
181 if (app_name) free(app_name);