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