|
From: Andre R. <and...@us...> - 2006-03-10 13:43:20
|
Update of /cvsroot/frontierkernel/Frontier/Common/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21680/Common/source Modified Files: sysshellcall.c Log Message: winshellcall now optionally also reads from the shell's stderr and returns its exit code. Index: sysshellcall.c =================================================================== RCS file: /cvsroot/frontierkernel/Frontier/Common/source/sysshellcall.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** sysshellcall.c 10 Mar 2006 09:59:55 -0000 1.5 --- sysshellcall.c 10 Mar 2006 13:43:17 -0000 1.6 *************** *** 444,448 **** ! static boolean runcmdshell (Handle hshell, Handle hcommand, HANDLE *hout) { /* --- 444,448 ---- ! static boolean runcmdshell (Handle hshell, Handle hcommand, HANDLE *hprocess, HANDLE *hout, HANDLE *herr) { /* *************** *** 455,463 **** STARTUPINFO startupinfo; PROCESS_INFORMATION processinfo; ! HANDLE hpiperead = nil; ! HANDLE hpipewrite = nil; boolean fl; ! /*create pipe for reading from command shell*/ clearbytes (&securityinfo, sizeof (securityinfo)); --- 455,467 ---- STARTUPINFO startupinfo; PROCESS_INFORMATION processinfo; ! HANDLE houtread = nil; ! HANDLE houtwrite = nil; ! HANDLE herrread = nil; ! HANDLE herrwrite = nil; boolean fl; ! *hprocess = nil; ! ! /*create pipes for reading from command shell*/ clearbytes (&securityinfo, sizeof (securityinfo)); *************** *** 466,475 **** 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*/ --- 470,495 ---- securityinfo.bInheritHandle = true; ! if (hout) { /*caller interested in stdout*/ + if (!CreatePipe (&houtread, &houtwrite, &securityinfo, nil)) + goto error; + + if (!SetHandleInformation (houtread, HANDLE_FLAG_INHERIT, 0)) + goto error; + } + else + houtwrite = GetStdHandle (STD_OUTPUT_HANDLE); + + if (herr) { /*caller interested in stderr*/ + + if (!CreatePipe (&herrread, &herrwrite, &securityinfo, nil)) + goto error; + + if (!SetHandleInformation (herrread, HANDLE_FLAG_INHERIT, 0)) + goto error; + } + else + herrwrite = GetStdHandle (STD_ERROR_HANDLE); + /*init structs for creating process*/ *************** *** 478,483 **** startupinfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; startupinfo.hStdInput = GetStdHandle (STD_INPUT_HANDLE); ! startupinfo.hStdOutput = hpipewrite; ! startupinfo.hStdError = GetStdHandle (STD_ERROR_HANDLE); startupinfo.wShowWindow = SW_HIDE; --- 498,503 ---- startupinfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; startupinfo.hStdInput = GetStdHandle (STD_INPUT_HANDLE); ! startupinfo.hStdOutput = houtwrite; ! startupinfo.hStdError = herrwrite; startupinfo.wShowWindow = SW_HIDE; *************** *** 530,536 **** goto error; ! CloseHandle (hpipewrite); /*now inherited by child process*/ ! ! CloseHandle (processinfo.hProcess); CloseHandle (processinfo.hThread); --- 550,556 ---- goto error; ! CloseHandle (houtwrite); /*now inherited by child process*/ ! CloseHandle (herrwrite); ! CloseHandle (processinfo.hThread); *************** *** 538,542 **** disposehandle (hshell); ! *hout = hpiperead; return (true); --- 558,568 ---- disposehandle (hshell); ! *hprocess = processinfo.hProcess; ! ! if (hout) ! *hout = houtread; ! ! if (herr) ! *herr = herrread; return (true); *************** *** 546,555 **** exit: /*error is already set*/ ! if (!hpiperead) ! CloseHandle (hpiperead); ! if (!hpipewrite) ! CloseHandle (hpipewrite); disposehandle (hcmdline); disposehandle (hshell); --- 572,587 ---- exit: /*error is already set*/ ! if (hout && !houtread) ! CloseHandle (houtread); ! if (hout && !houtwrite) ! CloseHandle (houtwrite); + if (herr && !herrread) + CloseHandle (herrread); + + if (herr && !herrwrite) + CloseHandle (herrwrite); + disposehandle (hcmdline); disposehandle (hshell); *************** *** 559,608 **** ! 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) { ! releasethreadglobals (); ! 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); --- 591,677 ---- ! static boolean readcmdpipe (HANDLE hpipe, Handle hdata, boolean *flreadmore) { /* ! 2006-03-10 aradke: read from pipe if data is available */ ! DWORD ctavail, ctread; ! DWORD err; ! if (!PeekNamedPipe (hpipe, nil, nil, nil, &ctavail, nil)) ! goto error; ! ! if (ctavail > 0) { ! long oldsize, newsize; ! oldsize = gethandlesize (hdata); ! newsize = oldsize + ctavail; ! if (!sethandlesize (hdata, newsize)) { /*memory error*/ ! *flreadmore = false; ! return (false); ! } ! ! if (!ReadFile (hpipe, &((*hdata)[oldsize]), ctavail, &ctread, nil)) /*should not block*/ ! goto error; ! } ! ! return (true); ! error: ! ! *flreadmore = false; ! ! err = GetLastError (); ! ! if (err == ERROR_BROKEN_PIPE) ! return (true); ! ! oserror (err); ! ! return (false); ! }/*readcmpipe*/ ! ! ! static boolean readcmdresult (HANDLE houtread, HANDLE herrread, Handle houttext, Handle herrtext) { ! ! /* ! 2006-03-09 aradke: read data from pipe until eof. ! we close our end of the pipe (hread) whether we succeed or not. ! */ ! ! boolean flreadout = (houttext != nil); ! boolean flreaderr = (herrtext != nil); ! boolean fl = true; ! ! while (flreadout || flreaderr) { ! if (flreadout) { ! ! fl = readcmdpipe (houtread, houttext, &flreadout); ! if (!fl) ! break; /*error occurred*/ } ! if (flreaderr) { ! ! fl = readcmdpipe (herrread, herrtext, &flreaderr); ! if (!fl) ! break; /*error occurred*/ } + + langbackgroundtask (true); /*resting*/ } /*while*/ ! if (houtread) ! CloseHandle (houtread); ! ! if (herrread) ! CloseHandle (herrread); return (fl); *************** *** 610,614 **** ! boolean winshellcall (Handle hcommand, Handle hreturn) { /* --- 679,715 ---- ! static boolean getcmdexitcode (Handle hprocess, long *status) { ! ! /* ! 2006-03-10 aradke: wait for child process to exit, then get its exit code ! */ ! ! DWORD res; ! boolean fl = true; ! ! *status = 0; ! ! releasethreadglobals (); ! ! res = WaitForSingleObject (hprocess, INFINITE); ! ! grabthreadglobals (); ! ! if (res != WAIT_OBJECT_0) ! goto exit; ! ! fl = GetExitCodeProcess (hprocess, status); ! ! if (!fl) ! winerror (); ! ! exit: ! CloseHandle (hprocess); ! ! return (fl); ! } /*getcmdexitcode*/ ! ! ! boolean winshellcall (Handle hcommand, Handle houttext, Handle herrtext, long *exitcode) { /* *************** *** 617,634 **** this implementation relies on the win32 api only and does not require popen etc to be available in the c runtime library. */ Handle hshell = nil; ! HANDLE hread; if (!getcmdshell (&hshell)) return (false); ! if (!runcmdshell (hshell, hcommand, &hread)) /*consumes hshell*/ return (false); ! if (!readcmdresult (hread, hreturn)) /*consumes hread*/ return (false); ! return (true); } /*winshellcall*/ --- 718,750 ---- this implementation relies on the win32 api only and does not require popen etc to be available in the c runtime library. + + 2006-03-10 aradke: also read stderr of child process and get its exit code. + caller owns houttext (previously hreturn) and herrtext. if either is nil, + don't create and read respective pipe. */ Handle hshell = nil; ! HANDLE hprocess = nil; ! HANDLE hout = nil; ! HANDLE herr = nil; if (!getcmdshell (&hshell)) return (false); ! if (!runcmdshell (hshell, hcommand, &hprocess, ! ((houttext != nil) ? &hout : nil), ! ((herrtext != nil) ? &herr : nil))) /*consumes hshell*/ return (false); ! if (!readcmdresult (hout, herr, houttext, herrtext)) { /*consumes hout and herr*/ ! CloseHandle (hprocess); return (false); ! } ! ! if (exitcode == nil) ! CloseHandle (hprocess); ! else if (!getcmdexitcode (hprocess, exitcode)) /*consumes hprocess*/ ! return (false); ! return (true); } /*winshellcall*/ |