3 #include <msvcrt/process.h>
4 #include <msvcrt/stdlib.h>
5 #include <msvcrt/fcntl.h>
6 #include <msvcrt/errno.h>
9 #include <msvcrt/msvcrtdbg.h>
14 argvtos(char* const* argv, char delim)
22 for (i = 0, len = 0; argv[i]; i++)
24 len += strlen(argv[i]) + 1;
27 str = ptr = (char*) malloc(len + 1);
31 for(i = 0; argv[i]; i++)
33 len = strlen(argv[i]);
34 memcpy(ptr, argv[i], len);
44 valisttos(const char* arg0, va_list alist, char delim)
46 va_list alist2 = alist;
57 len += strlen(ptr) + 1;
58 ptr = va_arg(alist, char*);
62 str = (char*) malloc(len + 1);
70 memcpy(ptr, arg0, len);
72 arg0 = va_arg(alist2, char*);
81 do_spawn(int mode, const char* cmdname, const char* args, const char* envp)
83 STARTUPINFO StartupInfo;
84 PROCESS_INFORMATION ProcessInformation;
92 DPRINT("do_spawn('%s')\n", cmdname);
94 if (mode != _P_NOWAIT && mode != _P_NOWAITO && mode != _P_WAIT && mode != _P_DETACH && mode != _P_OVERLAY)
100 if (0 != _access(cmdname, F_OK))
105 if (0 == _access(cmdname, D_OK))
111 memset (&StartupInfo, 0, sizeof(STARTUPINFO));
112 StartupInfo.cb = sizeof(STARTUPINFO);
114 for (last = i = 0; i < maxfno; i++)
116 if ((void*)-1 != _get_osfhandle(i))
124 StartupInfo.cbReserved2 = sizeof(ULONG) + last * (sizeof(char) + sizeof(HANDLE));
125 StartupInfo.lpReserved2 = malloc(StartupInfo.cbReserved2);
126 if (StartupInfo.lpReserved2 == NULL)
132 *(DWORD*)StartupInfo.lpReserved2 = last;
133 fmode = (char*)(StartupInfo.lpReserved2 + sizeof(ULONG));
134 hFile = (HANDLE*)(StartupInfo.lpReserved2 + sizeof(ULONG) + last * sizeof(char));
135 for (i = 0; i < last; i++)
137 int _mode = __fileno_getmode(i);
138 HANDLE h = _get_osfhandle(i);
139 /* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
142 if ((((ULONG)h) & 0x10000003) == 0x3 || _mode & _O_NOINHERIT || (i < 3 && mode == _P_DETACH))
144 *hFile = INVALID_HANDLE_VALUE;
151 bFlag = GetHandleInformation(h, &dwFlags);
152 if (bFlag && (dwFlags & HANDLE_FLAG_INHERIT))
155 *fmode = (_O_ACCMODE & _mode) | (((_O_TEXT | _O_BINARY) & _mode) >> 8);
159 *hFile = INVALID_HANDLE_VALUE;
168 bResult = CreateProcessA((char *)cmdname,
173 mode == _P_DETACH ? DETACHED_PROCESS : 0,
177 &ProcessInformation);
178 if (StartupInfo.lpReserved2)
180 free(StartupInfo.lpReserved2);
185 dwError = GetLastError();
186 DPRINT("%x\n", dwError);
187 __set_errno(dwError);
190 CloseHandle(ProcessInformation.hThread);
196 WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
197 GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
198 CloseHandle(ProcessInformation.hProcess);
199 return (int)dwExitCode;
201 CloseHandle(ProcessInformation.hProcess);
204 return (int)ProcessInformation.hProcess;
207 int _spawnl(int mode, const char *cmdname, const char* arg0, ...)
213 DPRINT("_spawnl('%s')\n", cmdname);
215 va_start(argp, arg0);
216 args = valisttos(arg0, argp, ' ');
220 ret = do_spawn(mode, cmdname, args, NULL);
226 int _spawnv(int mode, const char *cmdname, char* const* argv)
231 DPRINT("_spawnv('%s')\n", cmdname);
233 args = argvtos(argv, ' ');
237 ret = do_spawn(mode, cmdname, args, NULL);
243 int _spawnle(int mode, const char *cmdname, const char* arg0, ... /*, NULL, const char* const* envp*/)
251 DPRINT("_spawnle('%s')\n", cmdname);
253 va_start(argp, arg0);
254 args = valisttos(arg0, argp, ' ');
257 ptr = (char* const*)va_arg(argp, char*);
260 envs = argvtos(ptr, 0);
263 ret = do_spawn(mode, cmdname, args, envs);
274 int _spawnve(int mode, const char *cmdname, char* const* argv, char* const* envp)
280 DPRINT("_spawnve('%s')\n", cmdname);
282 args = argvtos(argv, ' ');
283 envs = argvtos(envp, 0);
287 ret = do_spawn(mode, cmdname, args, envs);
297 int _spawnvp(int mode, const char* cmdname, char* const* argv)
299 char pathname[FILENAME_MAX];
301 DPRINT("_spawnvp('%s')\n", cmdname);
303 _searchenv(cmdname, "PATH", pathname);
305 return _spawnv(mode, pathname[0] ? pathname : cmdname, argv);
308 int _spawnlpe(int mode, const char* cmdname, const char* arg0, .../*, NULL, const char* const* envp*/)
315 char pathname[FILENAME_MAX];
317 DPRINT("_spawnlpe('%s')\n", cmdname);
319 _searchenv(cmdname, "PATH", pathname);
321 va_start(argp, arg0);
322 args = valisttos(arg0, argp, ' ');
325 ptr = (char* const*)va_arg(argp, char*);
328 envs = argvtos(ptr, 0);
331 ret = do_spawn(mode, pathname[0] ? pathname : cmdname, args, envs);
341 int _spawnvpe(int mode, const char* cmdname, char* const* argv, char* const* envp)
343 char pathname[FILENAME_MAX];
345 DPRINT("_spawnvpe('%s')\n", cmdname);
347 _searchenv(cmdname, "PATH", pathname);
349 return _spawnve(mode, pathname[0] ? pathname : cmdname, argv, envp);
352 int _execl(const char* cmdname, const char* arg0, ...)
358 DPRINT("_execl('%s')\n", cmdname);
360 va_start(argp, arg0);
361 args = valisttos(arg0, argp, ' ');
365 ret = do_spawn(P_OVERLAY, cmdname, args, NULL);
371 int _execv(const char* cmdname, char* const* argv)
373 DPRINT("_execv('%s')\n", cmdname);
374 return _spawnv(P_OVERLAY, cmdname, argv);
377 int _execle(const char* cmdname, const char* arg0, ... /*, NULL, char* const* envp */)
385 DPRINT("_execle('%s')\n", cmdname);
387 va_start(argp, arg0);
388 args = valisttos(arg0, argp, ' ');
391 ptr = (char* const*)va_arg(argp, char*);
394 envs = argvtos((char**)ptr, 0);
397 ret = do_spawn(P_OVERLAY, cmdname, args, envs);
407 int _execve(const char* cmdname, char* const* argv, char* const* envp)
409 DPRINT("_execve('%s')\n", cmdname);
410 return _spawnve(P_OVERLAY, cmdname, argv, envp);
413 int _execlp(const char* cmdname, const char* arg0, ...)
418 char pathname[FILENAME_MAX];
420 DPRINT("_execlp('%s')\n", cmdname);
422 _searchenv(cmdname, "PATH", pathname);
424 va_start(argp, arg0);
425 args = valisttos(arg0, argp, ' ');
429 ret = do_spawn(P_OVERLAY, pathname[0] ? pathname : cmdname, args, NULL);
435 int _execvp(const char* cmdname, char* const* argv)
437 DPRINT("_execvp('%s')\n", cmdname);
438 return _spawnvp(P_OVERLAY, cmdname, argv);
441 int _execlpe(const char* cmdname, const char* arg0, ... /*, NULL, char* const* envp */)
448 char pathname[FILENAME_MAX];
450 DPRINT("_execlpe('%s')\n", cmdname);
452 _searchenv(cmdname, "PATH", pathname);
454 va_start(argp, arg0);
455 args = valisttos(arg0, argp, ' ');
458 ptr = (char* const*)va_arg(argp, char*);
461 envs = argvtos(ptr, 0);
464 ret = do_spawn(P_OVERLAY, pathname[0] ? pathname : cmdname, args, envs);
474 int _execvpe(const char* cmdname, char* const* argv, char* const* envp)
476 DPRINT("_execvpe('%s')\n", cmdname);
477 return _spawnvpe(P_OVERLAY, cmdname, argv, envp);