edd09400be549ff27b3a1fbb1aaab1aa201b7900
[reactos.git] / reactos / lib / msvcrt / process / _system.c
1 /* $Id: _system.c,v 1.5 2002/11/24 18:42:23 robd Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/msvcrt/process/system.c
6 * PURPOSE: Excutes a shell command
7 * PROGRAMER: Boudewijn Dekker
8 * UPDATE HISTORY:
9 * 04/03/99: Created
10 */
11 #include <windows.h>
12 #include <msvcrt/stdlib.h>
13 #include <msvcrt/string.h>
14 #include <msvcrt/process.h>
15 #include <msvcrt/errno.h>
16
17 int system(const char *command)
18 {
19 char *szCmdLine = NULL;
20 char *szComSpec = NULL;
21
22 PROCESS_INFORMATION ProcessInformation;
23 STARTUPINFO StartupInfo;
24 char *s;
25 BOOL result;
26
27 int nStatus;
28
29 szComSpec = getenv("COMSPEC");
30
31 // system should return 0 if command is null and the shell is found
32
33 if (command == NULL) {
34 if (szComSpec == NULL)
35 return 0;
36 else
37 {
38 free(szComSpec);
39 return -1;
40 }
41 }
42
43 // should return 127 or 0 ( MS ) if the shell is not found
44 // __set_errno(ENOENT);
45
46 if (szComSpec == NULL)
47 {
48 szComSpec = strdup("cmd.exe");
49 if (szComSpec == NULL)
50 {
51 __set_errno(ENOMEM);
52 return -1;
53 }
54 }
55
56 s = max(strchr(szComSpec, '\\'), strchr(szComSpec, '/'));
57 if (s == NULL)
58 s = szComSpec;
59 else
60 s++;
61
62 szCmdLine = malloc(strlen(s) + 4 + strlen(command) + 1);
63 if (szCmdLine == NULL)
64 {
65 free (szComSpec);
66 __set_errno(ENOMEM);
67 return -1;
68 }
69
70 strcpy(szCmdLine, s);
71 s = strrchr(szCmdLine, '.');
72 if (s)
73 *s = 0;
74 strcat(szCmdLine, " /C ");
75 strcat(szCmdLine, command);
76
77 //command file has invalid format ENOEXEC
78
79 memset (&StartupInfo, 0, sizeof(STARTUPINFO));
80 StartupInfo.cb = sizeof(STARTUPINFO);
81 StartupInfo.lpReserved= NULL;
82 StartupInfo.dwFlags = 0;
83 StartupInfo.wShowWindow = SW_SHOWDEFAULT;
84 StartupInfo.lpReserved2 = NULL;
85 StartupInfo.cbReserved2 = 0;
86
87 // According to ansi standards the new process should ignore SIGINT and SIGQUIT
88 // In order to disable ctr-c the process is created with CREATE_NEW_PROCESS_GROUP,
89 // thus SetConsoleCtrlHandler(NULL,TRUE) is made on behalf of the new process.
90
91
92 //SIGCHILD should be blocked aswell
93
94 result = CreateProcessA(szComSpec,
95 szCmdLine,
96 NULL,
97 NULL,
98 TRUE,
99 0,
100 NULL,
101 NULL,
102 &StartupInfo,
103 &ProcessInformation);
104 free(szCmdLine);
105 free(szComSpec);
106
107 if (result == FALSE)
108 {
109 __set_errno(ENOEXEC);
110 return -1;
111 }
112
113 CloseHandle(ProcessInformation.hThread);
114
115 // system should wait untill the calling process is finished
116 _cwait(&nStatus,(int)ProcessInformation.hProcess,0);
117 CloseHandle(ProcessInformation.hProcess);
118
119 return nStatus;
120 }