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