From: Rolf K. <lab...@us...> - 2004-04-01 10:00:42
|
Update of /cvsroot/opengtoolkit/pipe/c_source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2168/c_source Modified Files: pipes.c Log Message: First draft of PipeOpenCmd() function Index: pipes.c =================================================================== RCS file: /cvsroot/opengtoolkit/pipe/c_source/pipes.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pipes.c 15 Mar 2004 08:04:46 -0000 1.5 --- pipes.c 1 Apr 2004 09:48:40 -0000 1.6 *************** *** 44,48 **** MgErr LibAPI PipeOpen(CStr name, uInt8 mode, uInt32 *fd); MgErr LibAPI PipeOpenCmd(CStr name, uInt8 mode, uInt32 *fdIn, uInt32 *fdOut, ! uInt32 *fdErr, uInt32 processID); MgErr LibAPI PipeClose(uInt32 fd); MgErr LibAPI PipeRead(uInt32 fd, uInt32 *bytesRead, LStrHandle data, uInt32 *eof); --- 44,48 ---- MgErr LibAPI PipeOpen(CStr name, uInt8 mode, uInt32 *fd); MgErr LibAPI PipeOpenCmd(CStr name, uInt8 mode, uInt32 *fdIn, uInt32 *fdOut, ! uInt32 *fdErr, uInt32 *processID); MgErr LibAPI PipeClose(uInt32 fd); MgErr LibAPI PipeRead(uInt32 fd, uInt32 *bytesRead, LStrHandle data, uInt32 *eof); *************** *** 50,53 **** --- 50,54 ---- #if defined(MSWin) + static MgErr CreateChildProcess(LPSTR cmdline, HANDLE *pid); static MgErr Win32ToLVErr(DWORD error); #elif defined (Unix) *************** *** 150,161 **** } ! MgErr LibAPI PipeOpenCmd(CStr name, uInt8 mode, uInt32 *fdIn, uInt32 *fdOut, uInt32 *fdErr, uInt32 processID) { MgErr err = noErr; #if defined(MSWin) ! SECURITY_ATTRIBUTES lsa = { 0 }; ! STARTUPINFO si = { 0 }; ! PROCESS_INFORMATION pi = { 0 }; #elif defined(Unix) --- 151,279 ---- } ! MgErr LibAPI PipeOpenCmd(CStr cmd, uInt8 mode, uInt32 *fdIn, uInt32 *fdOut, uInt32 *fdErr, uInt32 *processID) { MgErr err = noErr; #if defined(MSWin) ! SECURITY_ATTRIBUTES saAttr = { 0 }; ! HANDLE hSaveStdout = 0L, hChildStdoutRd = 0L, hChildStdoutWr = 0L; ! HANDLE hSaveStdin = 0L, hChildStdinRd = 0L, hChildStdinWr = 0L; ! HANDLE hSaveStderr = 0L, hChildStderrRd = 0L, hChildStderrWr = 0L; ! BOOL bError = *fdErr != FALSE; ! ! if (mode > kReadWriteMode) ! return mgArgErr; ! ! saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); ! saAttr.lpSecurityDescriptor = NULL; ! saAttr.bInheritHandle = TRUE; ! ! if (mode == kWriteMode || mode == kReadWriteMode) ! { ! /* Save the handle to the current STDOUT. */ ! hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); ! ! /* Create a pipe for the child process's STDOUT. */ ! if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) ! goto error; ! ! /* Set a write handle to the pipe to be STDOUT. */ ! if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) ! goto error; ! ! /* Create noninheritable read handle and close the inheritable read handle. */ ! if (!DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, ! GetCurrentProcess(), (HANDLE*)fdOut , 0, ! FALSE, ! DUPLICATE_SAME_ACCESS)) ! goto error; ! CloseHandle(hChildStdoutRd); ! hChildStdoutRd = 0; ! } ! ! if (mode == kReadMode || mode == kReadWriteMode) ! { ! /* Save the handle to the current STDIN. */ ! hSaveStdin = GetStdHandle(STD_INPUT_HANDLE); ! ! /* Create a pipe for the child process's STDIN. */ ! if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) ! goto error; ! ! /* Set a read handle to the pipe to be STDIN. */ ! if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd)) ! goto error; ! ! /* Duplicate the write handle to the pipe so it is not inherited. */ ! if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, ! GetCurrentProcess(), (HANDLE*)fdIn, 0, ! FALSE, ! DUPLICATE_SAME_ACCESS)) ! goto error; ! CloseHandle(hChildStdinWr); ! hChildStdinRd = 0; ! } ! ! if (bError) ! { ! /* Save the handle to the current STDERR. */ ! hSaveStderr = GetStdHandle(STD_ERROR_HANDLE); ! ! /* Create a pipe for the child process's STDERR. */ ! if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0)) ! goto error; ! ! /* Set a read handle to the pipe to be STDERR. */ ! if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrRd)) ! goto error; ! ! /* Duplicate the write handle to the pipe so it is not inherited. */ ! if (!DuplicateHandle(GetCurrentProcess(), hChildStderrWr, ! GetCurrentProcess(), (HANDLE*)fdErr, 0, ! FALSE, ! DUPLICATE_SAME_ACCESS)) ! goto error; ! CloseHandle(hChildStderrWr); ! hChildStderrRd = 0; ! } ! ! /* Now create the child process. */ ! err = CreateChildProcess(cmd, (HANDLE*)processID); ! if (err) ! goto error; ! ! /* After process creation, restore the saved STDIN and STDOUT. */ ! if (mode == kReadMode || mode == kReadWriteMode) ! if (!SetStdHandle(STD_INPUT_HANDLE, hSaveStdin)) ! goto error; ! ! if (mode == kWriteMode || mode == kReadWriteMode) ! if (!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) ! goto error; ! ! if (mode == kWriteMode || mode == kReadWriteMode) ! if (!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) ! goto error; + return noErr; + error: + if (hSaveStdout) + CloseHandle(hSaveStdout); + if (hChildStdoutRd) + CloseHandle(hChildStdoutRd); + if (hChildStdoutWr) + CloseHandle(hChildStdoutWr); + if (hSaveStdin) + CloseHandle(hSaveStdin); + if (hChildStdinRd) + CloseHandle(hChildStdinRd); + if (hChildStdinWr) + CloseHandle(hChildStdinWr); + if (hSaveStderr) + CloseHandle(hSaveStderr); + if (hChildStderrRd) + CloseHandle(hChildStderrRd); + if (hChildStderrWr) + CloseHandle(hChildStderrWr); + return dvOpenErr; #elif defined(Unix) *************** *** 272,275 **** --- 390,433 ---- #if defined(MSWin) + static MgErr CreateChildProcess(LPSTR cmdline, HANDLE *pid) + { + PROCESS_INFORMATION piProcInfo; + STARTUPINFO siStartInfo; + BOOL bFuncRetn = FALSE; + + /* Set up members of the PROCESS_INFORMATION structure. */ + ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); + + /* Set up members of the STARTUPINFO structure. */ + ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); + siStartInfo.cb = sizeof(STARTUPINFO); + + /* Create the child process. */ + bFuncRetn = CreateProcess(NULL, + cmdline, // command line + NULL, // process security attributes + NULL, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + NULL, // use parent's environment + NULL, // use parent's current directory + &siStartInfo, // STARTUPINFO pointer + &piProcInfo); // receives PROCESS_INFORMATION + + if (bFuncRetn == 0) + { + return mFullErr; + } + else + { + if (pid) + *pid = piProcInfo.hProcess; + else + CloseHandle(piProcInfo.hProcess); + CloseHandle(piProcInfo.hThread); + return noErr; + } + } + struct errentry { DWORD oscode; /* OS return value */ |