[#13765] GenerativeHash — TAKAHASHI Masayoshi <maki@...>

高橋征義です。

17 messages 2001/07/08
[#13769] Re: GenerativeHash — matz@... (Yukihiro Matsumoto) 2001/07/09

まつもと ゆきひろです

[#13774] mkmf.rb: cleaning facility — Takaaki Tateishi <ttate@...>

立石です.

14 messages 2001/07/09

[#13800] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — nobu.nakada@...

なかだです。

20 messages 2001/07/10
[#13801] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — WATANABE Hirofumi <eban@...> 2001/07/10

わたなべです。

[#13802] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — matz@... (Yukihiro Matsumoto) 2001/07/10

まつもと ゆきひろです

[#13804] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — WATANABE Hirofumi <eban@...> 2001/07/10

わたなべです。

[#13805] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — matz@... (Yukihiro Matsumoto) 2001/07/10

まつもと ゆきひろです

[#13806] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — WATANABE Hirofumi <eban@...> 2001/07/10

わたなべです。

[#13807] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — matz@... (Yukihiro Matsumoto) 2001/07/10

まつもと ゆきひろです

[#13808] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — "Akinori MUSHA" <knu@...> 2001/07/10

At Tue, 10 Jul 2001 15:23:04 +0900,

[#13809] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — WATANABE Hirofumi <eban@...> 2001/07/10

わたなべです。

[#13810] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — "Akinori MUSHA" <knu@...> 2001/07/10

At Tue, 10 Jul 2001 16:50:52 +0900,

[#13811] Re: [ruby-cvs] ruby: * ruby.h: fix a wrong function name: rb_iglob() -> rb_globi(). — "Akinori MUSHA" <knu@...> 2001/07/10

 もうひとつあった。

[#13828] supported platforms / K&R — "Akinori MUSHA" <knu@...>

 digest モジュールの各プラットフォームでの動作確認をお願いした

39 messages 2001/07/13
[#14389] Re: supported platforms / K&R — Koji Arai <JCA02266@...> 2001/08/08

新井です。

[#14399] Re: supported platforms / K&R — Takashi Shimizu <simtak@...> 2001/08/09

清水@biglobeです。

[#14404] Re: supported platforms / K&R — Koji Arai <JCA02266@...> 2001/08/09

新井です。

[#14461] Re: supported platforms / K&R — Takashi Shimizu <simtak@...> 2001/08/14

清水@biglobe です。

[#14466] Re: supported platforms / K&R — nobu.nakada@... 2001/08/14

なかだです。

[#14468] Re: supported platforms / K&R — Koji Arai <JCA02266@...> 2001/08/14

新井です。

[#14477] recursive malloc (Re: supported platforms / K&R) — Koji Arai <JCA02266@...> 2001/08/15

新井です。

[#14482] Re: recursive malloc (Re: supported platforms / K&R) — nobu.nakada@... 2001/08/15

なかだです。

[#14486] Re: recursive malloc (Re: supported platforms / K&R) — Koji Arai <JCA02266@...> 2001/08/15

新井です。

[#14490] Re: recursive malloc (Re: supported platforms/ K&R) — nobu.nakada@... 2001/08/15

なかだです。

[#14492] Re: recursive malloc (Re: supported platforms/ K&R) — Koji Arai <JCA02266@...> 2001/08/15

新井です。

[#14493] Re: recursive malloc (Re: supportedplatforms/ K&R) — nobu.nakada@... 2001/08/15

なかだです。

[#13878] Prototype for rb_gc_mark / volatile in ruby.h — Tietew <tietew@...>

Tietew です。

18 messages 2001/07/15
[#13880] Re: Prototype for rb_gc_mark / volatile in ruby.h — matz@... (Yukihiro Matsumoto) 2001/07/16

まつもと ゆきひろです

[#13940] IO#read — "Akinori MUSHA" <knu@...>

 IO#read を使って何度もストリームから読み込むような処理をする

20 messages 2001/07/19

[#13959] Re: [ruby-list:30682] Re: overwride method — "Akinori MUSHA" <knu@...>

At Fri, 20 Jul 2001 21:09:36 +0900,

95 messages 2001/07/20
[#13963] Re: [ruby-list:30682] Re: overwride method — GOTO Kentaro <gotoken@...> 2001/07/20

ごとけんです

[#13965] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/21

まつもと ゆきひろです

[#13967] Re: [ruby-list:30682] Re: overwride method — GOTO Kentaro <gotoken@...> 2001/07/21

ごとけんです

[#13969] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/21

まつもと ゆきひろです

[#13980] Re: [ruby-list:30682] Re: overwride method — GOTO Kentaro <gotoken@...> 2001/07/21

[ruby-dev:13969]>

[#13981] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/21

まつもと ゆきひろです

[#13984] Re: [ruby-list:30682] Re: overwride method — GOTO Kentaro <gotoken@...> 2001/07/22

ごとけんです

[#13993] Re: [ruby-list:30682] Re: overwride method — "NAKAMURA, Hiroshi" <nakahiro@...> 2001/07/23

なひです。

[#13994] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/23

まつもと ゆきひろです

[#13995] Re: [ruby-list:30682] Re: overwride method — keiju@... (石塚圭樹) 2001/07/23

けいじゅ@日本ラショナルソフトウェアです.

[#13996] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/23

まつもと ゆきひろです

[#13997] Re: [ruby-list:30682] Re: overwride method — keiju@... (石塚圭樹) 2001/07/23

けいじゅ@日本ラショナルソフトウェアです.

[#13998] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/23

まつもと ゆきひろです

[#14000] Re: [ruby-list:30682] Re: overwride method — "NAKAMURA, Hiroshi" <nakahiro@...> 2001/07/23

なひです。

[#14005] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/23

まつもと ゆきひろです

[#14016] Re: [ruby-list:30682] Re: overwride method — "NAKAMURA, Hiroshi" <nakahiro@...> 2001/07/24

なひです。

[#14021] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/24

まつもと ゆきひろです

[#14022] Re: [ruby-list:30682] Re: overwride method — "NAKAMURA, Hiroshi" <nakahiro@...> 2001/07/24

なひです。

[#14023] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/24

まつもと ゆきひろです

[#14037] Re: [ruby-list:30682] Re: overwride method — GOTO Kentaro <gotoken@...> 2001/07/24

ごとけんです

[#14039] Re: [ruby-list:30682] Re: overwride method — Masatoshi SEKI <m_seki@...> 2001/07/24

[#14040] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/24

まつもと ゆきひろです

[#14043] Re: [ruby-list:30682] Re: overwride method — m_seki@... 2001/07/24

[#14053] Re: [ruby-list:30682] Re: overwride method — matz@... (Yukihiro Matsumoto) 2001/07/25

まつもと ゆきひろです

[#14082] private instance variable と _dump/_load — Masatoshi SEKI <m_seki@...> 2001/07/25

[#14084] Re: private instance variable と _dump/_load — keiju@... (石塚圭樹) 2001/07/25

けいじゅ@日本ラショナルソフトウェアです.

[#14087] Re: private instance variable と _dump/_load — matz@... (Yukihiro Matsumoto) 2001/07/25

まつもと ゆきひろです

[#14089] Re: private instance variable と _dump/_load — keiju@... (石塚圭樹) 2001/07/25

けいじゅ@日本ラショナルソフトウェアです.

[#14094] Re: private instance variable と _dump/_load — matz@... (Yukihiro Matsumoto) 2001/07/26

まつもと ゆきひろです

[#14133] Re: private instance variable と _dump/_load — "Shin'ya Adzumi" <adzumi@...> 2001/07/27

あづみです。

[#14134] Re: private instance variable と _dump/_load — matz@... (Yukihiro Matsumoto) 2001/07/27

まつもと ゆきひろです

[#14140] Re: private instance variable と _dump/_load — Kazuhiro NISHIYAMA <zn@...> 2001/07/27

In <996211878.306635.31396.nullmailer@ev.netlab.jp>

[#14143] Re: private instance variable と _dump/_load — matz@... (Yukihiro Matsumoto) 2001/07/27

まつもと ゆきひろです

[#14144] Re: private instance variable と _dump/_load — Kazuhiro NISHIYAMA <zn@...> 2001/07/27

In <996255758.830993.629.nullmailer@ev.netlab.jp>

[#14066] Re: [ruby-list:30682] Re: overwride method — "Shin'ya Adzumi" <adzumi@...> 2001/07/25

あづみです。

[#14068] private instance variable (Re: Re: overwride method) — matz@... (Yukihiro Matsumoto) 2001/07/25

まつもと ゆきひろです

[#14099] Is private instance variable really needed? — Shugo Maeda <shugo@...> 2001/07/26

前田です。

[#14104] Re: Is private instance variable really needed? — matz@... (Yukihiro Matsumoto) 2001/07/26

まつもと ゆきひろです

[#14026] Exception in coerce — Shin-ichiro HARA <sinara@...>

原です。

21 messages 2001/07/24
[#14027] Re: Exception in coerce — matz@... (Yukihiro Matsumoto) 2001/07/24

まつもと ゆきひろです

[#14028] Re: Exception in coerce — Shin-ichiro HARA <sinara@...> 2001/07/24

原です。

[#14029] Re: Exception in coerce — matz@... (Yukihiro Matsumoto) 2001/07/24

まつもと ゆきひろです

[#14030] Re: Exception in coerce — matz@... (Yukihiro Matsumoto) 2001/07/24

まつもと ゆきひろです

[#14031] Re: Exception in coerce — Shin-ichiro HARA <sinara@...> 2001/07/24

原です。

[#14032] Re: Exception in coerce — matz@... (Yukihiro Matsumoto) 2001/07/24

まつもと ゆきひろです

[ruby-dev:13761] Re: mswin32/ming32 system patch (experimental)

From: "U.Nakamura" <usa@...>
Date: 2001-07-06 18:49:39 UTC
List: ruby-dev #13761
こんにちは、なかむら(う)です。

At Sat, 16 Jun 2001 23:13:49 +0900, nobu.nakada@nifty.ne.jp wrote in
    '[ruby-dev:13604] Re: mswin32/ming32 system patch (experimental)'
>   一案としてこういうのは。[ruby-dev:13510]からの差分ですが、
> win32/win32.c だけです。process.c は #ifndef NT を抜いた以外は
> CVS HEAD と同じなので省略、win32/win32.h は CVS HEAD そのままで
> す。

だいぶ遅くなりましたが(すみません)、まとめ。
これをそのまま採用して、末尾のパッチのようになりました。
この先の拡張は、別途fork+execなメソッドの議論の後ですね。
# あるいは、fork(のように動くもの)を実装するか :-P

これでcommitしようと思ってますが、どうでしょう?


Index: process.c
===================================================================
RCS file: /src/ruby/process.c,v
retrieving revision 1.36
diff -u -2 -p -r1.36 process.c
--- process.c	2001/05/21 04:22:54	1.36
+++ process.c	2001/07/06 18:40:25
@@ -1328,5 +1328,4 @@ Init_process()
     rb_define_singleton_method(rb_mProcess, "exit!", rb_f_exit_bang, -1);
     rb_define_module_function(rb_mProcess, "kill", rb_f_kill, -1);
-#ifndef NT
     rb_define_module_function(rb_mProcess, "wait", proc_wait, 0);
     rb_define_module_function(rb_mProcess, "wait2", proc_wait2, 0);
@@ -1356,5 +1355,4 @@ Init_process()
     rb_define_module_function(rb_mProcess, "pid", get_pid, 0);
     rb_define_module_function(rb_mProcess, "ppid", get_ppid, 0);
-#endif /* ifndef NT */
 
     rb_define_module_function(rb_mProcess, "getpgrp", proc_getpgrp, -1);
Index: win32/win32.c
===================================================================
RCS file: /src/ruby/win32/win32.c,v
retrieving revision 1.45
diff -u -2 -p -r1.45 win32.c
--- win32/win32.c	2001/05/12 06:47:24	1.45
+++ win32/win32.c	2001/07/06 18:40:25
@@ -73,4 +73,5 @@ extern char **environ;
 #endif
 
+static struct ChildRecord *CreateChild(char *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
 static bool NtHasRedirection (char *);
 static int valid_filename(char *s);
@@ -295,23 +296,73 @@ char *getlogin()
 
 #if 1
-// popen stuff
+#define MAXCHILDNUM 256	/* max num of child processes */
 
-//
-// use these so I can remember which index is which
-//
+struct ChildRecord {
+    HANDLE hProcess;	/* process handle */
+    pid_t pid;		/* process id */
+    FILE* pipe;		/* pipe */
+} ChildRecord[MAXCHILDNUM];
 
-#define NtPipeRead  0	   // index of pipe read descriptor
-#define NtPipeWrite 1	   // index of pipe write descriptor
+#define FOREACH_CHILD(v) do { \
+    struct ChildRecord* v; \
+    for (v = ChildRecord; v < ChildRecord + sizeof(ChildRecord) / sizeof(ChildRecord[0]); ++v)
+#define END_FOREACH_CHILD } while (0)
 
-#define NtPipeSize  1024   // size of pipe buffer
+static struct ChildRecord *
+FindFirstChildSlot(void)
+{
+    FOREACH_CHILD(child) {
+	if (child->pid) return child;
+    } END_FOREACH_CHILD;
+    return NULL;
+}
 
-#define MYPOPENSIZE 256	   // size of book keeping structure
+static struct ChildRecord *
+FindChildSlot(pid_t pid)
+{
 
-struct {
-    int inuse;
-    int pid;
-    FILE *pipe;
-} MyPopenRecord[MYPOPENSIZE];
+    FOREACH_CHILD(child) {
+	if (child->pid == pid) {
+	    return child;
+	}
+    } END_FOREACH_CHILD;
+    return NULL;
+}
 
+static struct ChildRecord *
+FindPipedChildSlot(FILE *fp)
+{
+    FOREACH_CHILD(child) {
+	if (child->pid && child->pipe == fp) {
+	    return child;
+	}
+    } END_FOREACH_CHILD;
+    return NULL;
+}
+
+static void
+CloseChildHandle(struct ChildRecord *child)
+{
+    HANDLE h = child->hProcess;
+    child->hProcess = NULL;
+    child->pid = 0;
+    CloseHandle(h);
+}
+
+static struct ChildRecord *
+FindFreeChildSlot(void)
+{
+    FOREACH_CHILD(child) {
+	if (!child->pid) {
+	    child->pid = -1;	/* lock the slot */
+	    child->hProcess = NULL;
+	    child->pipe = NULL;
+	    return child;
+	}
+    } END_FOREACH_CHILD;
+    return NULL;
+}
+
+
 int SafeFree(char **vec, int vecc)
 {
@@ -397,32 +448,11 @@ mypopen (char *cmd, char *mode) 
 {
     FILE *fp;
-    int saved, reading;
+    int reading;
     int pipemode;
-    int pipes[2];
-    int pid;
-    int slot;
-    static initialized = 0;
-
-    //
-    // if first time through, intialize our book keeping structure
-    //
-
-    if (!initialized++) {
-	for (slot = 0; slot < MYPOPENSIZE; slot++)
-	    MyPopenRecord[slot].inuse = FALSE;
-    }
-
-    //printf("mypopen %s\n", cmd);
-    
-    //
-    // find a free popen slot
-    //
-
-    for (slot = 0; slot < MYPOPENSIZE && MyPopenRecord[slot].inuse; slot++)
-	;
-
-    if (slot > MYPOPENSIZE) {
-	return NULL;
-    }
+    struct ChildRecord* child;
+    BOOL fRet;
+    HANDLE hInFile, hOutFile;
+    SECURITY_ATTRIBUTES sa;
+    int fd;
 
     //
@@ -436,297 +466,76 @@ mypopen (char *cmd, char *mode) 
     // Now get a pipe
     //
-
-#if 0    
-    if (_pipe(pipes, NtPipeSize, pipemode) == -1) {
-	return NULL;
+    sa.nLength              = sizeof (SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle       = TRUE;
+
+    fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
+    if (!fRet) {
+	errno = GetLastError();
+	rb_sys_fail("mypopen: CreatePipe");
     }
 
     if (reading) {
-
-	//
-	// we\'re reading from the pipe, so we must hook up the
-	// write end of the pipe to the new processes stdout.
-	// To do this we must save our file handle from stdout
-	// by _dup\'ing it, then setting our stdout to be the pipe\'s 
-	// write descriptor. We must also make the write handle 
-	// inheritable so the new process can use it.
-
-	if ((saved = _dup(fileno(stdout))) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-	if (_dup2 (pipes[NtPipeWrite], fileno(stdout)) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
+	child = CreateChild(cmd, &sa, NULL, hOutFile, NULL);
     }
     else {
-	//
-	// must be writing to the new process. Do the opposite of
-	// the above, i.e. hook up the processes stdin to the read
-	// end of the pipe.
-	//
-
-	if ((saved = _dup(fileno(stdin))) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-	if (_dup2(pipes[NtPipeRead], fileno(stdin)) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-    }
-
-    //
-    // Start the new process. Must set _fileinfo to non-zero value
-    // for file descriptors to be inherited. Reset after the process
-    // is started.
-    //
-
-    if (NtHasRedirection(cmd)) {
-      docmd:
-	pid = spawnlpe(_P_NOWAIT, "cmd.exe", "/c", cmd, 0, environ);
-	if (pid == -1) {
-	    _close(pipes[NtPipeRead]);
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
+	child = CreateChild(cmd, &sa, hInFile, NULL, NULL);
     }
-    else {
-	char **vec;
-	int vecc = NtMakeCmdVector(cmd, &vec, FALSE);
 
-	//pid = spawnvpe (_P_NOWAIT, vec[0], vec, environ);
-	pid = spawnvpe (_P_WAIT, vec[0], vec, environ);
-	if (pid == -1) {
-	    goto docmd;
-	}
-		Safefree (vec, vecc);
+    if (!child) {
+	CloseHandle(hInFile);
+	CloseHandle(hOutFile);
+	rb_sys_fail("mypopen: CreateChild");
     }
 
     if (reading) {
-
-	//
-	// We need to close our instance of the inherited pipe write
-	// handle now that it's been inherited so that it will actually close
-	// when the child process ends.
-	//
-
-	if (_close(pipes[NtPipeWrite]) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    return NULL;
-	}
-	if (_dup2 (saved, fileno(stdout)) == -1) {
-	    _close(pipes[NtPipeRead]);
-	    return NULL;
-	}
-	_close(saved);
-
-	// 
-	// Now get a stream pointer to return to the calling program.
-	//
-
-	if ((fp = (FILE *) fdopen(pipes[NtPipeRead], mode)) == NULL) {
-	    return NULL;
-	}
+	fd = _open_osfhandle((long)hInFile,  (_O_RDONLY | pipemode));
+	CloseHandle(hOutFile);
     }
     else {
-
-	//
-	// need to close our read end of the pipe so that it will go 
-	// away when the write end is closed.
-	//
-
-	if (_close(pipes[NtPipeRead]) == -1) {
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-	if (_dup2 (saved, fileno(stdin)) == -1) {
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
-	_close(saved);
-
-	// 
-	// Now get a stream pointer to return to the calling program.
-	//
+	fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode));
+	CloseHandle(hInFile);
+    }
 
-	if ((fp = (FILE *) fdopen(pipes[NtPipeWrite], mode)) == NULL) {
-	    _close(pipes[NtPipeWrite]);
-	    return NULL;
-	}
+    if (fd == -1) {
+	CloseHandle(reading ? hInFile : hOutFile);
+	CloseChildHandle(child);
+	rb_sys_fail("mypopen: _open_osfhandle");
     }
 
-    //
-    // do the book keeping
-    //
+    if ((fp = (FILE *) fdopen(fd, mode)) == NULL) {
+	_close(fd);
+	CloseChildHandle(child);
+	rb_sys_fail("mypopen: fdopen");
+    }
 
-    MyPopenRecord[slot].inuse = TRUE;
-    MyPopenRecord[slot].pipe = fp;
-    MyPopenRecord[slot].pid = pid;
+    child->pipe = fp;
 
     return fp;
-#else
-    {
-		int p[2];
-
-		BOOL fRet;
-		HANDLE hInFile, hOutFile;
-		LPCSTR lpApplicationName = NULL;
-		LPTSTR lpCommandLine;
-		LPTSTR lpCmd2 = NULL;
-		DWORD  dwCreationFlags;
-		STARTUPINFO aStartupInfo;
-		PROCESS_INFORMATION     aProcessInformation;
-		SECURITY_ATTRIBUTES sa;
-		int fd;
-
-		sa.nLength              = sizeof (SECURITY_ATTRIBUTES);
-		sa.lpSecurityDescriptor = NULL;
-		sa.bInheritHandle       = TRUE;
-
-		fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
-		if (!fRet) {
-			errno = GetLastError();
-			rb_sys_fail("mypopen: CreatePipe");
-		}
-
-		memset(&aStartupInfo, 0, sizeof (STARTUPINFO));
-		memset(&aProcessInformation, 0, sizeof (PROCESS_INFORMATION));
-		aStartupInfo.cb = sizeof (STARTUPINFO);
-		aStartupInfo.dwFlags    = STARTF_USESTDHANDLES;
-
-		if (reading) {
-			aStartupInfo.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
-			aStartupInfo.hStdOutput = hOutFile;
-		}
-		else {
-			aStartupInfo.hStdInput  = hInFile;
-			aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
-		}
-		aStartupInfo.hStdError  = GetStdHandle(STD_ERROR_HANDLE);
-
-		dwCreationFlags = (NORMAL_PRIORITY_CLASS);
-
-		lpCommandLine = cmd;
-		if (NtHasRedirection(cmd) || isInternalCmd(cmd)) {
-		  lpApplicationName = getenv("COMSPEC");
-		  lpCmd2 = xmalloc(strlen(lpApplicationName) + 1 + strlen(cmd) + sizeof (" /c "));
-		  sprintf(lpCmd2, "%s %s%s", lpApplicationName, " /c ", cmd);
-		  lpCommandLine = lpCmd2;
-		}
-
-		fRet = CreateProcess(lpApplicationName, lpCommandLine, &sa, &sa,
-			sa.bInheritHandle, dwCreationFlags, NULL, NULL, &aStartupInfo, &aProcessInformation);
-		errno = GetLastError();
-
-		if (lpCmd2)
-			free(lpCmd2);
-
-		if (!fRet) {
-			CloseHandle(hInFile);
-			CloseHandle(hOutFile);
-			return NULL;
-		}
-
-		CloseHandle(aProcessInformation.hThread);
-
-		if (reading) {
-			fd = _open_osfhandle((long)hInFile,  (_O_RDONLY | pipemode));
-			CloseHandle(hOutFile);
-		}
-		else {
-			fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode));
-			CloseHandle(hInFile);
-		}
-
-		if (fd == -1) {
-			CloseHandle(reading ? hInFile : hOutFile);
-			CloseHandle(aProcessInformation.hProcess);
-			rb_sys_fail("mypopen: _open_osfhandle");
-		}
-
-		if ((fp = (FILE *) fdopen(fd, mode)) == NULL) {
-			_close(fd);
-			CloseHandle(aProcessInformation.hProcess);
-			rb_sys_fail("mypopen: fdopen");
-		}
-
-		MyPopenRecord[slot].inuse = TRUE;
-		MyPopenRecord[slot].pipe  = fp;
-		MyPopenRecord[slot].pid   = (int)aProcessInformation.hProcess;
-		return fp;
-    }
-#endif
 }
 
+extern VALUE rb_last_status;
+
 int
 mypclose(FILE *fp)
 {
-    int i;
-    DWORD exitcode;
+    struct ChildRecord *child = FindPipedChildSlot(fp);
 
-    Sleep(100);
-    for (i = 0; i < MYPOPENSIZE; i++) {
-	if (MyPopenRecord[i].inuse && MyPopenRecord[i].pipe == fp)
-	    break;
+    if (!child) {
+	rb_fatal("Invalid file pointer passed to mypclose!\n");
     }
-    if (i >= MYPOPENSIZE) {
-                rb_fatal("Invalid file pointer passed to mypclose!\n");
-    }
 
     //
-    // get the return status of the process
-    //
-
-#if 0
-    if (_cwait(&exitcode, MyPopenRecord[i].pid, WAIT_CHILD) == -1) {
-	if (errno == ECHILD) {
-	    fprintf(stderr, "mypclose: nosuch child as pid %x\n", 
-		    MyPopenRecord[i].pid);
-	}
-    }
-#else
-	for (;;) {
-		if (GetExitCodeProcess((HANDLE)MyPopenRecord[i].pid, &exitcode)) {
-			if (exitcode == STILL_ACTIVE) {
-				//printf("Process is Active.\n");
-				Sleep(100);
-				TerminateProcess((HANDLE)MyPopenRecord[i].pid, 0); // ugly...
-				continue;
-			}
-			else if (exitcode == 0) {
-				//printf("done.\n");
-				break;
-			}
-			else {
-				//printf("never.\n");
-				break;
-			}
-		}
-	}
-	CloseHandle((HANDLE)MyPopenRecord[i].pid);
-#endif
-
-    //
     // close the pipe
     //
-
+    child->pipe = NULL;
     fflush(fp);
     fclose(fp);
 
     //
-    // free this slot
+    // get the return status of the process
     //
-
-    MyPopenRecord[i].inuse = FALSE;
-    MyPopenRecord[i].pipe  = NULL;
-    MyPopenRecord[i].pid   = 0;
-
-    return (int)((exitcode & 0xff) << 8);
+    rb_syswait(child->pid);
+    return NUM2INT(rb_last_status);
 }
 #endif
@@ -735,109 +544,103 @@ mypclose(FILE *fp)
 
 
-typedef char* CHARP;
-/*
- * The following code is based on the do_exec and do_aexec functions
- * in file doio.c
- */
-
 int
 do_spawn(cmd)
 char *cmd;
 {
-    register char **a;
-    register char *s;
-    char **argv;
-    int status = -1;
-    char *shell, *cmd2;
-    int mode = NtSyncProcess ? P_WAIT : P_NOWAIT;
-    char quote;
-    char *exec;
+    struct ChildRecord *child = CreateChild(cmd, NULL, NULL, NULL, NULL);
+    if (!child) {
+	rb_sys_fail("do_spawn: CreateChild");
+    }
+    rb_syswait(child->pid);
+    return NUM2INT(rb_last_status);
+}
+
+static struct ChildRecord *
+CreateChild(char *cmd, SECURITY_ATTRIBUTES *psa, HANDLE hInput, HANDLE hOutput, HANDLE hError)
+{
+    BOOL fRet;
+    DWORD  dwCreationFlags;
+    STARTUPINFO aStartupInfo;
+    PROCESS_INFORMATION aProcessInformation;
+    SECURITY_ATTRIBUTES sa;
+    char *shell;
+    struct ChildRecord *child;
+
+    child = FindFreeChildSlot();
+    if (!child) {
+	errno = EAGAIN;
+	return NULL;
+    }
 
-    /* save an extra exec if possible */
-    if ((shell = getenv("RUBYSHELL")) != 0) {
-	if (NtHasRedirection(cmd)) {
-	    int  i;
-	    char *p;
-	    char *argv[4];
-	    char *cmdline = ALLOC_N(char, (strlen(cmd) * 2 + 1));
+    if (!psa) {
+	sa.nLength              = sizeof (SECURITY_ATTRIBUTES);
+	sa.lpSecurityDescriptor = NULL;
+	sa.bInheritHandle       = TRUE;
+	psa = &sa;
+    }
 
-	    p=cmdline;           
-	    *p++ = '"';
-	    for (s=cmd; *s;) {
-		if (*s == '"') 
-		    *p++ = '\\'; /* Escape d-quote */
-		*p++ = *s++;
-	    }
-	    *p++ = '"';
-	    *p   = '\0';
+    memset(&aStartupInfo, 0, sizeof (STARTUPINFO));
+    memset(&aProcessInformation, 0, sizeof (PROCESS_INFORMATION));
+    aStartupInfo.cb = sizeof (STARTUPINFO);
+    aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
+    if (hInput) {
+	aStartupInfo.hStdInput  = hInput;
+    }
+    else {
+	aStartupInfo.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
+    }
+    if (hOutput) {
+	aStartupInfo.hStdOutput = hOutput;
+    }
+    else {
+	aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+    }
+    if (hError) {
+	aStartupInfo.hStdError = hError;
+    }
+    else {
+	aStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+    }
 
-	    /* fprintf(stderr, "do_spawn: %s %s\n", shell, cmdline); */
-	    argv[0] = shell;
-	    argv[1] = "-c";
-	    argv[2] = cmdline;
-	    argv[4] = NULL;
-	    status = spawnvpe(mode, argv[0], argv, environ);
-	    /* return spawnle(mode, shell, shell, "-c", cmd, (char*)0, environ); */
-	    free(cmdline);
-	    return (int)((status & 0xff) << 8);
-	} 
-    }
-    else if ((shell = getenv("COMSPEC")) != 0) {
-	if (NtHasRedirection(cmd) /* || isInternalCmd(cmd) */) {
-	    status = spawnle(mode, shell, shell, "/c", cmd, (char*)0, environ);
-	    return (int)((status & 0xff) << 8);
-	}
+    dwCreationFlags = (NORMAL_PRIORITY_CLASS);
+
+    if ((shell = getenv("RUBYSHELL")) && NtHasRedirection(cmd)) {
+	char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) + sizeof (" -c "));
+	sprintf(tmp, "%s -c %s", shell, cmd);
+	cmd = tmp;
+    }
+    else if ((shell = getenv("COMSPEC")) &&
+	     (NtHasRedirection(cmd) || isInternalCmd(cmd))) {
+	char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) + sizeof (" /c "));
+	sprintf(tmp, "%s /c %s", shell, cmd);
+	cmd = tmp;
+    }
+    else {
+	shell = NULL;
     }
 
-    argv = ALLOC_N(CHARP, (strlen(cmd) / 2 + 2));
-    cmd2 = ALLOC_N(char, (strlen(cmd) + 1));
-    strcpy(cmd2, cmd);
-    a = argv;
-    for (s = cmd2; *s;) {
-	while (*s && ISSPACE(*s)) s++;
-	if (*s == '"') {
-	    quote = *s;
-	    *(a++) = s++;
-	    while (*s) {
-		if (*s == '\\' && *(s + 1) == quote) {
-		    memmove(s, s + 1, strlen(s) + 1);
-		    s++;
-		}
-		else if (*s == quote) {
-		    s++;
-		    break;
-		}
-		s++;
-	    }
-	}
-	else if (*s) {
-	    *(a++) = s;
-	    while (*s && !ISSPACE(*s)) s++;
-	}
-	if (*s)
-	    *s++ = '\0';
-    }
-    *a = NULL;
-    exec = NULL;
-    if (argv[0]) {
-	exec = ALLOC_N(char, (strlen(argv[0]) + 1));
-	if (argv[0][0] == '"' && argv[0][strlen(argv[0]) - 1] == '"') {
-	    strcpy(exec, &argv[0][1]);
-	    exec[strlen(exec) - 1] = '\0';
-	}
-	else {
-	    strcpy(exec, argv[0]);
-	}
-	if ((status = spawnvpe(mode, exec, argv, environ)) == -1) {
-	    free(exec);
-	    free(argv);
-	    free(cmd2);
-	    return -1;
-	}
+    RUBY_CRITICAL({
+	fRet = CreateProcess(shell, cmd, psa, psa,
+			     psa->bInheritHandle, dwCreationFlags, NULL, NULL,
+			     &aStartupInfo, &aProcessInformation);
+	errno = GetLastError();
+    });
+
+    if (!fRet) {
+	child->pid = 0;		/* release the slot */
+	return NULL;
     }
-    free(exec);
-    free(cmd2);
-    free(argv);
-    return (int)((status & 0xff) << 8);
+
+    CloseHandle(aProcessInformation.hThread);
+
+    child->hProcess = aProcessInformation.hProcess;
+    child->pid = (pid_t)aProcessInformation.dwProcessId;
+
+    if (!IsWinNT()) {
+	/* On Win9x, make pid positive similarly to cygwin and perl */
+	child->pid = -child->pid;
+    }
+
+    return child;
 }
 
@@ -1061,4 +864,5 @@ NtHasRedirection (char *cmd)
 	  case '>':
 	  case '<':
+	  case '|':
 
 	    if (!inquote)
@@ -2467,5 +2271,19 @@ waitpid (pid_t pid, int *stat_loc, int o
 {
     DWORD timeout;
+    DWORD exitcode;
+    int ret;
+    struct ChildRecord* child;
 
+    if (pid == -1) {
+	child = FindFirstChildSlot();
+    }
+    else {
+	child = FindChildSlot(pid);
+    }
+    if (!child) {
+	errno = ECHILD;
+	return -1;
+    }
+
     if (options == WNOHANG) {
 	timeout = 0;
@@ -2473,15 +2291,32 @@ waitpid (pid_t pid, int *stat_loc, int o
 	timeout = INFINITE;
     }
-    RUBY_CRITICAL({
-	if (wait_events((HANDLE)pid, timeout) == WAIT_OBJECT_0) {
-	    pid = _cwait(stat_loc, pid, 0);
+
+    for (;;) {
+	if (!GetExitCodeProcess(child->hProcess, &exitcode)) {
+	    /* If an error occured, return immediatly. */
+	    errno = GetLastError();
+	    if (errno == ERROR_INVALID_PARAMETER) {
+		errno = ECHILD;
+	    }
+	    CloseChildHandle(child);
+	    pid = -1;
+	    break;
 	}
-	else {
+	else if (exitcode != STILL_ACTIVE) {
+	    /* If already died, return immediatly. */
+	    pid = child->pid;
+	    CloseChildHandle(child);
+	    if (stat_loc) *stat_loc = exitcode << 8;
+	    break;
+	}
+
+	/* wait... */
+	if (wait_events(child->hProcess, timeout) != WAIT_OBJECT_0) {
+	    /* still active */
 	    pid = 0;
+	    break;
 	}
-    });
-#if !defined __BORLANDC__
-    if (pid) *stat_loc <<= 8;
-#endif
+    }
+
     return pid;
 }
@@ -2491,5 +2326,5 @@ waitpid (pid_t pid, int *stat_loc, int o
 int _cdecl
 gettimeofday(struct timeval *tv, struct timezone *tz)
-{                                
+{
     SYSTEMTIME st;
     time_t t;
@@ -2557,30 +2392,48 @@ chown(const char *path, int owner, int g
 
 #include <signal.h>
+#ifndef SIGINT
+#define SIGINT 2
+#endif
+#ifndef SIGKILL
+#define SIGKILL	9
+#endif
 int
 kill(int pid, int sig)
 {
-    if ((unsigned int)pid == GetCurrentProcessId())
+    if ((unsigned int)pid == GetCurrentProcessId() && sig != SIGKILL)
 	return raise(sig);
 
-    if (sig == 2 && pid > 0) {
-	if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid)) {
-	    errno = GetLastError();
-	    return -1;
-	}
+    if (sig == SIGINT && pid > 0) {
+	RUBY_CRITICAL({
+	    if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid)) {
+		errno = GetLastError();
+		return -1;
+	    }
+	});
     }
-    else if (sig == 9 && pid > 0) {
+    else if (sig == SIGKILL && pid > 0) {
 	HANDLE hProc;
+	int ret = 0;
 
-	hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
-	if (hProc == NULL || hProc == INVALID_HANDLE_VALUE) {
-	    errno = GetLastError();
-	    return -1;
-	}
-	if (!TerminateProcess(hProc, 0)) {
-	    errno = GetLastError();
+	RUBY_CRITICAL({
+	    hProc = OpenProcess(PROCESS_TERMINATE, FALSE,
+				IsWin95() ? -pid : pid);
+	    if (hProc == NULL || hProc == INVALID_HANDLE_VALUE) {
+		if (GetLastError() == ERROR_INVALID_PARAMETER) {
+		    errno = ESRCH;
+		}
+		else {
+		    errno = EPERM;
+		}
+		return -1;
+	    }
+
+	    if (!TerminateProcess(hProc, 0)) {
+		errno = EPERM;
+		ret = -1;
+	    }
 	    CloseHandle(hProc);
-	    return -1;
-	}
-	CloseHandle(hProc);
+	});
+	return ret;
     }
     else {


それでは。

--
U.Nakamura <usa@osb.att.ne.jp>

In This Thread