|
From: Andre R. <and...@us...> - 2006-03-09 22:19:58
|
Update of /cvsroot/frontierkernel/Frontier/Common/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4451/Common/source Modified Files: sysshellcall.c Log Message: Extended winshellcall code to deal with the situation when the COMSPEC environment variable is not defined or does not point to an existing file. Index: sysshellcall.c =================================================================== RCS file: /cvsroot/frontierkernel/Frontier/Common/source/sysshellcall.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** sysshellcall.c 9 Mar 2006 18:37:00 -0000 1.3 --- sysshellcall.c 9 Mar 2006 22:19:54 -0000 1.4 *************** *** 32,35 **** --- 32,36 ---- #include "strings.h" #include "threads.h" + #include "error.h" #include "sysshellcall.h" *************** *** 158,162 **** 7.0b51: Call the UNIX popen command, which evaluates a string as if it were typed ! ôn the command line. Verb: sys.unixShellCommand. Code adapted by Timothy Paustian from Apple sample code. This routine by PBS. --- 159,163 ---- 7.0b51: Call the UNIX popen command, which evaluates a string as if it were typed ! on the command line. Verb: sys.unixShellCommand. Code adapted by Timothy Paustian from Apple sample code. This routine by PBS. *************** *** 207,210 **** --- 208,263 ---- #ifdef WIN95VERSION + static boolean getenvironmentvariable (char *name, boolean flwinerror, Handle *hresult) { + + /* + 2006-03-09 aradke: utility function for getting a Windows environment variable + as a handle without terminating nil char. + */ + + Handle h; + long res; + + res = GetEnvironmentVariable (name, nil, 0); + + if (res == 0) { + if (flwinerror) + winerror (); + return (false); + } + + if (!newclearhandle (res, &h)) + return (false); + + lockhandle (h); + + res = GetEnvironmentVariable (name, *h, res); + + unlockhandle (h); + + if (!sethandlesize (h, res)) { /*drop trailing nil char*/ + disposehandle (h); + return (false); + } + + *hresult = h; + + return (true); + } /*getenvironmentvariable*/ + + + static boolean cmdshellexists (Handle hshell) { + + DWORD attr; + + lockhandle (hshell); + + attr = GetFileAttributes (*hshell); + + unlockhandle (hshell); + + return (attr != INVALID_FILE_ATTRIBUTES); + } /*cmdshellexists*/ + + static boolean getcmdshell (Handle *hshell) { *************** *** 216,275 **** */ ! Handle h; ! long res; ! ! res = GetEnvironmentVariable("COMSPEC", nil, 0); ! ! if (res > 0) { /*var exists, allocate buffer and get its value*/ ! ! if (!newclearhandle (res, &h)) ! return (false); ! ! lockhandle (h); ! res = GetEnvironmentVariable("COMSPEC", *h, res); /*FIXME: check result, dispose h*/ ! unlockhandle (h); ! assert (res == gethandlesize (h) - 1); ! ! sethandlesize (h, res); /*drop trailing nil char*/ } else { ! OSVERSIONINFO osinfo; ! bigstring bs; ! osinfo.dwOSVersionInfoSize = sizeof (osinfo); ! ! GetVersionEx (&osinfo); /*FIXME: check result, report error*/ ! if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { ! copystring ("\x0b" "command.com", bs); /*Win95/98/ME: actual DOS command interpreter*/ } ! else { ! copystring ("\x07" "cmd.exe", bs); /*WinNT and successors: DOS emulation*/ } ! ! if (!newtexthandle (bs, &h)) return (false); ! } - *hshell = h; - return (true); ! } /*getcmdshell*/ ! boolean runcmdshell (Handle hshell, Handle hcommand, HANDLE *hout) { /* 2006-03-09 aradke: launch the command shell as a child process. TO DO: - check length of hcmdline < MAX_PATH - - make sure handles in processinfo struct are closed - - before creating process, check whether hshell exists - - if we can't access hshell, do a search path lookup - - proper error checking and reporting */ --- 269,419 ---- */ ! OSVERSIONINFO osinfo; ! bigstring bs; ! ! if (getenvironmentvariable ("COMSPEC", false, hshell)) ! return (true); ! osinfo.dwOSVersionInfoSize = sizeof (osinfo); ! if (GetVersionEx (&osinfo) == nil) { ! winerror (); ! return (false); ! } ! if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { ! copystring ("\x0b" "command.com", bs); /*Win95/98/ME: actual DOS command interpreter*/ } else { ! copystring ("\x07" "cmd.exe", bs); /*WinNT and successors: DOS emulation*/ ! } ! return (newtexthandle (bs, hshell)); ! } /*getcmdshell*/ ! ! #define CHDOUBLEQUOTE '"' ! #define CHSEMICOLON ';' ! #define CHBACKSLASH '\\' ! ! ! static boolean getnextpath (Handle hpath, long *ixstart, Handle *hitem) { ! ! Handle h; ! handlestream s; ! char ch; ! ! openhandlestream (hpath, &s); ! s.pos = *ixstart; ! ! /*first pass: locate end of next path item*/ ! ! skiphandlestreamchars (&s, CHSEMICOLON); /*ignore leading semicolons*/ ! *ixstart = s.pos; ! ! while (!athandlestreameof (&s)) { ! ! ch = nexthandlestreamcharacter (&s); ! ! if (ch == CHSEMICOLON) { ! break; } ! else if (ch == CHDOUBLEQUOTE) { ! s.pos++; ! seekhandlestreamchar (&s, CHDOUBLEQUOTE); /*skip over contents of doublequotes*/ } ! ! s.pos++; ! }/*while*/ ! ! /*extract item*/ ! ! if (!loadfromhandletohandle (s.data, ixstart, s.pos - *ixstart, false, &h)) ! return (false); ! ! /*second pass: remove included doublequotes*/ ! ! openhandlestream (h, &s); ! ! while (true) { ! ! seekhandlestreamchar (&s, CHDOUBLEQUOTE); ! ! if (athandlestreameof (&s)) ! break; ! ! pullfromhandlestream (&s, 1, nil); ! }/*while*/ ! ! if (lasthandlestreamcharacter (&s) != CHBACKSLASH) ! if (!writehandlestreamchar (&s, CHBACKSLASH)) { ! disposehandlestream (&s); return (false); ! } ! ! *hitem = closehandlestream (&s); return (true); ! } /*getnextpath*/ ! ! ! static boolean searchcmdpath (Handle *hshell) { + /* + 2006-03-09 aradke: get the PATH environment variable and parse it. + see if the command shell is located in any of the directories. + caller is responsible for disposing hshell. + + TO DO: + - check length of hshell < MAX_PATH + */ + + Handle hpath = nil; + Handle h = nil; + long ix = 0; ! /*obtain path environment variable*/ ! ! if (!getenvironmentvariable ("PATH", true, &hpath)) ! return (false); ! ! /*parse path*/ ! ! while (getnextpath (hpath, &ix, &h)) { ! ! if (!pushhandle (*hshell, h)) ! goto exit; ! ! if (!enlargehandle (h, 1, "\0")) ! goto exit; ! ! if (cmdshellexists (h)) { ! disposehandle (*hshell); ! *hshell = h; ! return (true); ! } ! ! disposehandle (h); ! }/*while*/ ! ! /*not found*/ ! ! oserror (ERROR_FILE_NOT_FOUND); ! ! exit: ! disposehandle (hpath); ! ! return (false); ! } /*searchcmdpath*/ ! ! ! static boolean runcmdshell (Handle hshell, Handle hcommand, HANDLE *hout) { /* 2006-03-09 aradke: launch the command shell as a child process. + we consume hshell, but caller is responsible for closing hout if we return true. TO DO: - check length of hcmdline < MAX_PATH */ *************** *** 280,287 **** HANDLE hpiperead = nil; HANDLE hpipewrite = nil; - DWORD attr; boolean fl; /*create pipe for reading from command shell*/ clearbytes (&securityinfo, sizeof (securityinfo)); securityinfo.nLength = sizeof (securityinfo); --- 424,431 ---- HANDLE hpiperead = nil; HANDLE hpipewrite = nil; boolean fl; /*create pipe for reading from command shell*/ + clearbytes (&securityinfo, sizeof (securityinfo)); securityinfo.nLength = sizeof (securityinfo); *************** *** 289,298 **** securityinfo.bInheritHandle = true; ! fl = CreatePipe (&hpiperead, &hpipewrite, &securityinfo, nil); ! ! if (!fl) ! goto exit; ! SetHandleInformation (hpiperead, HANDLE_FLAG_INHERIT, 0); /*init structs for creating process*/ --- 433,441 ---- securityinfo.bInheritHandle = true; ! if (!CreatePipe (&hpiperead, &hpipewrite, &securityinfo, nil)) ! goto error; ! if (!SetHandleInformation (hpiperead, HANDLE_FLAG_INHERIT, 0)) ! goto error; /*init structs for creating process*/ *************** *** 324,336 **** /*check whether command shell can be accessed*/ ! lockhandle (hshell); ! ! attr = GetFileAttributes(*hshell); ! ! unlockhandle (hshell); ! ! if (attr == INVALID_FILE_ATTRIBUTES) ! goto exit; /*not found, try searching PATH for command shell?*/ ! /*create command shell process*/ --- 467,475 ---- /*check whether command shell can be accessed*/ ! if (!cmdshellexists (hshell)) { ! if (!searchcmdpath (&hshell)) /*do a search path lookup*/ ! goto exit; ! } ! /*create command shell process*/ *************** *** 356,372 **** if (!fl) ! goto exit; ! CloseHandle (hpipewrite); /*inherited by child process*/ CloseHandle (processinfo.hProcess); CloseHandle (processinfo.hThread); disposehandle (hcmdline); *hout = hpiperead; return (true); ! ! exit: if (!hpiperead) CloseHandle (hpiperead); --- 495,516 ---- if (!fl) ! goto error; ! CloseHandle (hpipewrite); /*now inherited by child process*/ ! CloseHandle (processinfo.hProcess); CloseHandle (processinfo.hThread); disposehandle (hcmdline); + disposehandle (hshell); *hout = hpiperead; return (true); ! ! error: ! winerror (); /*note fall through*/ ! ! exit: /*error is already set*/ if (!hpiperead) CloseHandle (hpiperead); *************** *** 376,379 **** --- 520,524 ---- disposehandle (hcmdline); + disposehandle (hshell); return (false); *************** *** 381,389 **** ! boolean readcmdresult (HANDLE hread, Handle hreturn) { ! char buf [1024]; long ct = 0; boolean fl; while (true) { --- 526,540 ---- ! static boolean readcmdresult (HANDLE hread, Handle hreturn) { ! ! /* ! 2006-03-09 aradke: read data from pipe until eof. ! we close our end of the pipe (hread) whether we succeed or not. ! */ ! char buf[1024]; long ct = 0; boolean fl; + DWORD err = 0; while (true) { *************** *** 393,412 **** fl = ReadFile (hread, buf, sizeof (buf), &ct, nil); ! grabthreadglobals (); ! if (!fl) /*an error occurred*/ ! break; ! if (fl && (ct == 0)) /*end of file*/ break; ! if (ct > 0) ! if (!enlargehandle (hreturn, ct, buf)) break; } /*while*/ CloseHandle (hread); ! return (true); } /*readcmdresult*/ --- 544,577 ---- fl = ReadFile (hread, buf, sizeof (buf), &ct, nil); ! if (!fl) ! err = GetLastError (); ! grabthreadglobals (); ! if (fl && (ct == 0)) /*regular end of file*/ break; + + if (!fl) { + + if (err == ERROR_BROKEN_PIPE) + fl = true; /*ignore broken pipe*/ + else + oserror (err); + + break; + } ! if (ct > 0) { ! ! fl = enlargehandle (hreturn, ct, buf); ! ! if (!fl) break; + } } /*while*/ CloseHandle (hread); ! return (fl); } /*readcmdresult*/ *************** *** 425,445 **** if (!getcmdshell (&hshell)) ! goto exit; if (!runcmdshell (hshell, hcommand, &hread)) ! goto exit; if (!readcmdresult (hread, hreturn)) ! goto exit; ! ! disposehandle (hshell); return (true); - - exit: - - disposehandle (hshell); - - return (false); } /*winshellcall*/ --- 590,602 ---- if (!getcmdshell (&hshell)) ! return (false); if (!runcmdshell (hshell, hcommand, &hread)) ! return (false); if (!readcmdresult (hread, hreturn)) ! return (false); return (true); } /*winshellcall*/ *************** *** 460,464 **** FILE *f; ! char buf [1024]; long ct = 0; --- 617,621 ---- FILE *f; ! char buf[1024]; long ct = 0; |