6 #include <internal/file.h>
10 #include <internal/debug.h>
13 #define find_execT find_execW
14 #define argvtosT argvtosW
15 #define do_spawnT do_spawnW
16 #define valisttosT valisttosW
19 #define find_execT find_execA
20 #define argvtosT argvtosA
21 #define do_spawnT do_spawnA
22 #define valisttosT valisttosA
27 _TCHAR
const* extT
[] =
36 const _TCHAR
* find_execT(const _TCHAR
* path
, _TCHAR
* rpath
)
42 DPRINT(MK_STR(find_execT
)"('%"sT
"', %x)\n", path
, rpath
);
48 if (_tcslen(path
) > FILENAME_MAX
- 1)
52 /* copy path in rpath */
53 for (rd
= path
, rp
= rpath
; *rd
; *rp
++ = *rd
++)
56 /* try first with the name as is */
57 for (i
= 0; i
< sizeof(extT
) / sizeof(*extT
); i
++)
61 DPRINT("trying '%"sT
"'\n", rpath
);
63 if (_taccess(rpath
, F_OK
) == 0 && access_dirT(rpath
) != 0)
71 _TCHAR
* env
= _tgetenv(_T("PATH"));
80 for (; *ep
&& (*ep
!= ';'); *rp
++ = *ep
++)
85 if (*rp
!= '/' && *rp
!= '\\')
91 for (rd
=path
; *rd
; *rp
++ = *rd
++)
93 for (i
= 0; i
< sizeof(extT
) / sizeof(*extT
); i
++)
97 DPRINT("trying '%"sT
"'\n", rpath
);
99 if (_taccess(rpath
, F_OK
) == 0 && access_dirT(rpath
) != 0)
109 return found
? rpath
: path
;
113 argvtosT(const _TCHAR
* const* argv
, _TCHAR delim
)
121 for (i
= 0, len
= 0; argv
[i
]; i
++)
123 len
+= _tcslen(argv
[i
]) + 1;
126 str
= ptr
= (_TCHAR
*) malloc(len
+ 1);
130 for(i
= 0; argv
[i
]; i
++)
132 len
= _tcslen(argv
[i
]);
133 memcpy(ptr
, argv
[i
], len
);
143 valisttosT(const _TCHAR
* arg0
, va_list alist
, _TCHAR delim
)
145 va_list alist2
= alist
;
156 len
+= _tcslen(ptr
) + 1;
157 ptr
= va_arg(alist
, _TCHAR
*);
161 str
= (_TCHAR
*) malloc(len
+ 1);
169 memcpy(ptr
, arg0
, len
);
172 arg0
= va_arg(alist2
, _TCHAR
*);
181 do_spawnT(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* args
, const _TCHAR
* envp
)
183 STARTUPINFO StartupInfo
= {0};
184 PROCESS_INFORMATION ProcessInformation
;
192 TRACE(MK_STR(do_spawnT
)"(%i,'%"sT
"','%"sT
"','%"sT
"')",mode
,cmdname
,args
,envp
);
195 if (mode
!= _P_NOWAIT
&& mode
!= _P_NOWAITO
&& mode
!= _P_WAIT
&& mode
!= _P_DETACH
&& mode
!= _P_OVERLAY
)
197 __set_errno ( EINVAL
);
201 if (0 != _taccess(cmdname
, F_OK
))
203 __set_errno ( ENOENT
);
206 if (0 == access_dirT(cmdname
))
208 __set_errno ( EISDIR
);
212 //memset (&StartupInfo, 0, sizeof(StartupInfo));
213 StartupInfo
.cb
= sizeof(StartupInfo
);
217 for (last
= i
= 0; i
< FDINFO_FD_MAX
; i
++)
219 if ((void*)-1 != _get_osfhandle(i
))
227 StartupInfo
.cbReserved2
= sizeof(ULONG
) + last
* (sizeof(char) + sizeof(HANDLE
));
228 StartupInfo
.lpReserved2
= malloc(StartupInfo
.cbReserved2
);
229 if (StartupInfo
.lpReserved2
== NULL
)
231 __set_errno ( ENOMEM
);
235 *(DWORD
*)StartupInfo
.lpReserved2
= last
;
236 fmode
= (char*)(StartupInfo
.lpReserved2
+ sizeof(ULONG
));
237 hFile
= (HANDLE
*)(StartupInfo
.lpReserved2
+ sizeof(ULONG
) + last
* sizeof(char));
238 for (i
= 0; i
< last
; i
++)
240 int _mode
= __fileno_getmode(i
);
241 HANDLE h
= _get_osfhandle(i
);
242 /* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
245 if ((((ULONG
)h
) & 0x10000003) == 0x3 || _mode
& _O_NOINHERIT
|| (i
< 3 && mode
== _P_DETACH
))
247 *hFile
= INVALID_HANDLE_VALUE
;
254 bFlag
= GetHandleInformation(h
, &dwFlags
);
255 if (bFlag
&& (dwFlags
& HANDLE_FLAG_INHERIT
))
258 *fmode
= (_O_ACCMODE
& _mode
) | (((_O_TEXT
| _O_BINARY
) & _mode
) >> 8);
262 *hFile
= INVALID_HANDLE_VALUE
;
272 create_io_inherit_block((STARTUPINFOA
*) &StartupInfo
);
274 bResult
= CreateProcess((_TCHAR
*)cmdname
,
279 mode
== _P_DETACH
? DETACHED_PROCESS
: 0,
283 &ProcessInformation
);
285 if (StartupInfo
.lpReserved2
)
287 free(StartupInfo
.lpReserved2
);
292 dwError
= GetLastError();
293 DPRINT("%x\n", dwError
);
294 __set_errno(dwError
);
297 CloseHandle(ProcessInformation
.hThread
);
302 CloseHandle(ProcessInformation
.hThread
);
303 return((int)ProcessInformation
.hProcess
);
307 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
308 GetExitCodeProcess(ProcessInformation
.hProcess
, &dwExitCode
);
309 CloseHandle(ProcessInformation
.hProcess
);
310 CloseHandle(ProcessInformation
.hThread
);
311 return( (int)dwExitCode
); //CORRECT?
313 CloseHandle(ProcessInformation
.hProcess
);
314 CloseHandle(ProcessInformation
.hThread
);
317 return( (int)ProcessInformation
.hProcess
);
323 int _tspawnl(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ...)
329 DPRINT(MK_STR(_tspawnl
)"('%"sT
"')\n", cmdname
);
331 va_start(argp
, arg0
);
332 args
= valisttosT(arg0
, argp
, ' ');
336 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
345 int _tspawnv(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
)
350 DPRINT(MK_STR(_tspawnv
)"('%"sT
"')\n", cmdname
);
352 args
= argvtosT(argv
, ' ');
356 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
365 int _tspawnle(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ... /*, NULL, const char* const* envp*/)
370 _TCHAR
const * const* ptr
;
373 DPRINT(MK_STR(_tspawnle
)"('%"sT
"')\n", cmdname
);
375 va_start(argp
, arg0
);
376 args
= valisttosT(arg0
, argp
, ' ');
379 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
382 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
383 envs
= argvtosT(ptr
, 0);
386 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
400 int _tspawnve(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
406 DPRINT(MK_STR(_tspawnve
)"('%"sT
"')\n", cmdname
);
408 args
= argvtosT(argv
, ' ');
409 envs
= argvtosT(envp
, 0);
413 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
426 int _tspawnvp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
428 _TCHAR pathname
[FILENAME_MAX
];
430 DPRINT(MK_STR(_tspawnvp
)"('%"sT
"')\n", cmdname
);
432 return _tspawnv(mode
, find_execT(cmdname
, pathname
), argv
);
438 int _tspawnlp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL*/)
443 _TCHAR pathname
[FILENAME_MAX
];
445 DPRINT(MK_STR(_tspawnlp
)"('%"sT
"')\n", cmdname
);
447 va_start(argp
, arg0
);
448 args
= valisttosT(arg0
, argp
, ' ');
451 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, NULL
);
461 int _tspawnlpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL, const char* const* envp*/)
466 _TCHAR
const* const * ptr
;
468 _TCHAR pathname
[FILENAME_MAX
];
470 DPRINT(MK_STR(_tspawnlpe
)"('%"sT
"')\n", cmdname
);
472 va_start(argp
, arg0
);
473 args
= valisttosT(arg0
, argp
, ' ');
476 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
479 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
480 envs
= argvtosT(ptr
, 0);
483 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, envs
);
496 int _tspawnvpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
498 _TCHAR pathname
[FILENAME_MAX
];
500 DPRINT(MK_STR(_tspawnvpe
)"('%"sT
"')\n", cmdname
);
502 return _tspawnve(mode
, find_execT(cmdname
, pathname
), argv
, envp
);
508 int _texecl(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
514 DPRINT(MK_STR(_texecl
)"('%"sT
"')\n", cmdname
);
516 va_start(argp
, arg0
);
517 args
= valisttosT(arg0
, argp
, ' ');
521 ret
= do_spawnT(P_OVERLAY
, cmdname
, args
, NULL
);
530 int _texecv(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
532 DPRINT(MK_STR(_texecv
)"('%"sT
"')\n", cmdname
);
533 return _tspawnv(P_OVERLAY
, cmdname
, argv
);
539 int _texecle(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
544 _TCHAR
const* const* ptr
;
547 DPRINT(MK_STR(_texecle
)"('%"sT
"')\n", cmdname
);
549 va_start(argp
, arg0
);
550 args
= valisttosT(arg0
, argp
, ' ');
553 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
556 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
557 envs
= argvtosT(ptr
, 0);
560 ret
= do_spawnT(P_OVERLAY
, cmdname
, args
, envs
);
573 int _texecve(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
575 DPRINT(MK_STR(_texecve
)"('%"sT
"')\n", cmdname
);
576 return _tspawnve(P_OVERLAY
, cmdname
, argv
, envp
);
582 int _texeclp(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
587 _TCHAR pathname
[FILENAME_MAX
];
589 DPRINT(MK_STR(_texeclp
)"('%"sT
"')\n", cmdname
);
591 va_start(argp
, arg0
);
592 args
= valisttosT(arg0
, argp
, ' ');
596 ret
= do_spawnT(P_OVERLAY
, find_execT(cmdname
, pathname
), args
, NULL
);
605 int _texecvp(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
607 DPRINT(MK_STR(_texecvp
)"('%"sT
"')\n", cmdname
);
608 return _tspawnvp(P_OVERLAY
, cmdname
, argv
);
614 int _texeclpe(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
619 _TCHAR
const* const* ptr
;
621 _TCHAR pathname
[FILENAME_MAX
];
623 DPRINT(MK_STR(_texeclpe
)"('%"sT
"')\n", cmdname
);
625 va_start(argp
, arg0
);
626 args
= valisttosT(arg0
, argp
, ' ');
629 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
632 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
633 envs
= argvtosT(ptr
, 0);
636 ret
= do_spawnT(P_OVERLAY
, find_execT(cmdname
, pathname
), args
, envs
);
649 int _texecvpe(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
651 DPRINT(MK_STR(_texecvpe
)"('%"sT
"')\n", cmdname
);
652 return _tspawnvpe(P_OVERLAY
, cmdname
, argv
, envp
);