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
);