From: Rolf K. <lab...@us...> - 2005-06-28 00:14:51
|
Update of /cvsroot/opengtoolkit/pipe/c_source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18993/c_source Modified Files: pipes.c Log Message: Made Linux part of code look more like what it is going to be. Refactored Windows code to make it somewhat easier to read. Index: pipes.c =================================================================== RCS file: /cvsroot/opengtoolkit/pipe/c_source/pipes.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pipes.c 13 Jun 2005 08:48:35 -0000 1.13 --- pipes.c 28 Jun 2005 00:14:37 -0000 1.14 *************** *** 33,37 **** #define LibAPI __declspec(dllexport) __cdecl #else ! #define LibAPI static #endif --- 33,37 ---- #define LibAPI __declspec(dllexport) __cdecl #else ! #define LibAPI __declspec(dllimport) __cdecl #endif *************** *** 50,56 **** #if defined(MSWin) ! static MgErr CreateChildProcess(LPSTR cmdline, HANDLE stdIn, HANDLE stdOut, HANDLE stdErr, DWORD *pid); static MgErr Win32ToLVErr(DWORD error); #elif defined (Unix) static MgErr UnixToLVErr(int32 errno); #elif defined (Mac) --- 50,67 ---- #if defined(MSWin) ! #define STANDARD_IN STD_INPUT_HANDLE ! #define STANDARD_OUT STD_OUTPUT_HANDLE ! #define STANDARD_ERR STD_ERROR_HANDLE ! typedef HANDLE std_handle; ! typedef HANDLE pipe_handle; static MgErr Win32ToLVErr(DWORD error); #elif defined (Unix) + #define STANDARD_IN 0 + #define STANDARD_OUT 1 + #define STANDARD_ERR 2 + + typedef struct file_ref std_handle; + typedef int pipe_handle; + static MgErr UnixToLVErr(int32 errno); #elif defined (Mac) *************** *** 58,61 **** --- 69,77 ---- #endif + static MgErr RedirectStandardIO(int32 type, std_handle *stdIO, pipe_handle *rmpipe, uInt32 *lvpipe); + static MgErr RestoreStandardIO(int32 type, std_handle *stdIO, pipe_handle rmpipe, uInt32 *lvpipe, MgErr err); + static MgErr CreateChildProcess(LPSTR cmdline, pipe_handle stdIn, pipe_handle stdOut, pipe_handle stdErr, uInt32 *pid); + + MgErr LibAPI PipeOpen(CStr name, uInt16 mode, uInt32 *fd) { *************** *** 64,67 **** --- 80,86 ---- HANDLE handle; DWORD dwMode; + #elif defined(Unix) + mode_t mode; + #endif DebugBreaking(); *************** *** 70,73 **** --- 89,93 ---- return mgArgErr; + #if defined(MSWin) if (WaitNamedPipe(name, 1000)) { *************** *** 116,124 **** #elif defined(Unix) - mode_t mode; - - if (mode > kWriteMode) - return mgArgErr; - switch (mode) { --- 136,139 ---- *************** *** 161,169 **** MgErr err = dvOpenErr; #if defined(MSWin) - BOOL ret; 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; if ((mode > kReadWriteMode) || --- 176,187 ---- MgErr err = dvOpenErr; #if defined(MSWin) SECURITY_ATTRIBUTES saAttr = { 0 }; ! HANDLE hSaveStdout = 0L, hChildStdout = 0L; ! HANDLE hSaveStdin = 0L, hChildStdin = 0L; ! HANDLE hSaveStderr = 0L, hChildStderr = 0L; ! #elif defined(Unix) ! std_handle hSaveStdout = 0L, hSaveStdin = 0L, hSaveStderr = 0L; ! pipe_handle hChildStdout = 0L, hChildStdin = 0L, hChildStderr = 0L; ! #endif if ((mode > kReadWriteMode) || *************** *** 174,203 **** DebugBreaking(); - saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); - saAttr.lpSecurityDescriptor = NULL; - saAttr.bInheritHandle = TRUE; - 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. */ ! ret = CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0); ! if (ret) ! { ! /* Set the read handle to the pipe to be STDIN. */ ! ret = SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd); ! if (ret) ! { ! /* Duplicate the write handle to the pipe so it is not inherited. */ ! ret = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, ! GetCurrentProcess(), (HANDLE*)fdIn, 0, ! FALSE, DUPLICATE_SAME_ACCESS); ! } ! CloseHandle(hChildStdinWr); ! } ! ! if (!ret) goto out; } --- 192,199 ---- DebugBreaking(); if (mode == kReadMode || mode == kReadWriteMode) { ! err = RedirectStandardIO(STANDARD_IN, &hSaveStdin, &hChildStdin, fdIn); ! if (err) goto out; } *************** *** 205,228 **** 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. */ ! ret = CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0); ! if (ret) ! { ! /* Set the write handle to the pipe to be STDOUT. */ ! ret = SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr); ! if (ret) ! { ! /* Create noninheritable read handle and close the inheritable read handle. */ ! ret = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, ! GetCurrentProcess(), (HANDLE*)fdOut, 0, ! FALSE, DUPLICATE_SAME_ACCESS); ! } ! CloseHandle(hChildStdoutRd); ! } ! ! if (!ret) goto out; } --- 201,206 ---- if (mode == kWriteMode || mode == kReadWriteMode) { ! err = RedirectStandardIO(STANDARD_OUT, &hSaveStdout, &hChildStdout, fdOut); ! if (err) goto out; } *************** *** 230,262 **** if (fdErr && *fdErr) { ! /* Save the handle to the current STDERR. */ ! hSaveStderr = GetStdHandle(STD_ERROR_HANDLE); ! ! /* Create a pipe for the child process's STDERR. */ ! ret = CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0); ! if (ret) ! { ! /* Set the write handle to the pipe to be STDERR. */ ! ret = SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr); ! if (ret) ! { ! /* Duplicate the read handle to the pipe so it is not inherited. */ ! ret = DuplicateHandle(GetCurrentProcess(), hChildStderrRd, ! GetCurrentProcess(), (HANDLE*)fdErr, 0, ! FALSE, DUPLICATE_SAME_ACCESS); ! } ! CloseHandle(hChildStderrRd); ! } ! ! if (!ret) goto out; } else { ! hChildStderrWr = GetStdHandle(STD_ERROR_HANDLE); } ! /* Now create the child process. */ ! err = CreateChildProcess(cmd, hChildStdinRd, hChildStdoutWr, hChildStderrWr, processID); out: --- 208,222 ---- if (fdErr && *fdErr) { ! err = RedirectStandardIO(STANDARD_ERR, &hSaveStderr, &hChildStderr, fdErr); ! if (err) goto out; } else { ! hChildStderr = GetStdHandle(STD_ERROR_HANDLE); } ! /* Now create the child process. */ ! err = CreateChildProcess(cmd, hChildStdin, hChildStdout, hChildStderr, processID); out: *************** *** 265,327 **** if (mode == kReadMode || mode == kReadWriteMode) { ! if (hChildStdinRd) ! CloseHandle(hChildStdinRd); ! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin); ! } if (mode == kWriteMode || mode == kReadWriteMode) { ! if (hChildStdoutWr) ! CloseHandle(hChildStdoutWr); ! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout); } if (fdErr && *fdErr) { ! if (hChildStderrWr) ! CloseHandle(hChildStderrWr); ! SetStdHandle(STD_ERROR_HANDLE, hSaveStderr); ! } ! ! if (err) ! { ! if (fdIn && *fdIn) ! CloseHandle(*(HANDLE*)fdIn); ! if (fdOut && *fdOut) ! CloseHandle(*(HANDLE*)fdOut); ! if (fdErr && *fdErr) ! CloseHandle(*(HANDLE*)fdErr); ! } ! #elif defined(Unix) ! char *pmode; ! pipe_t handle; ! ! if (mode > kWriteMode) ! return mgArgErr; ! ! switch (mode) ! { ! case kReadMode: ! pMode = "r"; ! break; ! case kWriteMode: ! pMode = "w"; ! break; ! } ! ! /* Attempt to create the named pipe */ ! handle = popen(name, pMode); ! if (handle <= 0) ! { ! err = UnixToLVErr(errno); ! *fd = 0; ! } ! else ! { ! *fd = handle; } - #else - err = mgNotImplementd: - #endif return err; } --- 225,240 ---- if (mode == kReadMode || mode == kReadWriteMode) { ! RestoreStandardIO(STANDARD_IN, &hSaveStdin, hChildStdin, fdIn, err); ! } if (mode == kWriteMode || mode == kReadWriteMode) { ! RestoreStandardIO(STANDARD_OUT, &hSaveStdout, hChildStdout, fdOut, err); } if (fdErr && *fdErr) { ! RestoreStandardIO(STANDARD_ERR, &hSaveStderr, hChildStderr, fdErr, err); } return err; } *************** *** 339,343 **** #elif defined(Unix) ! if (close((pipe_t)fd) < 0) err = UnixToLVErr(errno); #else --- 252,256 ---- #elif defined(Unix) ! if (close(fd) < 0) err = UnixToLVErr(errno); #else *************** *** 375,384 **** #if defined(MSWin) /* ReadFile blocks on any pipe not opened in overlapped mode and the anonymous ! pipes used for standard handle redirection are always non-overlapping. We don't ! want to block here, as for LabVIEW configurations with only one thread per ! execution system we would block the ReadPipe function and can't read another ! pipe. So we peek first at the pipe to see if there is anything available and if so ! we invoke ReadFile to read the entire data instead of maybe only part of a byte- ! stream sent from the other side.*/ if (!PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, bytesRead, NULL)) { --- 288,297 ---- #if defined(MSWin) /* ReadFile blocks on any pipe not opened in overlapped mode and the anonymous ! pipes used for standard handle redirection are always non-overlapping. We don't ! want to block here, as for LabVIEW configurations with only one thread per ! execution system we would block the ReadPipe function and can't read another ! pipe. So we peek first at the pipe to see if there is anything available and if so ! we invoke ReadFile to read the entire data instead of maybe only part of a byte- ! stream sent from the other side.*/ if (!PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, bytesRead, NULL)) { *************** *** 445,459 **** } #else ! err = mgNotImplementd: #endif return err; } ! /* size of the table */ ! #define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0])) #if defined(MSWin) ! static MgErr CreateChildProcess(LPSTR cmdline, HANDLE stdIn, HANDLE stdOut, HANDLE stdErr, DWORD *pid) { PROCESS_INFORMATION piProcInfo; STARTUPINFOA siStartInfo; --- 358,474 ---- } #else ! err = mgNotImplementd; #endif return err; } ! static MgErr RedirectStandardIO(int32 type, std_handle *stdIO, pipe_handle *rmpipe, uInt32 *lvpipe) ! { ! MgErr err = noErr; ! #if defined(MSWin) ! SECURITY_ATTRIBUTES saAttr = { 0 }; ! HANDLE temp; ! BOOL ret; ! ! saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); ! saAttr.lpSecurityDescriptor = NULL; ! saAttr.bInheritHandle = TRUE; ! ! /* Save the handle to the current STDIN. */ ! *stdIO = GetStdHandle(type); ! ! /* Create a pipe for the child process's standard IO. */ ! if (type == STANDARD_IN) ! ret = CreatePipe(rmpipe, &temp, &saAttr, 0); ! else ! ret = CreatePipe(&temp, rmpipe, &saAttr, 0); ! ! if (ret) ! { ! /* Set the handle to the pipe to be STD IO. */ ! ret = SetStdHandle(type, *rmpipe); ! if (ret) ! { ! /* Duplicate the write handle to the pipe so it is not inherited. */ ! ret = DuplicateHandle(GetCurrentProcess(), temp, ! GetCurrentProcess(), (HANDLE*)lvpipe, 0, ! FALSE, DUPLICATE_SAME_ACCESS); ! ! } ! CloseHandle(temp); ! } ! if (!ret) ! err = Win32ToLVErr(GetLastError()); ! ! #elif defined(Unix) ! struct pipe_ref p_fd; ! pipe_handle temp; ! int i; ! ! /* save current std input fd + flags, and set not inheritable */ ! if (stdio->handle = dup(type) < 0) ! return UnixToLVErr(errno); ! ! stdio->flags = fcntl(type, F_GETFD, 0); ! fcntl(stdio->handle, F_SETFD, stdio->flags | FD_CLOEXEC); ! ! if (pipe((int *)&p_fd)) ! { ! err = UnixToLVErr(errno); ! close(stdio->handle); ! return err; ! } ! if (type == STANDARD_IN) ! { ! temp = p_fd.wr; ! *rmpipe = p_fd.rd; ! } ! else ! { ! temp = p_fd.rd; ! *rmpipe = p_fd.wr; ! } + if (dup2(*rmpipe, type) == type) + { + close(*rmpipe); + i = fcntl(temp, F_GETFD, 0); + fcntl(temp, F_SETFD, i | FD_CLOEXEC); + + if ((*lvpipe = (uInt32)fdopen(temp, type == STANDARD_IN ? "wb" : "rb")) == NULL) + { + err = UnixToLVErr(errno); + close(stdio->handle); + close(temp); + } + } + #else + err = mgNotImplementd + #endif + return err; + } + + static MgErr RestoreStandardIO(int32 type, std_handle *stdIO, pipe_handle rmpipe, uInt32 *lvpipe, MgErr err) + { #if defined(MSWin) ! if (rmpipe) ! CloseHandle(rmpipe); ! SetStdHandle(type, *stdIO); ! if (err) ! { ! CloseHandle(*(HANDLE*)lvpipe); ! *lvpipe = 0; ! } ! #elif defined(Unix) ! #else ! return mgNotImplementd ! #endif ! return err; ! } ! ! static MgErr CreateChildProcess(LPSTR cmdline, pipe_handle stdIn, pipe_handle stdOut, pipe_handle stdErr, uInt32 *pid) { + MgErr err = noErr; + #if defined(MSWin) PROCESS_INFORMATION piProcInfo; STARTUPINFOA siStartInfo; *************** *** 493,499 **** CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); ! return noErr; } struct errentry { DWORD oscode; /* OS return value */ --- 508,546 ---- CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); ! #elif defined(Unix) ! int pi; ! ! /* parse command line into arguments */ ! ! ! ! /* spawn the child process */ ! pi = fork(); ! ! if (pi == 0 ) ! { ! /* This is the child process. Execute the command */ ! execvp(cvs_process->args[0], cvs_process->args); ! _exit(1); ! } ! else if (pi == -1 ) ! { ! /* fork failed */ ! *pid = 0L; ! return dvOpenErr; ! } ! else ! *pid = pi; ! ! #else ! return mgNotImplementd ! #endif ! return err; } + /* size of the table */ + #define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0])) + + #if defined(MSWin) struct errentry { DWORD oscode; /* OS return value */ |