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
;
208 TRACE(MK_STR(do_spawnT
)"(%i,'%"sT
"','%"sT
"','%"sT
"')",mode
,cmdname
,args
,envp
);
211 if (mode
!= _P_NOWAIT
&& mode
!= _P_NOWAITO
&& mode
!= _P_WAIT
&& mode
!= _P_DETACH
&& mode
!= _P_OVERLAY
)
213 _set_errno ( EINVAL
);
217 if (0 != _taccess(cmdname
, F_OK
))
219 _set_errno ( ENOENT
);
222 if (0 == access_dirT(cmdname
))
224 _set_errno ( EISDIR
);
228 memset (&StartupInfo
, 0, sizeof(StartupInfo
));
229 StartupInfo
.cb
= sizeof(StartupInfo
);
233 for (last
= i
= 0; i
< FDINFO_FD_MAX
; i
++)
235 if ((void*)-1 != _get_osfhandle(i
))
243 StartupInfo
.cbReserved2
= sizeof(ULONG
) + last
* (sizeof(char) + sizeof(HANDLE
));
244 StartupInfo
.lpReserved2
= malloc(StartupInfo
.cbReserved2
);
245 if (StartupInfo
.lpReserved2
== NULL
)
247 _set_errno ( ENOMEM
);
251 *(DWORD
*)StartupInfo
.lpReserved2
= last
;
252 fmode
= (char*)(StartupInfo
.lpReserved2
+ sizeof(ULONG
));
253 hFile
= (HANDLE
*)(StartupInfo
.lpReserved2
+ sizeof(ULONG
) + last
* sizeof(char));
254 for (i
= 0; i
< last
; i
++)
256 int _mode
= __fileno_getmode(i
);
257 HANDLE h
= _get_osfhandle(i
);
258 /* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
261 if ((((ULONG
)h
) & 0x10000003) == 0x3 || _mode
& _O_NOINHERIT
|| (i
< 3 && mode
== _P_DETACH
))
263 *hFile
= INVALID_HANDLE_VALUE
;
270 bFlag
= GetHandleInformation(h
, &dwFlags
);
271 if (bFlag
&& (dwFlags
& HANDLE_FLAG_INHERIT
))
274 *fmode
= (_O_ACCMODE
& _mode
) | (((_O_TEXT
| _O_BINARY
) & _mode
) >> 8);
278 *hFile
= INVALID_HANDLE_VALUE
;
288 create_io_inherit_block(&StartupInfo
.cbReserved2
, &StartupInfo
.lpReserved2
);
290 if (mode
== _P_DETACH
)
292 dwFlags
|= DETACHED_PROCESS
;
295 dwFlags
|= CREATE_UNICODE_ENVIRONMENT
;
298 bResult
= CreateProcess((_TCHAR
*)cmdname
,
307 &ProcessInformation
);
309 if (StartupInfo
.lpReserved2
)
311 free(StartupInfo
.lpReserved2
);
316 dwError
= GetLastError();
317 ERR("%x\n", dwError
);
321 CloseHandle(ProcessInformation
.hThread
);
326 return((intptr_t)ProcessInformation
.hProcess
);
328 CloseHandle(ProcessInformation
.hProcess
);
331 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
332 GetExitCodeProcess(ProcessInformation
.hProcess
, &dwExitCode
);
333 CloseHandle(ProcessInformation
.hProcess
);
334 return( (int)dwExitCode
); //CORRECT?
336 CloseHandle(ProcessInformation
.hProcess
);
339 return( (intptr_t)ProcessInformation
.hProcess
);
345 intptr_t _tspawnl(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ...)
351 TRACE(MK_STR(_tspawnl
)"('%"sT
"')\n", cmdname
);
353 va_start(argp
, arg0
);
354 args
= valisttosT(arg0
, argp
, ' ');
358 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
368 intptr_t _tspawnv(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
)
373 TRACE(MK_STR(_tspawnv
)"('%"sT
"')\n", cmdname
);
375 args
= argvtosT(argv
, ' ');
379 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
388 intptr_t _tspawnle(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ... /*, NULL, const char* const* envp*/)
393 _TCHAR
const * const* ptr
;
396 TRACE(MK_STR(_tspawnle
)"('%"sT
"')\n", cmdname
);
398 va_start(argp
, arg0
);
399 args
= valisttosT(arg0
, argp
, ' ');
402 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
405 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
406 envs
= argvtosT(ptr
, 0);
409 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
424 intptr_t _tspawnve(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
430 TRACE(MK_STR(_tspawnve
)"('%"sT
"')\n", cmdname
);
432 args
= argvtosT(argv
, ' ');
433 envs
= argvtosT(envp
, 0);
437 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
450 intptr_t _tspawnvp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
452 _TCHAR pathname
[FILENAME_MAX
];
454 TRACE(MK_STR(_tspawnvp
)"('%"sT
"')\n", cmdname
);
456 return _tspawnv(mode
, find_execT(cmdname
, pathname
), argv
);
462 intptr_t _tspawnlp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL*/)
467 _TCHAR pathname
[FILENAME_MAX
];
469 TRACE(MK_STR(_tspawnlp
)"('%"sT
"')\n", cmdname
);
471 va_start(argp
, arg0
);
472 args
= valisttosT(arg0
, argp
, ' ');
475 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, NULL
);
486 intptr_t _tspawnlpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL, const char* const* envp*/)
491 _TCHAR
const* const * ptr
;
493 _TCHAR pathname
[FILENAME_MAX
];
495 TRACE(MK_STR(_tspawnlpe
)"('%"sT
"')\n", cmdname
);
497 va_start(argp
, arg0
);
498 args
= valisttosT(arg0
, argp
, ' ');
501 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
504 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
505 envs
= argvtosT(ptr
, 0);
508 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, envs
);
522 intptr_t _tspawnvpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
524 _TCHAR pathname
[FILENAME_MAX
];
526 TRACE(MK_STR(_tspawnvpe
)"('%"sT
"')\n", cmdname
);
528 return _tspawnve(mode
, find_execT(cmdname
, pathname
), argv
, envp
);
534 intptr_t _texecl(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
540 TRACE(MK_STR(_texecl
)"('%"sT
"')\n", cmdname
);
542 va_start(argp
, arg0
);
543 args
= valisttosT(arg0
, argp
, ' ');
547 ret
= do_spawnT(_P_OVERLAY
, cmdname
, args
, NULL
);
557 intptr_t _texecv(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
559 TRACE(MK_STR(_texecv
)"('%"sT
"')\n", cmdname
);
560 return _tspawnv(_P_OVERLAY
, cmdname
, argv
);
566 intptr_t _texecle(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
571 _TCHAR
const* const* ptr
;
574 TRACE(MK_STR(_texecle
)"('%"sT
"')\n", cmdname
);
576 va_start(argp
, arg0
);
577 args
= valisttosT(arg0
, argp
, ' ');
580 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
583 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
584 envs
= argvtosT(ptr
, 0);
587 ret
= do_spawnT(_P_OVERLAY
, cmdname
, args
, envs
);
601 intptr_t _texecve(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
603 TRACE(MK_STR(_texecve
)"('%"sT
"')\n", cmdname
);
604 return _tspawnve(_P_OVERLAY
, cmdname
, argv
, envp
);
610 intptr_t _texeclp(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
615 _TCHAR pathname
[FILENAME_MAX
];
617 TRACE(MK_STR(_texeclp
)"('%"sT
"')\n", cmdname
);
619 va_start(argp
, arg0
);
620 args
= valisttosT(arg0
, argp
, ' ');
624 ret
= do_spawnT(_P_OVERLAY
, find_execT(cmdname
, pathname
), args
, NULL
);
634 intptr_t _texecvp(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
636 TRACE(MK_STR(_texecvp
)"('%"sT
"')\n", cmdname
);
637 return _tspawnvp(_P_OVERLAY
, cmdname
, argv
);
643 intptr_t _texeclpe(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
648 _TCHAR
const* const* ptr
;
650 _TCHAR pathname
[FILENAME_MAX
];
652 TRACE(MK_STR(_texeclpe
)"('%"sT
"')\n", cmdname
);
654 va_start(argp
, arg0
);
655 args
= valisttosT(arg0
, argp
, ' ');
658 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
661 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
662 envs
= argvtosT(ptr
, 0);
665 ret
= do_spawnT(_P_OVERLAY
, find_execT(cmdname
, pathname
), args
, envs
);
679 intptr_t _texecvpe(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
681 TRACE(MK_STR(_texecvpe
)"('%"sT
"')\n", cmdname
);
682 return _tspawnvpe(_P_OVERLAY
, cmdname
, argv
, envp
);