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
23 #define find_execT find_execA
24 #define argvtosT argvtosA
25 #define do_spawnT do_spawnA
26 #define valisttosT valisttosA
32 _TCHAR
const* extT
[] =
41 const _TCHAR
* find_execT(const _TCHAR
* path
, _TCHAR
* rpath
)
45 unsigned int i
, found
= 0;
47 TRACE(MK_STR(find_execT
)"('%"sT
"', %x)\n", path
, rpath
);
53 if (_tcslen(path
) > FILENAME_MAX
- 1)
57 /* copy path in rpath */
58 for (rd
= path
, rp
= rpath
; *rd
; *rp
++ = *rd
++)
61 /* try first with the name as is */
62 for (i
= 0; i
< sizeof(extT
) / sizeof(*extT
); i
++)
66 TRACE("trying '%"sT
"'\n", rpath
);
68 if (_taccess(rpath
, F_OK
) == 0 && access_dirT(rpath
) != 0)
76 _TCHAR
* env
= _tgetenv(_T("PATH"));
85 for (; *ep
&& (*ep
!= ';'); *rp
++ = *ep
++)
90 if (*rp
!= '/' && *rp
!= '\\')
96 for (rd
=path
; *rd
; *rp
++ = *rd
++)
98 for (i
= 0; i
< sizeof(extT
) / sizeof(*extT
); i
++)
100 _tcscpy(rp
, extT
[i
]);
102 TRACE("trying '%"sT
"'\n", rpath
);
104 if (_taccess(rpath
, F_OK
) == 0 && access_dirT(rpath
) != 0)
114 return found
? rpath
: path
;
118 argvtosT(const _TCHAR
* const* argv
, _TCHAR delim
)
126 for (i
= 0, len
= 0; argv
[i
]; i
++)
128 len
+= _tcslen(argv
[i
]) + 1;
131 str
= ptr
= (_TCHAR
*) malloc(len
+ 1);
135 for(i
= 0; argv
[i
]; i
++)
137 len
= _tcslen(argv
[i
]);
138 memcpy(ptr
, argv
[i
], len
* sizeof(_TCHAR
));
148 valisttosT(const _TCHAR
* arg0
, va_list alist
, _TCHAR delim
)
150 va_list alist2
= alist
;
161 len
+= _tcslen(ptr
) + 1;
162 ptr
= va_arg(alist
, _TCHAR
*);
166 str
= (_TCHAR
*) malloc(len
+ 1);
174 memcpy(ptr
, arg0
, len
* sizeof(_TCHAR
));
177 arg0
= va_arg(alist2
, _TCHAR
*);
186 do_spawnT(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* args
, const _TCHAR
* envp
)
188 STARTUPINFO StartupInfo
= {0};
189 PROCESS_INFORMATION ProcessInformation
;
197 TRACE(MK_STR(do_spawnT
)"(%i,'%"sT
"','%"sT
"','%"sT
"')",mode
,cmdname
,args
,envp
);
200 if (mode
!= _P_NOWAIT
&& mode
!= _P_NOWAITO
&& mode
!= _P_WAIT
&& mode
!= _P_DETACH
&& mode
!= _P_OVERLAY
)
202 __set_errno ( EINVAL
);
206 if (0 != _taccess(cmdname
, F_OK
))
208 __set_errno ( ENOENT
);
211 if (0 == access_dirT(cmdname
))
213 __set_errno ( EISDIR
);
217 memset (&StartupInfo
, 0, sizeof(StartupInfo
));
218 StartupInfo
.cb
= sizeof(StartupInfo
);
222 for (last
= i
= 0; i
< FDINFO_FD_MAX
; i
++)
224 if ((void*)-1 != _get_osfhandle(i
))
232 StartupInfo
.cbReserved2
= sizeof(ULONG
) + last
* (sizeof(char) + sizeof(HANDLE
));
233 StartupInfo
.lpReserved2
= malloc(StartupInfo
.cbReserved2
);
234 if (StartupInfo
.lpReserved2
== NULL
)
236 __set_errno ( ENOMEM
);
240 *(DWORD
*)StartupInfo
.lpReserved2
= last
;
241 fmode
= (char*)(StartupInfo
.lpReserved2
+ sizeof(ULONG
));
242 hFile
= (HANDLE
*)(StartupInfo
.lpReserved2
+ sizeof(ULONG
) + last
* sizeof(char));
243 for (i
= 0; i
< last
; i
++)
245 int _mode
= __fileno_getmode(i
);
246 HANDLE h
= _get_osfhandle(i
);
247 /* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
250 if ((((ULONG
)h
) & 0x10000003) == 0x3 || _mode
& _O_NOINHERIT
|| (i
< 3 && mode
== _P_DETACH
))
252 *hFile
= INVALID_HANDLE_VALUE
;
259 bFlag
= GetHandleInformation(h
, &dwFlags
);
260 if (bFlag
&& (dwFlags
& HANDLE_FLAG_INHERIT
))
263 *fmode
= (_O_ACCMODE
& _mode
) | (((_O_TEXT
| _O_BINARY
) & _mode
) >> 8);
267 *hFile
= INVALID_HANDLE_VALUE
;
277 create_io_inherit_block(&StartupInfo
.cbReserved2
, &StartupInfo
.lpReserved2
);
279 bResult
= CreateProcess((_TCHAR
*)cmdname
,
284 mode
== _P_DETACH
? DETACHED_PROCESS
: 0,
288 &ProcessInformation
);
290 if (StartupInfo
.lpReserved2
)
292 free(StartupInfo
.lpReserved2
);
297 dwError
= GetLastError();
298 ERR("%x\n", dwError
);
299 __set_errno(dwError
);
302 CloseHandle(ProcessInformation
.hThread
);
307 return((intptr_t)ProcessInformation
.hProcess
);
309 CloseHandle(ProcessInformation
.hProcess
);
312 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
313 GetExitCodeProcess(ProcessInformation
.hProcess
, &dwExitCode
);
314 CloseHandle(ProcessInformation
.hProcess
);
315 return( (int)dwExitCode
); //CORRECT?
317 CloseHandle(ProcessInformation
.hProcess
);
320 return( (intptr_t)ProcessInformation
.hProcess
);
326 intptr_t _tspawnl(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ...)
332 TRACE(MK_STR(_tspawnl
)"('%"sT
"')\n", cmdname
);
334 va_start(argp
, arg0
);
335 args
= valisttosT(arg0
, argp
, ' ');
339 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
348 intptr_t _tspawnv(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
)
353 TRACE(MK_STR(_tspawnv
)"('%"sT
"')\n", cmdname
);
355 args
= argvtosT(argv
, ' ');
359 ret
= do_spawnT(mode
, cmdname
, args
, NULL
);
368 intptr_t _tspawnle(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* arg0
, ... /*, NULL, const char* const* envp*/)
373 _TCHAR
const * const* ptr
;
376 TRACE(MK_STR(_tspawnle
)"('%"sT
"')\n", cmdname
);
378 va_start(argp
, arg0
);
379 args
= valisttosT(arg0
, argp
, ' ');
382 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
385 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
386 envs
= argvtosT(ptr
, 0);
389 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
403 intptr_t _tspawnve(int mode
, const _TCHAR
*cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
409 TRACE(MK_STR(_tspawnve
)"('%"sT
"')\n", cmdname
);
411 args
= argvtosT(argv
, ' ');
412 envs
= argvtosT(envp
, 0);
416 ret
= do_spawnT(mode
, cmdname
, args
, envs
);
429 intptr_t _tspawnvp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
431 _TCHAR pathname
[FILENAME_MAX
];
433 TRACE(MK_STR(_tspawnvp
)"('%"sT
"')\n", cmdname
);
435 return _tspawnv(mode
, find_execT(cmdname
, pathname
), argv
);
441 intptr_t _tspawnlp(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL*/)
446 _TCHAR pathname
[FILENAME_MAX
];
448 TRACE(MK_STR(_tspawnlp
)"('%"sT
"')\n", cmdname
);
450 va_start(argp
, arg0
);
451 args
= valisttosT(arg0
, argp
, ' ');
454 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, NULL
);
464 intptr_t _tspawnlpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* arg0
, .../*, NULL, const char* const* envp*/)
469 _TCHAR
const* const * ptr
;
471 _TCHAR pathname
[FILENAME_MAX
];
473 TRACE(MK_STR(_tspawnlpe
)"('%"sT
"')\n", cmdname
);
475 va_start(argp
, arg0
);
476 args
= valisttosT(arg0
, argp
, ' ');
479 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
482 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
483 envs
= argvtosT(ptr
, 0);
486 ret
= do_spawnT(mode
, find_execT(cmdname
, pathname
), args
, envs
);
499 intptr_t _tspawnvpe(int mode
, const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
501 _TCHAR pathname
[FILENAME_MAX
];
503 TRACE(MK_STR(_tspawnvpe
)"('%"sT
"')\n", cmdname
);
505 return _tspawnve(mode
, find_execT(cmdname
, pathname
), argv
, envp
);
511 intptr_t _texecl(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
517 TRACE(MK_STR(_texecl
)"('%"sT
"')\n", cmdname
);
519 va_start(argp
, arg0
);
520 args
= valisttosT(arg0
, argp
, ' ');
524 ret
= do_spawnT(P_OVERLAY
, cmdname
, args
, NULL
);
533 intptr_t _texecv(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
535 TRACE(MK_STR(_texecv
)"('%"sT
"')\n", cmdname
);
536 return _tspawnv(P_OVERLAY
, cmdname
, argv
);
542 intptr_t _texecle(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
547 _TCHAR
const* const* ptr
;
550 TRACE(MK_STR(_texecle
)"('%"sT
"')\n", cmdname
);
552 va_start(argp
, arg0
);
553 args
= valisttosT(arg0
, argp
, ' ');
556 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
559 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
560 envs
= argvtosT(ptr
, 0);
563 ret
= do_spawnT(P_OVERLAY
, cmdname
, args
, envs
);
576 intptr_t _texecve(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
578 TRACE(MK_STR(_texecve
)"('%"sT
"')\n", cmdname
);
579 return _tspawnve(P_OVERLAY
, cmdname
, argv
, envp
);
585 intptr_t _texeclp(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ...)
590 _TCHAR pathname
[FILENAME_MAX
];
592 TRACE(MK_STR(_texeclp
)"('%"sT
"')\n", cmdname
);
594 va_start(argp
, arg0
);
595 args
= valisttosT(arg0
, argp
, ' ');
599 ret
= do_spawnT(P_OVERLAY
, find_execT(cmdname
, pathname
), args
, NULL
);
608 intptr_t _texecvp(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
)
610 TRACE(MK_STR(_texecvp
)"('%"sT
"')\n", cmdname
);
611 return _tspawnvp(P_OVERLAY
, cmdname
, argv
);
617 intptr_t _texeclpe(const _TCHAR
* cmdname
, const _TCHAR
* arg0
, ... /*, NULL, char* const* envp */)
622 _TCHAR
const* const* ptr
;
624 _TCHAR pathname
[FILENAME_MAX
];
626 TRACE(MK_STR(_texeclpe
)"('%"sT
"')\n", cmdname
);
628 va_start(argp
, arg0
);
629 args
= valisttosT(arg0
, argp
, ' ');
632 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
635 ptr
= (_TCHAR
const* const*)va_arg(argp
, _TCHAR
*);
636 envs
= argvtosT(ptr
, 0);
639 ret
= do_spawnT(P_OVERLAY
, find_execT(cmdname
, pathname
), args
, envs
);
652 intptr_t _texecvpe(const _TCHAR
* cmdname
, const _TCHAR
* const* argv
, const _TCHAR
* const* envp
)
654 TRACE(MK_STR(_texecvpe
)"('%"sT
"')\n", cmdname
);
655 return _tspawnvpe(P_OVERLAY
, cmdname
, argv
, envp
);