2 #include <msvcrt/process.h>
3 #include <msvcrt/stdlib.h>
4 #include <msvcrt/string.h>
5 #include <msvcrt/errno.h>
6 #include <msvcrt/internal/file.h>
9 #include <msvcrt/msvcrtdbg.h>
22 const char* find_exec(const char* path, char* rpath)
28 DPRINT("find_exec('%s', %x)\n", path, rpath);
34 if (strlen(path) > FILENAME_MAX - 1)
38 /* copy path in rpath */
39 for (rd = path, rp = rpath; *rd; *rp++ = *rd++);
41 /* try first with the name as is */
42 for (i = 0; i < sizeof(ext) / sizeof(*ext); i++)
46 DPRINT("trying '%s'\n", rpath);
48 if (_access(rpath, F_OK) == 0 && _access(rpath, D_OK) != 0)
56 char* env = getenv("PATH");
64 for (; *ep && (*ep != ';'); *rp++ = *ep++);
68 if (*rp != '/' && *rp != '\\')
74 for (rd=path; *rd; *rp++ = *rd++);
75 for (i = 0; i < sizeof(ext) / sizeof(*ext); i++)
79 DPRINT("trying '%s'\n", rpath);
81 if (_access(rpath, F_OK) == 0 && _access(rpath, D_OK) != 0)
92 return found ? rpath : path;
96 argvtos(char* const* argv, char delim)
104 for (i = 0, len = 0; argv[i]; i++)
106 len += strlen(argv[i]) + 1;
109 str = ptr = (char*) malloc(len + 1);
113 for(i = 0; argv[i]; i++)
115 len = strlen(argv[i]);
116 memcpy(ptr, argv[i], len);
126 valisttos(const char* arg0, va_list alist, char delim)
128 va_list alist2 = alist;
139 len += strlen(ptr) + 1;
140 ptr = va_arg(alist, char*);
144 str = (char*) malloc(len + 1);
152 memcpy(ptr, arg0, len);
155 arg0 = va_arg(alist2, char*);
164 do_spawn(int mode, const char* cmdname, const char* args, const char* envp)
166 STARTUPINFOA StartupInfo;
167 PROCESS_INFORMATION ProcessInformation;
175 DPRINT("do_spawn('%s')\n", cmdname);
177 if (mode != _P_NOWAIT && mode != _P_NOWAITO && mode != _P_WAIT && mode != _P_DETACH && mode != _P_OVERLAY)
179 __set_errno ( EINVAL );
183 if (0 != _access(cmdname, F_OK))
185 __set_errno ( ENOENT );
188 if (0 == _access(cmdname, D_OK))
190 __set_errno ( EISDIR );
194 memset (&StartupInfo, 0, sizeof(StartupInfo));
195 StartupInfo.cb = sizeof(StartupInfo);
197 for (last = i = 0; i < maxfno; i++)
199 if ((void*)-1 != _get_osfhandle(i))
207 StartupInfo.cbReserved2 = sizeof(ULONG) + last * (sizeof(char) + sizeof(HANDLE));
208 StartupInfo.lpReserved2 = malloc(StartupInfo.cbReserved2);
209 if (StartupInfo.lpReserved2 == NULL)
211 __set_errno ( ENOMEM );
215 *(DWORD*)StartupInfo.lpReserved2 = last;
216 fmode = (char*)(StartupInfo.lpReserved2 + sizeof(ULONG));
217 hFile = (HANDLE*)(StartupInfo.lpReserved2 + sizeof(ULONG) + last * sizeof(char));
218 for (i = 0; i < last; i++)
220 int _mode = __fileno_getmode(i);
221 HANDLE h = _get_osfhandle(i);
222 /* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
225 if ((((ULONG)h) & 0x10000003) == 0x3 || _mode & _O_NOINHERIT || (i < 3 && mode == _P_DETACH))
227 *hFile = INVALID_HANDLE_VALUE;
234 bFlag = GetHandleInformation(h, &dwFlags);
235 if (bFlag && (dwFlags & HANDLE_FLAG_INHERIT))
238 *fmode = (_O_ACCMODE & _mode) | (((_O_TEXT | _O_BINARY) & _mode) >> 8);
242 *hFile = INVALID_HANDLE_VALUE;
251 bResult = CreateProcessA((char *)cmdname,
256 mode == _P_DETACH ? DETACHED_PROCESS : 0,
260 &ProcessInformation);
261 if (StartupInfo.lpReserved2)
263 free(StartupInfo.lpReserved2);
268 dwError = GetLastError();
269 DPRINT("%x\n", dwError);
270 __set_errno(dwError);
273 CloseHandle(ProcessInformation.hThread);
279 WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
280 GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
281 CloseHandle(ProcessInformation.hProcess);
282 return (int)dwExitCode;
284 CloseHandle(ProcessInformation.hProcess);
287 return (int)ProcessInformation.hProcess;
293 int _spawnl(int mode, const char *cmdname, const char* arg0, ...)
299 DPRINT("_spawnl('%s')\n", cmdname);
301 va_start(argp, arg0);
302 args = valisttos(arg0, argp, ' ');
306 ret = do_spawn(mode, cmdname, args, NULL);
315 int _spawnv(int mode, const char *cmdname, char* const* argv)
320 DPRINT("_spawnv('%s')\n", cmdname);
322 args = argvtos(argv, ' ');
326 ret = do_spawn(mode, cmdname, args, NULL);
335 int _spawnle(int mode, const char *cmdname, const char* arg0, ... /*, NULL, const char* const* envp*/)
343 DPRINT("_spawnle('%s')\n", cmdname);
345 va_start(argp, arg0);
346 args = valisttos(arg0, argp, ' ');
349 ptr = (char* const*)va_arg(argp, char*);
352 ptr = (char* const*)va_arg(argp, char*);
353 envs = argvtos(ptr, 0);
356 ret = do_spawn(mode, cmdname, args, envs);
370 int _spawnve(int mode, const char *cmdname, char* const* argv, char* const* envp)
376 DPRINT("_spawnve('%s')\n", cmdname);
378 args = argvtos(argv, ' ');
379 envs = argvtos(envp, 0);
383 ret = do_spawn(mode, cmdname, args, envs);
396 int _spawnvp(int mode, const char* cmdname, char* const* argv)
398 char pathname[FILENAME_MAX];
400 DPRINT("_spawnvp('%s')\n", cmdname);
402 return _spawnv(mode, find_exec(cmdname, pathname), argv);
408 int _spawnlp(int mode, const char* cmdname, const char* arg0, .../*, NULL*/)
413 char pathname[FILENAME_MAX];
415 DPRINT("_spawnlp('%s')\n", cmdname);
417 va_start(argp, arg0);
418 args = valisttos(arg0, argp, ' ');
421 ret = do_spawn(mode, find_exec(cmdname, pathname), args, NULL);
431 int _spawnlpe(int mode, const char* cmdname, const char* arg0, .../*, NULL, const char* const* envp*/)
438 char pathname[FILENAME_MAX];
440 DPRINT("_spawnlpe('%s')\n", cmdname);
442 va_start(argp, arg0);
443 args = valisttos(arg0, argp, ' ');
446 ptr = (char* const*)va_arg(argp, char*);
449 ptr = (char* const*)va_arg(argp, char*);
450 envs = argvtos(ptr, 0);
453 ret = do_spawn(mode, find_exec(cmdname, pathname), args, envs);
466 int _spawnvpe(int mode, const char* cmdname, char* const* argv, char* const* envp)
468 char pathname[FILENAME_MAX];
470 DPRINT("_spawnvpe('%s')\n", cmdname);
472 return _spawnve(mode, find_exec(cmdname, pathname), argv, envp);
478 int _execl(const char* cmdname, const char* arg0, ...)
484 DPRINT("_execl('%s')\n", cmdname);
486 va_start(argp, arg0);
487 args = valisttos(arg0, argp, ' ');
491 ret = do_spawn(P_OVERLAY, cmdname, args, NULL);
500 int _execv(const char* cmdname, char* const* argv)
502 DPRINT("_execv('%s')\n", cmdname);
503 return _spawnv(P_OVERLAY, cmdname, argv);
509 int _execle(const char* cmdname, const char* arg0, ... /*, NULL, char* const* envp */)
517 DPRINT("_execle('%s')\n", cmdname);
519 va_start(argp, arg0);
520 args = valisttos(arg0, argp, ' ');
523 ptr = (char* const*)va_arg(argp, char*);
526 ptr = (char* const*)va_arg(argp, char*);
527 envs = argvtos(ptr, 0);
530 ret = do_spawn(P_OVERLAY, cmdname, args, envs);
543 int _execve(const char* cmdname, char* const* argv, char* const* envp)
545 DPRINT("_execve('%s')\n", cmdname);
546 return _spawnve(P_OVERLAY, cmdname, argv, envp);
552 int _execlp(const char* cmdname, const char* arg0, ...)
557 char pathname[FILENAME_MAX];
559 DPRINT("_execlp('%s')\n", cmdname);
561 va_start(argp, arg0);
562 args = valisttos(arg0, argp, ' ');
566 ret = do_spawn(P_OVERLAY, find_exec(cmdname, pathname), args, NULL);
575 int _execvp(const char* cmdname, char* const* argv)
577 DPRINT("_execvp('%s')\n", cmdname);
578 return _spawnvp(P_OVERLAY, cmdname, argv);
584 int _execlpe(const char* cmdname, const char* arg0, ... /*, NULL, char* const* envp */)
591 char pathname[FILENAME_MAX];
593 DPRINT("_execlpe('%s')\n", cmdname);
595 va_start(argp, arg0);
596 args = valisttos(arg0, argp, ' ');
599 ptr = (char* const*)va_arg(argp, char*);
602 ptr = (char* const*)va_arg(argp, char*);
603 envs = argvtos(ptr, 0);
606 ret = do_spawn(P_OVERLAY, find_exec(cmdname, pathname), args, envs);
619 int _execvpe(const char* cmdname, char* const* argv, char* const* envp)
621 DPRINT("_execvpe('%s')\n", cmdname);
622 return _spawnvpe(P_OVERLAY, cmdname, argv, envp);