From: nobu.nakada@... Date: 2002-08-26T16:08:04+09:00 Subject: [ruby-dev:18080] Re: Win32 signal, process etc なかだです。 At Mon, 26 Aug 2002 14:23:18 +0900, U.Nakamura wrote: > > win32/win32.c:kill()でSIGINTとSIGKILLだけ処理していますが、 > > signal.cではSIGKILLが定義されていないため、実際には即値で指定し > > ないと使えません。win32.cのSIGKILLの定義をsignal.cにもコピーす > > るか、win32.hでsignal.hもインクルードしてそっちに持っていくかす > > る必要があると思います。あるいは、SIGTERMはあるようなのでこれも > > SIGKILLと同じ処理にするとか。 > > win32.hに入れようと思って、そのまま忘れてました。 > 候補にないですが、win32.hじゃなくてrubysig.h(ですよね?)じゃ > ないと何かまずいんでしたっけ? そっちのほうがいいかも知れません。 > > もうひとつ、pipe_exec()では一旦stdin/stdoutにdupしてから > > CreateProcess()してますが、なんとなくこれはCreateChild()と機能 > > 的に重複してるような気がします。 > > pipe_exec()ではCreateProcess()じゃなくてCreateChild()を呼ん > でるつもりですが、見間違え? いや、だからこそ重複してるような気がするわけです。 > ただ、CreateChild()の後ろの三つの引数を結局どこでも使ってな > くて意味がないというのは思います。 > pipe_exec()で使うような使い方のために用意したつもりだったよ > うな気もするんですけどね。 です。それを使うとたぶんこんな感じ。 # DuplicateHandleしないとまずい? Index: win32.c =================================================================== RCS file: /cvs/ruby/src/ruby/win32/win32.c,v retrieving revision 1.63 diff -u -2 -p -r1.63 win32.c --- win32.c 20 Aug 2002 13:03:22 -0000 1.63 +++ win32.c 24 Aug 2002 14:18:02 -0000 @@ -85,4 +85,7 @@ static DWORD wait_events(HANDLE event, D #ifndef __BORLANDC__ static int rb_w32_open_osfhandle(long osfhandle, int flags); +#define open_osfhandle rb_w32_open_osfhandle +#else +#define open_osfhandle _open_osfhandle #endif @@ -440,11 +443,8 @@ pipe_exec(char *cmd, int mode, FILE **fp HANDLE hReadIn, hReadOut; HANDLE hWriteIn, hWriteOut; - HANDLE hSavedStdIn, hSavedStdOut; - HANDLE hDupInFile, hDupOutFile; - HANDLE hCurProc; SECURITY_ATTRIBUTES sa; - BOOL fRet; BOOL reading, writing; - int fdin, fdout; + FILE *fr, *fw; + int fd; int pipemode; char modes[3]; @@ -454,5 +454,13 @@ pipe_exec(char *cmd, int mode, FILE **fp writing = (mode & (O_WRONLY | O_RDWR)) ? TRUE : FALSE; reading = ((mode & O_RDWR) || !writing) ? TRUE : FALSE; - pipemode = (mode & O_BINARY) ? O_BINARY : O_TEXT; + if (mode & O_BINARY) { + pipemode = O_BINARY; + modes[1] = 'b'; + modes[2] = '\0'; + } + else { + pipemode = O_TEXT; + modes[1] = '\0'; + } sa.nLength = sizeof (SECURITY_ATTRIBUTES); @@ -463,168 +471,67 @@ pipe_exec(char *cmd, int mode, FILE **fp RUBY_CRITICAL(do { ret = -1; - hCurProc = GetCurrentProcess(); if (reading) { - fRet = CreatePipe(&hReadIn, &hReadOut, &sa, 2048L); - if (!fRet) { + if (!CreatePipe(&hReadIn, &hReadOut, &sa, 2048L)) { errno = GetLastError(); break; } - hSavedStdOut = GetStdHandle(STD_OUTPUT_HANDLE); - if (!SetStdHandle(STD_OUTPUT_HANDLE, hReadOut) || - !DuplicateHandle(hCurProc, hReadIn, hCurProc, &hDupInFile, 0, - FALSE, DUPLICATE_SAME_ACCESS)) { - errno = GetLastError(); - CloseHandle(hReadIn); - CloseHandle(hReadOut); - CloseHandle(hCurProc); - break; - } - CloseHandle(hReadIn); } if (writing) { - fRet = CreatePipe(&hWriteIn, &hWriteOut, &sa, 2048L); - if (!fRet) { + if (!CreatePipe(&hWriteIn, &hWriteOut, &sa, 2048L)) { errno = GetLastError(); if (reading) { - CloseHandle(hDupInFile); + CloseHandle(hReadIn); CloseHandle(hReadOut); } break; } - hSavedStdIn = GetStdHandle(STD_INPUT_HANDLE); - if (!SetStdHandle(STD_INPUT_HANDLE, hWriteIn) || - !DuplicateHandle(hCurProc, hWriteOut, hCurProc, &hDupOutFile, 0, - FALSE, DUPLICATE_SAME_ACCESS)) { - errno = GetLastError(); - CloseHandle(hWriteIn); - CloseHandle(hWriteOut); - CloseHandle(hCurProc); - if (reading) { - CloseHandle(hDupInFile); - CloseHandle(hReadOut); - } - break; - } - CloseHandle(hWriteOut); } - CloseHandle(hCurProc); - ret = 0; - } while (0)); - if (ret != 0) { - return ret; - } - /* create child process */ - child = CreateChild(cmd, &sa, NULL, NULL, NULL); - if (!child) { - RUBY_CRITICAL({ - if (reading) { - SetStdHandle(STD_OUTPUT_HANDLE, hSavedStdOut); - CloseHandle(hReadOut); - CloseHandle(hDupInFile); - } - if (writing) { - SetStdHandle(STD_INPUT_HANDLE, hSavedStdIn); - CloseHandle(hWriteIn); - CloseHandle(hDupOutFile); - } - }); - return -1; - } + /* create child process */ + child = CreateChild(cmd, &sa, hWriteIn, hReadOut, NULL); + if (reading) CloseHandle(hReadOut); + if (writing) CloseHandle(hWriteIn); + if (!child) { + if (reading) CloseHandle(hReadIn); + if (writing) CloseHandle(hWriteOut); + break; + } - /* restore STDIN/STDOUT */ - RUBY_CRITICAL(do { - ret = -1; if (reading) { - if (!SetStdHandle(STD_OUTPUT_HANDLE, hSavedStdOut)) { - errno = GetLastError(); + fd = open_osfhandle((long)hReadIn, (_O_RDONLY | pipemode)); + if (fd == -1) { + CloseHandle(hReadIn); + read_open_failed: + if (writing) CloseHandle(hWriteOut); CloseChildHandle(child); - CloseHandle(hReadOut); - CloseHandle(hDupInFile); - if (writing) { - CloseHandle(hWriteIn); - CloseHandle(hDupOutFile); - } break; } + modes[0] = 'r'; + if ((fr = (FILE *)fdopen(fd, modes)) == NULL) { + _close(fd); + goto read_open_failed; + } } if (writing) { - if (!SetStdHandle(STD_INPUT_HANDLE, hSavedStdIn)) { - errno = GetLastError(); + fd = open_osfhandle((long)hWriteOut, (_O_WRONLY | pipemode)); + if (fd == -1) { + CloseHandle(hWriteOut); + write_open_failed: + if (reading) fclose(fr); CloseChildHandle(child); - CloseHandle(hWriteIn); - CloseHandle(hDupOutFile); - if (reading) { - CloseHandle(hReadOut); - CloseHandle(hDupInFile); - } break; } - } - ret = 0; - } while (0)); - if (ret != 0) { - return ret; - } - - if (reading) { -#ifdef __BORLANDC__ - fdin = _open_osfhandle((long)hDupInFile, (_O_RDONLY | pipemode)); -#else - fdin = rb_w32_open_osfhandle((long)hDupInFile, (_O_RDONLY | pipemode)); -#endif - CloseHandle(hReadOut); - if (fdin == -1) { - CloseHandle(hDupInFile); - if (writing) { - CloseHandle(hWriteIn); - CloseHandle(hDupOutFile); - } - CloseChildHandle(child); - return -1; - } - } - if (writing) { -#ifdef __BORLANDC__ - fdout = _open_osfhandle((long)hDupOutFile, (_O_WRONLY | pipemode)); -#else - fdout = rb_w32_open_osfhandle((long)hDupOutFile, - (_O_WRONLY | pipemode)); -#endif - CloseHandle(hWriteIn); - if (fdout == -1) { - CloseHandle(hDupOutFile); - if (reading) { - _close(fdin); - } - CloseChildHandle(child); - return -1; - } - } - - if (reading) { - sprintf(modes, "r%s", pipemode == O_BINARY ? "b" : ""); - if ((*fpr = (FILE *)fdopen(fdin, modes)) == NULL) { - _close(fdin); - if (writing) { - _close(fdout); - } - CloseChildHandle(child); - return -1; - } - } - if (writing) { - sprintf(modes, "w%s", pipemode == O_BINARY ? "b" : ""); - if ((*fpw = (FILE *)fdopen(fdout, modes)) == NULL) { - _close(fdout); - if (reading) { - fclose(*fpr); + modes[0] = 'w'; + if ((fw = (FILE *)fdopen(fd, modes)) == NULL) { + _close(fd); + goto write_open_failed; } - CloseChildHandle(child); - return -1; } - } + *fpr = fr; + *fpw = fw; + ret = child->pid; + } while (0)); - return child->pid; + return ret; } @@ -2031,9 +1938,5 @@ rb_w32_socket (int af, int type, int pro //fprintf(stderr, "socket fail (%d)", WSAGetLastError()); } -#ifdef __BORLANDC__ - return _open_osfhandle(s, O_RDWR|O_BINARY); -#else - return rb_w32_open_osfhandle(s, O_RDWR|O_BINARY); -#endif + return open_osfhandle(s, O_RDWR|O_BINARY); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦