void nt_execve_wrapped(char *prog, char**args, char**envir ) { STARTUPINFO si; PROCESS_INFORMATION pi; BOOL bRet; DWORD type=0; char *argv0; char **savedargs = args; unsigned int cmdsize,cmdlen; char *cmdstr ,*cmdend; // int rc=0; // unused variable int retries=0; int is_winnt; int hasdot=0; char myself[512]; memset(&si,0,sizeof(si)); /* * This memory is not freed because we are exec()ed and will * not be alive long. */ /* This version avoids realloc in concat_args_and_quote, so it should be a little bit safer */ /* cmdsize = 65500; * cmdstr= heap_alloc(cmdsize); */ cmdsize = MAX_PATH << 2; cmdstr= heap_alloc(MAX_PATH<<2); is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS); /* replace /bin/sh with myself to be executed */ if( strcmp(prog, "/bin/sh") == 0 ) { if (GetModuleFileName(GetModuleHandle(NULL),myself,512) <= 512) { prog = myself; } } cmdlen = copy_quote_and_fix_slashes(prog,cmdstr,&hasdot); cmdend = cmdstr + cmdlen; *cmdend = 0; if (!is_winnt) { argv0 = NULL; goto win95_directly_here; } else { argv0 = heap_alloc(MAX_PATH); wsprintf(argv0,"%s",prog); } retry: bRet=GetBinaryType(argv0,&type); if (is_winnt && !bRet ) { /* Don't append .EXE if it could be a script file */ if (GetLastError() == ERROR_BAD_EXE_FORMAT) { try_shell_ex(args,1); errno = ENOEXEC; return; } else if (retries) { /* If argv[0] got parsed as \\foo (stupid paths with '/' as one * of the components will do it,) and if argv[1] is not the same, * then this is not a real UNC name. * In other cases, argv[0] and argv[1] here must be the same * anyway. -amol 5/1/6/98 */ if ( ( (*prog == '\\') ||(*prog == '/') ) && ( (prog[1] == '\\') ||(prog[1] == '/') ) && ((*args[0] == *prog) && (args[0][1] == prog[1])) && (!args[1]) ) try_shell_ex(args,1); errno = ENOENT; } if (retries > 2) { return; } if (retries == 0) { wsprintf(argv0,"%s.EXE",prog); retries++; } else if (prog[0] == '\\' && retries == 1) { char ptr[80]; if(GetEnvironmentVariable("ZSHROOT",ptr,80)) { wsprintf(argv0,"%s%s",ptr,prog); } retries++; } else if (prog[0] == '\\' && retries == 2) { char ptr[80]; if(GetEnvironmentVariable("ZSHROOT",ptr,80)) { wsprintf(argv0,"%s%s.EXE",ptr,prog); } retries++; } else retries += 2; goto retry; } else if (bRet && retries > 0) { //re-fix argv0 cmdlen = copy_quote_and_fix_slashes(argv0,cmdstr,&hasdot); cmdend = cmdstr + cmdlen; *cmdend = 0; } win95_directly_here: si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = (HANDLE)_get_osfhandle(0); si.hStdOutput = (HANDLE)_get_osfhandle(1); si.hStdError = (HANDLE)_get_osfhandle(2); *args++; // ignore argv[0]; concat_args_and_quote(args,&cmdstr,&cmdlen,&cmdend,&cmdsize); *cmdend = 0; if (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS) { if (!SetConsoleCtrlHandler(NULL,FALSE)) { errno = ENOENT; } } fix_path_for_child(); if (cmdlen < 1000) dprintf("argv0 %s cmdstr %s\n",argv0,cmdstr); if (!CreateProcess(argv0, cmdstr, NULL, NULL, TRUE, // need this for redirecting std handles 0, NULL,//envcrap, NULL, &si, &pi) ) { if (GetLastError() == ERROR_BAD_EXE_FORMAT) { try_shell_ex(savedargs,1); errno = ENOEXEC; } else if (GetLastError() == ERROR_INVALID_PARAMETER) { /* exceeded command line */ errno = ENAMETOOLONG; } else errno = ENOENT; } else { errno= 0; // { DWORD exitcode=0; int gui_app = 0; if (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS) { SetConsoleCtrlHandler(NULL,TRUE); } if (isset(WINNTWAITFORGUIAPPS)) gui_app = 0; else if (is_winnt) gui_app = is_gui(argv0); else gui_app = is_9x_gui(prog); if (!gui_app) { WaitForSingleObject(pi.hProcess,INFINITE); } (void)GetExitCodeProcess(pi.hProcess,&exitcode); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); ExitProcess(exitcode); } } }
void nt_execve(char *prog, char**args, char**envir ) { STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE htemp; BOOL bRet; DWORD type=0; DWORD dwCreationflags; unsigned int priority; char *argv0; char *cmdstr, *cmdend ; char *originalPtr; unsigned int cmdsize,cmdlen; char *p2; char **savedargs; int retries=0; int hasdot =0; int is_winnt ; memset(&si,0,sizeof(si)); savedargs = args; /* * This memory is not freed because we are exec()ed and will * not be alive long. */ originalPtr = cmdstr= heap_alloc(MAX_PATH<<2); is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS); cmdsize = MAX_PATH<<2; p2 = cmdstr; cmdlen = 0; cmdlen += copy_quote_and_fix_slashes(prog,cmdstr,&hasdot); p2 += cmdlen; /* If the command was not quoted , skip initial character we left for quote */ if (*cmdstr != '"') { *cmdstr = 'A'; cmdstr++; cmdsize--; } *p2 = 0; cmdend = p2; if (!is_winnt){ argv0 = NULL; goto win95_directly_here; } else { argv0 = heap_alloc(MAX_PATH); /* not freed */ wsprintf(argv0,"%s",prog); } retry: bRet=GetBinaryType(argv0,&type); dprintf("binary type for %s is %d\n",argv0,bRet); // // For NT, append .EXE and retry // if (is_winnt && !bRet ) { /* Don't append .EXE if it could be a script file */ if (GetLastError() == ERROR_BAD_EXE_FORMAT){ errno = ENOEXEC; if (!__nt_only_start_exes) try_shell_ex(args,1,FALSE); //can't throw on error return; } else if ( retries ){ if ( ( (argv0[0] == '\\') ||(argv0[0] == '/') ) && ( (argv0[1] == '\\') ||(argv0[1] == '/') ) && (!args[1]) ) if (!__nt_only_start_exes) try_shell_ex(args,1,FALSE); errno = ENOENT; } if (retries > 1){ return; } // Try uppercase once and then lower case // if (!retries) wsprintf(argv0,"%s.exe",prog); else wsprintf(argv0,"%s.EXE",prog); /* fix for clearcase */ retries++; goto retry; } win95_directly_here: si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; htemp= (HANDLE)_get_osfhandle(0); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdInput,0,TRUE,DUPLICATE_SAME_ACCESS); htemp= (HANDLE)_get_osfhandle(1); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdOutput,0,TRUE,DUPLICATE_SAME_ACCESS); htemp= (HANDLE)_get_osfhandle(2); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdError,0,TRUE,DUPLICATE_SAME_ACCESS); *args++; // the first arg is the command dprintf("nt_execve calling c_a_a_q"); if(!concat_args_and_quote(args,&originalPtr,&cmdstr,&cmdlen,&cmdend, &cmdsize)) { dprintf("concat_args_and_quote failed\n"); heap_free(originalPtr); errno = ENOMEM; goto fail_return; } *cmdend = 0; dwCreationflags = GetPriorityClass(GetCurrentProcess()); if (__nt_child_nohupped) { dwCreationflags |= DETACHED_PROCESS; } priority = GetThreadPriority(GetCurrentThread()); (void)fix_path_for_child(); if (is_winnt) dwCreationflags |= CREATE_SUSPENDED; re_cp: dprintf("argv0 %s cmdstr %s\n",argv0,cmdstr); bRet = CreateProcessA(argv0, cmdstr, NULL, NULL, TRUE, // need this for redirecting std handles dwCreationflags, NULL, NULL, &si, &pi); if (!bRet){ if (GetLastError() == ERROR_BAD_EXE_FORMAT) { if (!__nt_only_start_exes) try_shell_ex(savedargs,1,FALSE); errno = ENOEXEC; } else if (GetLastError() == ERROR_INVALID_PARAMETER) { /* can't get invalid parameter, so this must be * the case when we exceed the command length limit. */ errno = ENAMETOOLONG; } else { errno = ENOENT; } if (!is_winnt && !hasdot) { //append '.' to the end if needed lstrcat(cmdstr,"."); hasdot=1; goto re_cp; } } else{ int gui_app ; char guivar[50]; if (GetEnvironmentVariable("TCSH_NOASYNCGUI",guivar,50)) gui_app=0; else { if (is_winnt || hasdot) gui_app= is_gui(argv0); else gui_app = is_9x_gui(prog); } if (is_winnt && !SetThreadPriority(pi.hThread,priority) ) { priority =GetLastError(); } if (is_winnt) ResumeThread(pi.hThread); errno= 0; if (__nt_really_exec||__nt_child_nohupped || gui_app){ ExitProcess(0); } else { DWORD exitcode=0; WaitForSingleObject(pi.hProcess,INFINITE); (void)GetExitCodeProcess(pi.hProcess,&exitcode); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); /* * If output was redirected to /dev/clipboard, * we need to close the pipe handles */ if (is_dev_clipboard_active) { CloseHandle((HANDLE)_get_osfhandle(0)); CloseHandle((HANDLE)_get_osfhandle(1)); CloseHandle((HANDLE)_get_osfhandle(2)); CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); CloseHandle(si.hStdError); WaitForSingleObject(ghdevclipthread,60*1000); } ExitProcess(exitcode); } } fail_return: CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); CloseHandle(si.hStdError); return; }