2 * PROJECT: ReactOS CRT library
3 * LICENSE: GPL (?) - See COPYING in the top level directory
4 * FILE: lib/sdk/crt/process/process.c
5 * PURPOSE: Process management functions
12 #include <internal/wine/msvcrt.h>
16 #define find_execT find_execW
17 #define argvtosT argvtosW
18 #define do_spawnT do_spawnW
19 #define valisttosT valisttosW
21 #define access_dirT access_dirW
24 #define find_execT find_execA
25 #define argvtosT argvtosA
26 #define do_spawnT do_spawnA
27 #define valisttosT valisttosA
29 #define access_dirT access_dirA
34 int access_dirT(const _TCHAR
*_path
);
36 _TCHAR
const* extT
[] =
45 const _TCHAR
* find_execT(const _TCHAR
* path
, _TCHAR
* rpath
)
49 unsigned int i
, found
= 0;
51 TRACE(MK_STR(find_execT
)"('%"sT
"', %x)\n", path
, rpath
);
57 if (_tcslen(path
) > FILENAME_MAX
- 1)
61 /* copy path in rpath */
62 for (rd
= path
, rp
= rpath
; *rd
; *rp
++ = *rd
++)
65 /* try first with the name as is */
66 for (i
= 0; i
< sizeof(extT
) / sizeof(*extT
); i
++)
70 TRACE("trying '%"sT
"'\n", rpath
);
72 if (_taccess(rpath
, F_OK
) == 0 && access_dirT(rpath
) != 0)
80 _TCHAR
* env
= _tgetenv(_T("PATH"));
89 for (; *ep
&& (*ep
!= ';'); *rp
++ = *ep
++)
94 if (*rp
!= '/' && *rp
!= '\\')
100 for (rd
=path
; *rd
; *rp
++ = *rd
++)
102 for (i
= 0; i
< sizeof(extT
) / sizeof(*extT
); i
++)
104 _tcscpy(rp
, extT
[i
]);
106 TRACE("trying '%"sT
"'\n", rpath
);
108 if (_taccess(rpath
, F_OK
) == 0 && access_dirT(rpath
) != 0)
118 return found
? rpath
: path
;
122 argvtosT(const _TCHAR
* const* argv
, _TCHAR delim
)
131 for (i
= 0, len
= 0; argv
[i
]; i
++)
133 len
+= _tcslen(argv
[i
]) + 1;
136 str
= ptr
= (_TCHAR
*) malloc((len
+ 1) * sizeof(_TCHAR
));
140 for(i
= 0; argv
[i
]; i
++)
142 len
= _tcslen(argv
[i
]);
143 memcpy(ptr
, argv
[i
], len
* sizeof(_TCHAR
));
153 valisttosT(const _TCHAR
* arg0
, va_list alist
, _TCHAR delim
)
162 va_copy(alist2
, alist
);
167 len
+= _tcslen(ptr
) + 1;
168 ptr
= va_arg(alist
, _TCHAR
*);
172 str
= (_TCHAR
*) malloc((len
+ 1) * sizeof(_TCHAR
));
183 memcpy(ptr
, arg0
, len
* sizeof(_TCHAR
));
186 arg0
= va_arg(alist2
, _TCHAR
*);
196 do_spawnT(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* args
, const _TCHAR
* envp
)
198 STARTUPINFO StartupInfo
= {0};
199 PROCESS_INFORMATION ProcessInformation
;
207 TRACE(MK_STR(do_spawnT
)"(%i,'%"sT
"','%"sT
"','%"sT
"')",mode
,cmdname
,args
,envp
);
210 if (mode
!= _P_NOWAIT
&& mode
!= _P_NOWAITO
&& mode
!= _P_WAIT
&& mode
!= _P_DETACH
&& mode
!= _P_OVERLAY
)
212 _set_errno ( EINVAL
);
216 if (0 != _taccess(cmdname
, F_OK
))
218 _set_errno ( ENOENT
);
221 if (0 == access_dirT(cmdname
))
223 _set_errno ( EISDIR
);
227 memset (&StartupInfo
, 0, sizeof(StartupInfo
));
228 StartupInfo
.cb
= sizeof(StartupInfo
);
232 for (last
= i
= 0; i
< FDINFO_FD_MAX
; i
++)
234 if ((void*)-1 != _get_osfhandle(i
))
242 StartupInfo
.cbReserved2
= sizeof(ULONG
) + last
* (sizeof(char) + sizeof(HANDLE
));
243 StartupInfo
.lpReserved2
= malloc(StartupInfo
.cbReserved2
);
244 if (StartupInfo
.lpReserved2
== NULL
)
246 _set_errno ( ENOMEM
);
250 *(DWORD
*)StartupInfo
.lpReserved2
= last
;
251 fmode
= (char*)(StartupInfo
.lpReserved2
+ sizeof(ULONG
));
252 hFile
= (HANDLE
*)(StartupInfo
.lpReserved2
+ sizeof(ULONG
) + last
* sizeof(char));
253 for (i
= 0; i
< last
; i
++)
255 int _mode
= __fileno_getmode(i
);
256 HANDLE h
= _get_osfhandle(i
);
257 /* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
260 if ((((ULONG
)h
) & 0x10000003) == 0x3 || _mode
& _O_NOINHERIT
|| (i
< 3 && mode
== _P_DETACH
))
262 *hFile
= INVALID_HANDLE_VALUE
;
269 bFlag
= GetHandleInformation(h
, &dwFlags
);
270 if (bFlag
&& (dwFlags
& HANDLE_FLAG_INHERIT
))
273 *fmode
= (_O_ACCMODE
& _mode
) | (((_O_TEXT
| _O_BINARY
) & _mode
) >> 8);
277 *hFile
= INVALID_HANDLE_VALUE
;
287 create_io_inherit_block(&StartupInfo
.cbReserved2
, &StartupInfo
.lpReserved2
);
289 bResult
= CreateProcess((_TCHAR
*)cmdname
,
294 mode
== _P_DETACH
? DETACHED_PROCESS
: 0,
298 &ProcessInformation
);
300 if (StartupInfo
.lpReserved2
)
302 free(StartupInfo
.lpReserved2
);
307 dwError
= GetLastError();
308 ERR("%x\n", dwError
);
312 CloseHandle(ProcessInformation
.hThread
);
317 return((intptr_t)ProcessInformation
.hProcess
);
319 CloseHandle(ProcessInformation
.hProcess
);
322 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
323 GetExitCodeProcess(ProcessInformation
.hProcess
, &dwExitCode
);
324 CloseHandle(ProcessInformation
.hProcess
);
325 return( (int)dwExitCode
); //CORRECT?
327 CloseHandle(ProcessInformation
.hProcess
);
330 return( (intptr_t)ProcessInformation
.hProcess
);
336 intptr_t _tspawnl(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ...)
342 TRACE(MK_STR(_tspawnl
)"('%"sT
"')\n", cmdname
);
344 va_start(argp
, arg0
);
345 args
= valisttosT(arg0
, argp
, ' ');
349 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
359 intptr_t _tspawnv(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
)
364 TRACE(MK_STR(_tspawnv
)"('%"sT
"')\n", cmdname
);
366 args
= argvtosT(argv
, ' ');
370 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
379 intptr_t _tspawnle(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ... /*, NULL, const char* const* envp*/)
384 _TCHAR
const * const* ptr
;
387 TRACE(MK_STR(_tspawnle
)"('%"sT
"')\n", cmdname
);
389 va_start(argp
, arg0
);
390 args
= valisttosT(arg0
, argp
, ' ');
393 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
396 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
397 envs
= argvtosT(ptr
, 0);
400 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
415 intptr_t _tspawnve(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
421 TRACE(MK_STR(_tspawnve
)"('%"sT
"')\n", cmdname
);
423 args
= argvtosT(argv
, ' ');
424 envs
= argvtosT(envp
, 0);
428 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
441 intptr_t _tspawnvp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
443 _TCHAR pathname
[FILENAME_MAX
];
445 TRACE(MK_STR(_tspawnvp
)"('%"sT
"')\n", cmdname
);
447 return _tspawnv(mode
, find_execT(cmdname
, pathname
), argv
);
453 intptr_t _tspawnlp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL*/)
458 _TCHAR pathname
[FILENAME_MAX
];
460 TRACE(MK_STR(_tspawnlp
)"('%"sT
"')\n", cmdname
);
462 va_start(argp
, arg0
);
463 args
= valisttosT(arg0
, argp
, ' ');
466 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, NULL
);
477 intptr_t _tspawnlpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL, const char* const* envp*/)
482 _TCHAR
const* const * ptr
;
484 _TCHAR pathname
[FILENAME_MAX
];
486 TRACE(MK_STR(_tspawnlpe
)"('%"sT
"')\n", cmdname
);
488 va_start(argp
, arg0
);
489 args
= valisttosT(arg0
, argp
, ' ');
492 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
495 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
496 envs
= argvtosT(ptr
, 0);
499 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, envs
);
513 intptr_t _tspawnvpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
515 _TCHAR pathname
[FILENAME_MAX
];
517 TRACE(MK_STR(_tspawnvpe
)"('%"sT
"')\n", cmdname
);
519 return _tspawnve(mode
, find_execT(cmdname
, pathname
), argv
, envp
);
525 intptr_t _texecl(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
531 TRACE(MK_STR(_texecl
)"('%"sT
"')\n", cmdname
);
533 va_start(argp
, arg0
);
534 args
= valisttosT(arg0
, argp
, ' ');
538 ret
= do_spawnT(_P_OVERLAY
, cmdname
, args
, NULL
);
548 intptr_t _texecv(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
550 TRACE(MK_STR(_texecv
)"('%"sT
"')\n", cmdname
);
551 return _tspawnv(_P_OVERLAY
, cmdname
, argv
);
557 intptr_t _texecle(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
562 _TCHAR
const* const* ptr
;
565 TRACE(MK_STR(_texecle
)"('%"sT
"')\n", cmdname
);
567 va_start(argp
, arg0
);
568 args
= valisttosT(arg0
, argp
, ' ');
571 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
574 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
575 envs
= argvtosT(ptr
, 0);
578 ret
= do_spawnT(_P_OVERLAY
, cmdname
, args
, envs
);
592 intptr_t _texecve(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
594 TRACE(MK_STR(_texecve
)"('%"sT
"')\n", cmdname
);
595 return _tspawnve(_P_OVERLAY
, cmdname
, argv
, envp
);
601 intptr_t _texeclp(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
606 _TCHAR pathname
[FILENAME_MAX
];
608 TRACE(MK_STR(_texeclp
)"('%"sT
"')\n", cmdname
);
610 va_start(argp
, arg0
);
611 args
= valisttosT(arg0
, argp
, ' ');
615 ret
= do_spawnT(_P_OVERLAY
, find_execT(cmdname
, pathname
), args
, NULL
);
625 intptr_t _texecvp(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
627 TRACE(MK_STR(_texecvp
)"('%"sT
"')\n", cmdname
);
628 return _tspawnvp(_P_OVERLAY
, cmdname
, argv
);
634 intptr_t _texeclpe(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
639 _TCHAR
const* const* ptr
;
641 _TCHAR pathname
[FILENAME_MAX
];
643 TRACE(MK_STR(_texeclpe
)"('%"sT
"')\n", cmdname
);
645 va_start(argp
, arg0
);
646 args
= valisttosT(arg0
, argp
, ' ');
649 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
652 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
653 envs
= argvtosT(ptr
, 0);
656 ret
= do_spawnT(_P_OVERLAY
, find_execT(cmdname
, pathname
), args
, envs
);
670 intptr_t _texecvpe(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
672 TRACE(MK_STR(_texecvpe
)"('%"sT
"')\n", cmdname
);
673 return _tspawnvpe(_P_OVERLAY
, cmdname
, argv
, envp
);