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
)
40 unsigned int i
, found
= 0;
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 return((int)ProcessInformation
.hProcess
);
304 CloseHandle(ProcessInformation
.hProcess
);
307 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
308 GetExitCodeProcess(ProcessInformation
.hProcess
, &dwExitCode
);
309 CloseHandle(ProcessInformation
.hProcess
);
310 return( (int)dwExitCode
); //CORRECT?
312 CloseHandle(ProcessInformation
.hProcess
);
315 return( (int)ProcessInformation
.hProcess
);
321 int _tspawnl(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ...)
327 DPRINT(MK_STR(_tspawnl
)"('%"sT
"')\n", cmdname
);
329 va_start(argp
, arg0
);
330 args
= valisttosT(arg0
, argp
, ' ');
334 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
343 int _tspawnv(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
)
348 DPRINT(MK_STR(_tspawnv
)"('%"sT
"')\n", cmdname
);
350 args
= argvtosT(argv
, ' ');
354 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
363 int _tspawnle(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ... /*, NULL, const char* const* envp*/)
368 _TCHAR
const * const* ptr
;
371 DPRINT(MK_STR(_tspawnle
)"('%"sT
"')\n", cmdname
);
373 va_start(argp
, arg0
);
374 args
= valisttosT(arg0
, argp
, ' ');
377 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
380 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
381 envs
= argvtosT(ptr
, 0);
384 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
398 int _tspawnve(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
404 DPRINT(MK_STR(_tspawnve
)"('%"sT
"')\n", cmdname
);
406 args
= argvtosT(argv
, ' ');
407 envs
= argvtosT(envp
, 0);
411 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
424 int _tspawnvp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
426 _TCHAR pathname
[FILENAME_MAX
];
428 DPRINT(MK_STR(_tspawnvp
)"('%"sT
"')\n", cmdname
);
430 return _tspawnv(mode
, find_execT(cmdname
, pathname
), argv
);
436 int _tspawnlp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL*/)
441 _TCHAR pathname
[FILENAME_MAX
];
443 DPRINT(MK_STR(_tspawnlp
)"('%"sT
"')\n", cmdname
);
445 va_start(argp
, arg0
);
446 args
= valisttosT(arg0
, argp
, ' ');
449 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, NULL
);
459 int _tspawnlpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL, const char* const* envp*/)
464 _TCHAR
const* const * ptr
;
466 _TCHAR pathname
[FILENAME_MAX
];
468 DPRINT(MK_STR(_tspawnlpe
)"('%"sT
"')\n", cmdname
);
470 va_start(argp
, arg0
);
471 args
= valisttosT(arg0
, argp
, ' ');
474 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
477 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
478 envs
= argvtosT(ptr
, 0);
481 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, envs
);
494 int _tspawnvpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
496 _TCHAR pathname
[FILENAME_MAX
];
498 DPRINT(MK_STR(_tspawnvpe
)"('%"sT
"')\n", cmdname
);
500 return _tspawnve(mode
, find_execT(cmdname
, pathname
), argv
, envp
);
506 int _texecl(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
512 DPRINT(MK_STR(_texecl
)"('%"sT
"')\n", cmdname
);
514 va_start(argp
, arg0
);
515 args
= valisttosT(arg0
, argp
, ' ');
519 ret
= do_spawnT(P_OVERLAY
, cmdname
, args
, NULL
);
528 int _texecv(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
530 DPRINT(MK_STR(_texecv
)"('%"sT
"')\n", cmdname
);
531 return _tspawnv(P_OVERLAY
, cmdname
, argv
);
537 int _texecle(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
542 _TCHAR
const* const* ptr
;
545 DPRINT(MK_STR(_texecle
)"('%"sT
"')\n", cmdname
);
547 va_start(argp
, arg0
);
548 args
= valisttosT(arg0
, argp
, ' ');
551 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
554 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
555 envs
= argvtosT(ptr
, 0);
558 ret
= do_spawnT(P_OVERLAY
, cmdname
, args
, envs
);
571 int _texecve(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
573 DPRINT(MK_STR(_texecve
)"('%"sT
"')\n", cmdname
);
574 return _tspawnve(P_OVERLAY
, cmdname
, argv
, envp
);
580 int _texeclp(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
585 _TCHAR pathname
[FILENAME_MAX
];
587 DPRINT(MK_STR(_texeclp
)"('%"sT
"')\n", cmdname
);
589 va_start(argp
, arg0
);
590 args
= valisttosT(arg0
, argp
, ' ');
594 ret
= do_spawnT(P_OVERLAY
, find_execT(cmdname
, pathname
), args
, NULL
);
603 int _texecvp(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
605 DPRINT(MK_STR(_texecvp
)"('%"sT
"')\n", cmdname
);
606 return _tspawnvp(P_OVERLAY
, cmdname
, argv
);
612 int _texeclpe(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
617 _TCHAR
const* const* ptr
;
619 _TCHAR pathname
[FILENAME_MAX
];
621 DPRINT(MK_STR(_texeclpe
)"('%"sT
"')\n", cmdname
);
623 va_start(argp
, arg0
);
624 args
= valisttosT(arg0
, argp
, ' ');
627 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
630 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
631 envs
= argvtosT(ptr
, 0);
634 ret
= do_spawnT(P_OVERLAY
, find_execT(cmdname
, pathname
), args
, envs
);
647 int _texecvpe(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
649 DPRINT(MK_STR(_texecvpe
)"('%"sT
"')\n", cmdname
);
650 return _tspawnvpe(P_OVERLAY
, cmdname
, argv
, envp
);