Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprocess.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS CRT library 00003 * LICENSE: GPL (?) - See COPYING in the top level directory 00004 * FILE: lib/sdk/crt/process/process.c 00005 * PURPOSE: Process management functions 00006 * PROGRAMMERS: ??? 00007 */ 00008 00009 #include <precomp.h> 00010 #include <process.h> 00011 #include <tchar.h> 00012 #include <internal/wine/msvcrt.h> 00013 00014 #ifdef _UNICODE 00015 #define sT "S" 00016 #define find_execT find_execW 00017 #define argvtosT argvtosW 00018 #define do_spawnT do_spawnW 00019 #define valisttosT valisttosW 00020 #define extT extW 00021 #else 00022 #define sT "s" 00023 #define find_execT find_execA 00024 #define argvtosT argvtosA 00025 #define do_spawnT do_spawnA 00026 #define valisttosT valisttosA 00027 #define extT extA 00028 #endif 00029 00030 #define MK_STR(s) #s 00031 00032 int access_dirT(const _TCHAR *_path); 00033 00034 _TCHAR const* extT[] = 00035 { 00036 _T(""), 00037 _T(".bat"), 00038 _T(".cmd"), 00039 _T(".com"), 00040 _T(".exe") 00041 }; 00042 00043 const _TCHAR* find_execT(const _TCHAR* path, _TCHAR* rpath) 00044 { 00045 _TCHAR *rp; 00046 const _TCHAR *rd; 00047 unsigned int i, found = 0; 00048 00049 TRACE(MK_STR(find_execT)"('%"sT"', %x)\n", path, rpath); 00050 00051 if (path == NULL) 00052 { 00053 return NULL; 00054 } 00055 if (_tcslen(path) > FILENAME_MAX - 1) 00056 { 00057 return path; 00058 } 00059 /* copy path in rpath */ 00060 for (rd = path, rp = rpath; *rd; *rp++ = *rd++) 00061 ; 00062 *rp = 0; 00063 /* try first with the name as is */ 00064 for (i = 0; i < sizeof(extT) / sizeof(*extT); i++) 00065 { 00066 _tcscpy(rp, extT[i]); 00067 00068 TRACE("trying '%"sT"'\n", rpath); 00069 00070 if (_taccess(rpath, F_OK) == 0 && access_dirT(rpath) != 0) 00071 { 00072 found = 1; 00073 break; 00074 } 00075 } 00076 if (!found) 00077 { 00078 _TCHAR* env = _tgetenv(_T("PATH")); 00079 if (env) 00080 { 00081 _TCHAR* ep = env; 00082 while (*ep && !found) 00083 { 00084 if (*ep == ';') 00085 ep++; 00086 rp=rpath; 00087 for (; *ep && (*ep != ';'); *rp++ = *ep++) 00088 ; 00089 if (rp > rpath) 00090 { 00091 rp--; 00092 if (*rp != '/' && *rp != '\\') 00093 { 00094 *++rp = '\\'; 00095 } 00096 rp++; 00097 } 00098 for (rd=path; *rd; *rp++ = *rd++) 00099 ; 00100 for (i = 0; i < sizeof(extT) / sizeof(*extT); i++) 00101 { 00102 _tcscpy(rp, extT[i]); 00103 00104 TRACE("trying '%"sT"'\n", rpath); 00105 00106 if (_taccess(rpath, F_OK) == 0 && access_dirT(rpath) != 0) 00107 { 00108 found = 1; 00109 break; 00110 } 00111 } 00112 } 00113 } 00114 } 00115 00116 return found ? rpath : path; 00117 } 00118 00119 static _TCHAR* 00120 argvtosT(const _TCHAR* const* argv, _TCHAR delim) 00121 { 00122 int i; 00123 size_t len; 00124 _TCHAR *ptr, *str; 00125 00126 if (argv == NULL) 00127 return NULL; 00128 00129 for (i = 0, len = 0; argv[i]; i++) 00130 { 00131 len += _tcslen(argv[i]) + 1; 00132 } 00133 00134 str = ptr = (_TCHAR*) malloc((len + 1) * sizeof(_TCHAR)); 00135 if (str == NULL) 00136 return NULL; 00137 00138 for(i = 0; argv[i]; i++) 00139 { 00140 len = _tcslen(argv[i]); 00141 memcpy(ptr, argv[i], len * sizeof(_TCHAR)); 00142 ptr += len; 00143 *ptr++ = delim; 00144 } 00145 *ptr = 0; 00146 00147 return str; 00148 } 00149 00150 static _TCHAR* 00151 valisttosT(const _TCHAR* arg0, va_list alist, _TCHAR delim) 00152 { 00153 va_list alist2 = alist; 00154 _TCHAR *ptr, *str; 00155 size_t len; 00156 00157 if (arg0 == NULL) 00158 return NULL; 00159 00160 ptr = (_TCHAR*)arg0; 00161 len = 0; 00162 do 00163 { 00164 len += _tcslen(ptr) + 1; 00165 ptr = va_arg(alist, _TCHAR*); 00166 } 00167 while(ptr != NULL); 00168 00169 str = (_TCHAR*) malloc((len + 1) * sizeof(_TCHAR)); 00170 if (str == NULL) 00171 return NULL; 00172 00173 ptr = str; 00174 do 00175 { 00176 len = _tcslen(arg0); 00177 memcpy(ptr, arg0, len * sizeof(_TCHAR)); 00178 ptr += len; 00179 *ptr++ = delim; 00180 arg0 = va_arg(alist2, _TCHAR*); 00181 } 00182 while(arg0 != NULL); 00183 *ptr = 0; 00184 00185 return str; 00186 } 00187 00188 static intptr_t 00189 do_spawnT(int mode, const _TCHAR* cmdname, const _TCHAR* args, const _TCHAR* envp) 00190 { 00191 STARTUPINFO StartupInfo = {0}; 00192 PROCESS_INFORMATION ProcessInformation; 00193 // char* fmode; 00194 // HANDLE* hFile; 00195 // int i, last; 00196 BOOL bResult; 00197 DWORD dwExitCode; 00198 DWORD dwError; 00199 00200 TRACE(MK_STR(do_spawnT)"(%i,'%"sT"','%"sT"','%"sT"')",mode,cmdname,args,envp); 00201 00202 00203 if (mode != _P_NOWAIT && mode != _P_NOWAITO && mode != _P_WAIT && mode != _P_DETACH && mode != _P_OVERLAY) 00204 { 00205 _set_errno ( EINVAL ); 00206 return( -1); 00207 } 00208 00209 if (0 != _taccess(cmdname, F_OK)) 00210 { 00211 _set_errno ( ENOENT ); 00212 return(-1); 00213 } 00214 if (0 == access_dirT(cmdname)) 00215 { 00216 _set_errno ( EISDIR ); 00217 return(-1); 00218 } 00219 00220 memset (&StartupInfo, 0, sizeof(StartupInfo)); 00221 StartupInfo.cb = sizeof(StartupInfo); 00222 00223 #if 0 00224 00225 for (last = i = 0; i < FDINFO_FD_MAX; i++) 00226 { 00227 if ((void*)-1 != _get_osfhandle(i)) 00228 { 00229 last = i + 1; 00230 } 00231 } 00232 00233 if (last) 00234 { 00235 StartupInfo.cbReserved2 = sizeof(ULONG) + last * (sizeof(char) + sizeof(HANDLE)); 00236 StartupInfo.lpReserved2 = malloc(StartupInfo.cbReserved2); 00237 if (StartupInfo.lpReserved2 == NULL) 00238 { 00239 _set_errno ( ENOMEM ); 00240 return -1; 00241 } 00242 00243 *(DWORD*)StartupInfo.lpReserved2 = last; 00244 fmode = (char*)(StartupInfo.lpReserved2 + sizeof(ULONG)); 00245 hFile = (HANDLE*)(StartupInfo.lpReserved2 + sizeof(ULONG) + last * sizeof(char)); 00246 for (i = 0; i < last; i++) 00247 { 00248 int _mode = __fileno_getmode(i); 00249 HANDLE h = _get_osfhandle(i); 00250 /* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3) 00251 * is possible wrong 00252 */ 00253 if ((((ULONG)h) & 0x10000003) == 0x3 || _mode & _O_NOINHERIT || (i < 3 && mode == _P_DETACH)) 00254 { 00255 *hFile = INVALID_HANDLE_VALUE; 00256 *fmode = 0; 00257 } 00258 else 00259 { 00260 DWORD dwFlags; 00261 BOOL bFlag; 00262 bFlag = GetHandleInformation(h, &dwFlags); 00263 if (bFlag && (dwFlags & HANDLE_FLAG_INHERIT)) 00264 { 00265 *hFile = h; 00266 *fmode = (_O_ACCMODE & _mode) | (((_O_TEXT | _O_BINARY) & _mode) >> 8); 00267 } 00268 else 00269 { 00270 *hFile = INVALID_HANDLE_VALUE; 00271 *fmode = 0; 00272 } 00273 } 00274 fmode++; 00275 hFile++; 00276 } 00277 } 00278 #endif 00279 00280 create_io_inherit_block(&StartupInfo.cbReserved2, &StartupInfo.lpReserved2); 00281 00282 bResult = CreateProcess((_TCHAR *)cmdname, 00283 (_TCHAR *)args, 00284 NULL, 00285 NULL, 00286 TRUE, 00287 mode == _P_DETACH ? DETACHED_PROCESS : 0, 00288 (LPVOID)envp, 00289 NULL, 00290 &StartupInfo, 00291 &ProcessInformation); 00292 00293 if (StartupInfo.lpReserved2) 00294 { 00295 free(StartupInfo.lpReserved2); 00296 } 00297 00298 if (!bResult) 00299 { 00300 dwError = GetLastError(); 00301 ERR("%x\n", dwError); 00302 _dosmaperr(dwError); 00303 return(-1); 00304 } 00305 CloseHandle(ProcessInformation.hThread); 00306 switch(mode) 00307 { 00308 case _P_NOWAIT: 00309 case _P_NOWAITO: 00310 return((intptr_t)ProcessInformation.hProcess); 00311 case _P_OVERLAY: 00312 CloseHandle(ProcessInformation.hProcess); 00313 _exit(0); 00314 case _P_WAIT: 00315 WaitForSingleObject(ProcessInformation.hProcess, INFINITE); 00316 GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode); 00317 CloseHandle(ProcessInformation.hProcess); 00318 return( (int)dwExitCode); //CORRECT? 00319 case _P_DETACH: 00320 CloseHandle(ProcessInformation.hProcess); 00321 return( 0); 00322 } 00323 return( (intptr_t)ProcessInformation.hProcess); 00324 } 00325 00326 /* 00327 * @implemented 00328 */ 00329 intptr_t _tspawnl(int mode, const _TCHAR *cmdname, const _TCHAR* arg0, ...) 00330 { 00331 va_list argp; 00332 _TCHAR* args; 00333 intptr_t ret = -1; 00334 00335 TRACE(MK_STR(_tspawnl)"('%"sT"')\n", cmdname); 00336 00337 va_start(argp, arg0); 00338 args = valisttosT(arg0, argp, ' '); 00339 00340 if (args) 00341 { 00342 ret = do_spawnT(mode, cmdname, args, NULL); 00343 free(args); 00344 } 00345 return ret; 00346 } 00347 00348 /* 00349 * @implemented 00350 */ 00351 intptr_t _tspawnv(int mode, const _TCHAR *cmdname, const _TCHAR* const* argv) 00352 { 00353 _TCHAR* args; 00354 intptr_t ret = -1; 00355 00356 TRACE(MK_STR(_tspawnv)"('%"sT"')\n", cmdname); 00357 00358 args = argvtosT(argv, ' '); 00359 00360 if (args) 00361 { 00362 ret = do_spawnT(mode, cmdname, args, NULL); 00363 free(args); 00364 } 00365 return ret; 00366 } 00367 00368 /* 00369 * @implemented 00370 */ 00371 intptr_t _tspawnle(int mode, const _TCHAR *cmdname, const _TCHAR* arg0, ... /*, NULL, const char* const* envp*/) 00372 { 00373 va_list argp; 00374 _TCHAR* args; 00375 _TCHAR* envs; 00376 _TCHAR const * const* ptr; 00377 intptr_t ret = -1; 00378 00379 TRACE(MK_STR(_tspawnle)"('%"sT"')\n", cmdname); 00380 00381 va_start(argp, arg0); 00382 args = valisttosT(arg0, argp, ' '); 00383 do 00384 { 00385 ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*); 00386 } 00387 while (ptr != NULL); 00388 ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*); 00389 envs = argvtosT(ptr, 0); 00390 if (args) 00391 { 00392 ret = do_spawnT(mode, cmdname, args, envs); 00393 free(args); 00394 } 00395 if (envs) 00396 { 00397 free(envs); 00398 } 00399 return ret; 00400 00401 } 00402 00403 /* 00404 * @implemented 00405 */ 00406 intptr_t _tspawnve(int mode, const _TCHAR *cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp) 00407 { 00408 _TCHAR *args; 00409 _TCHAR *envs; 00410 intptr_t ret = -1; 00411 00412 TRACE(MK_STR(_tspawnve)"('%"sT"')\n", cmdname); 00413 00414 args = argvtosT(argv, ' '); 00415 envs = argvtosT(envp, 0); 00416 00417 if (args) 00418 { 00419 ret = do_spawnT(mode, cmdname, args, envs); 00420 free(args); 00421 } 00422 if (envs) 00423 { 00424 free(envs); 00425 } 00426 return ret; 00427 } 00428 00429 /* 00430 * @implemented 00431 */ 00432 intptr_t _tspawnvp(int mode, const _TCHAR* cmdname, const _TCHAR* const* argv) 00433 { 00434 _TCHAR pathname[FILENAME_MAX]; 00435 00436 TRACE(MK_STR(_tspawnvp)"('%"sT"')\n", cmdname); 00437 00438 return _tspawnv(mode, find_execT(cmdname, pathname), argv); 00439 } 00440 00441 /* 00442 * @implemented 00443 */ 00444 intptr_t _tspawnlp(int mode, const _TCHAR* cmdname, const _TCHAR* arg0, .../*, NULL*/) 00445 { 00446 va_list argp; 00447 _TCHAR* args; 00448 intptr_t ret = -1; 00449 _TCHAR pathname[FILENAME_MAX]; 00450 00451 TRACE(MK_STR(_tspawnlp)"('%"sT"')\n", cmdname); 00452 00453 va_start(argp, arg0); 00454 args = valisttosT(arg0, argp, ' '); 00455 if (args) 00456 { 00457 ret = do_spawnT(mode, find_execT(cmdname, pathname), args, NULL); 00458 free(args); 00459 } 00460 return ret; 00461 } 00462 00463 00464 /* 00465 * @implemented 00466 */ 00467 intptr_t _tspawnlpe(int mode, const _TCHAR* cmdname, const _TCHAR* arg0, .../*, NULL, const char* const* envp*/) 00468 { 00469 va_list argp; 00470 _TCHAR* args; 00471 _TCHAR* envs; 00472 _TCHAR const* const * ptr; 00473 intptr_t ret = -1; 00474 _TCHAR pathname[FILENAME_MAX]; 00475 00476 TRACE(MK_STR(_tspawnlpe)"('%"sT"')\n", cmdname); 00477 00478 va_start(argp, arg0); 00479 args = valisttosT(arg0, argp, ' '); 00480 do 00481 { 00482 ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*); 00483 } 00484 while (ptr != NULL); 00485 ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*); 00486 envs = argvtosT(ptr, 0); 00487 if (args) 00488 { 00489 ret = do_spawnT(mode, find_execT(cmdname, pathname), args, envs); 00490 free(args); 00491 } 00492 if (envs) 00493 { 00494 free(envs); 00495 } 00496 return ret; 00497 } 00498 00499 /* 00500 * @implemented 00501 */ 00502 intptr_t _tspawnvpe(int mode, const _TCHAR* cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp) 00503 { 00504 _TCHAR pathname[FILENAME_MAX]; 00505 00506 TRACE(MK_STR(_tspawnvpe)"('%"sT"')\n", cmdname); 00507 00508 return _tspawnve(mode, find_execT(cmdname, pathname), argv, envp); 00509 } 00510 00511 /* 00512 * @implemented 00513 */ 00514 intptr_t _texecl(const _TCHAR* cmdname, const _TCHAR* arg0, ...) 00515 { 00516 _TCHAR* args; 00517 va_list argp; 00518 intptr_t ret = -1; 00519 00520 TRACE(MK_STR(_texecl)"('%"sT"')\n", cmdname); 00521 00522 va_start(argp, arg0); 00523 args = valisttosT(arg0, argp, ' '); 00524 00525 if (args) 00526 { 00527 ret = do_spawnT(_P_OVERLAY, cmdname, args, NULL); 00528 free(args); 00529 } 00530 return ret; 00531 } 00532 00533 /* 00534 * @implemented 00535 */ 00536 intptr_t _texecv(const _TCHAR* cmdname, const _TCHAR* const* argv) 00537 { 00538 TRACE(MK_STR(_texecv)"('%"sT"')\n", cmdname); 00539 return _tspawnv(_P_OVERLAY, cmdname, argv); 00540 } 00541 00542 /* 00543 * @implemented 00544 */ 00545 intptr_t _texecle(const _TCHAR* cmdname, const _TCHAR* arg0, ... /*, NULL, char* const* envp */) 00546 { 00547 va_list argp; 00548 _TCHAR* args; 00549 _TCHAR* envs; 00550 _TCHAR const* const* ptr; 00551 intptr_t ret = -1; 00552 00553 TRACE(MK_STR(_texecle)"('%"sT"')\n", cmdname); 00554 00555 va_start(argp, arg0); 00556 args = valisttosT(arg0, argp, ' '); 00557 do 00558 { 00559 ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*); 00560 } 00561 while (ptr != NULL); 00562 ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*); 00563 envs = argvtosT(ptr, 0); 00564 if (args) 00565 { 00566 ret = do_spawnT(_P_OVERLAY, cmdname, args, envs); 00567 free(args); 00568 } 00569 if (envs) 00570 { 00571 free(envs); 00572 } 00573 return ret; 00574 } 00575 00576 /* 00577 * @implemented 00578 */ 00579 intptr_t _texecve(const _TCHAR* cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp) 00580 { 00581 TRACE(MK_STR(_texecve)"('%"sT"')\n", cmdname); 00582 return _tspawnve(_P_OVERLAY, cmdname, argv, envp); 00583 } 00584 00585 /* 00586 * @implemented 00587 */ 00588 intptr_t _texeclp(const _TCHAR* cmdname, const _TCHAR* arg0, ...) 00589 { 00590 _TCHAR* args; 00591 va_list argp; 00592 intptr_t ret = -1; 00593 _TCHAR pathname[FILENAME_MAX]; 00594 00595 TRACE(MK_STR(_texeclp)"('%"sT"')\n", cmdname); 00596 00597 va_start(argp, arg0); 00598 args = valisttosT(arg0, argp, ' '); 00599 00600 if (args) 00601 { 00602 ret = do_spawnT(_P_OVERLAY, find_execT(cmdname, pathname), args, NULL); 00603 free(args); 00604 } 00605 return ret; 00606 } 00607 00608 /* 00609 * @implemented 00610 */ 00611 intptr_t _texecvp(const _TCHAR* cmdname, const _TCHAR* const* argv) 00612 { 00613 TRACE(MK_STR(_texecvp)"('%"sT"')\n", cmdname); 00614 return _tspawnvp(_P_OVERLAY, cmdname, argv); 00615 } 00616 00617 /* 00618 * @implemented 00619 */ 00620 intptr_t _texeclpe(const _TCHAR* cmdname, const _TCHAR* arg0, ... /*, NULL, char* const* envp */) 00621 { 00622 va_list argp; 00623 _TCHAR* args; 00624 _TCHAR* envs; 00625 _TCHAR const* const* ptr; 00626 intptr_t ret = -1; 00627 _TCHAR pathname[FILENAME_MAX]; 00628 00629 TRACE(MK_STR(_texeclpe)"('%"sT"')\n", cmdname); 00630 00631 va_start(argp, arg0); 00632 args = valisttosT(arg0, argp, ' '); 00633 do 00634 { 00635 ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*); 00636 } 00637 while (ptr != NULL); 00638 ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*); 00639 envs = argvtosT(ptr, 0); 00640 if (args) 00641 { 00642 ret = do_spawnT(_P_OVERLAY, find_execT(cmdname, pathname), args, envs); 00643 free(args); 00644 } 00645 if (envs) 00646 { 00647 free(envs); 00648 } 00649 return ret; 00650 } 00651 00652 /* 00653 * @implemented 00654 */ 00655 intptr_t _texecvpe(const _TCHAR* cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp) 00656 { 00657 TRACE(MK_STR(_texecvpe)"('%"sT"')\n", cmdname); 00658 return _tspawnvpe(_P_OVERLAY, cmdname, argv, envp); 00659 } 00660 00661 Generated on Sat May 26 2012 04:16:10 for ReactOS by
1.7.6.1
|