[#13493] yield *[[]] — Tanaka Akira <akr@...17n.org>

しばらく前に、yield *[[]] の挙動に関して bug report をして、まつもとさ

96 messages 2001/06/07
[#13494] Re: yield *[[]] — nobu.nakada@... 2001/06/07

なかだです。

[#13496] Re: yield *[[]] — Tanaka Akira <akr@...17n.org> 2001/06/08

In article <200106071409.XAA21101@sharui.nakada.kanuma.tochigi.jp>,

[#13503] Re: yield *[[]] — matz@... (Yukihiro Matsumoto) 2001/06/08

まつもと ゆきひろです

[#13506] Re: yield *[[]] — Tanaka Akira <akr@...17n.org> 2001/06/08

In article <991988462.179562.20598.nullmailer@ev.netlab.zetabits.com>,

[#13512] Re: yield *[[]] — matz@... (Yukihiro Matsumoto) 2001/06/08

まつもと ゆきひろです

[#13497] Re: yield *[[]] — Shugo Maeda <shugo@...> 2001/06/08

前田です。

[#13500] Re: yield *[[]] — "K.Kosako" <kosako@...> 2001/06/08

Shugo Maedaさんの<87lmn336s3.wl@localhost.netlab.jp>から

[#13501] Re: yield *[[]] — Shugo Maeda <shugo@...> 2001/06/08

前田です。

[#13504] Re: yield *[[]] — "K.Kosako" <kosako@...> 2001/06/08

Shugo Maedaさんの<87hexr316u.wl@localhost.netlab.jp>から

[#13505] Re: yield *[[]] — Shugo Maeda <shugo@...> 2001/06/08

前田です。

[#13511] Re: yield *[[]] — matz@... (Yukihiro Matsumoto) 2001/06/08

まつもと ゆきひろです

[#13526] Re: yield *[[]] — Shugo Maeda <shugo@...> 2001/06/09

前田です。

[#13530] Re: yield *[[]] — Tanaka Akira <akr@...17n.org> 2001/06/09

In article <m38zj242y9.wl@localhost.localdomain>,

[#13549] Re: yield *[[]] — Shin-ichiro HARA <sinara@...> 2001/06/12

原です。

[#13553] Re: yield *[[]] — Tanaka Akira <akr@...17n.org> 2001/06/12

In article <4.3.2-J.20010612154813.02c89a70@blade.nagaokaut.ac.jp>,

[#13554] Re: yield *[[]] — Shin-ichiro HARA <sinara@...> 2001/06/12

原です。

[#13560] Re: yield *[[]] — Tanaka Akira <akr@...17n.org> 2001/06/13

In article <4.3.2-J.20010612185543.00c8b988@blade.nagaokaut.ac.jp>,

[#13561] Re: yield *[[]] — matz@... (Yukihiro Matsumoto) 2001/06/13

まつもと ゆきひろです

[#13566] Re: yield *[[]] — Tanaka Akira <akr@...17n.org> 2001/06/13

In article <992410104.066682.22743.nullmailer@ev.netlab.zetabits.com>,

[#13591] Re: yield *[[]] — Tanaka Akira <akr@...17n.org> 2001/06/14

In article <hvor8wo501g.fsf@flux.etl.go.jp>,

[#13597] Re: yield *[[]] — matz@... (Yukihiro Matsumoto) 2001/06/14

まつもと ゆきひろです

[#13598] Re: yield *[[]] — Tanaka Akira <akr@...17n.org> 2001/06/15

In article <992533086.935976.4066.nullmailer@ev.netlab.zetabits.com>,

[#13616] Re: yield *[[]] — matz@... (Yukihiro Matsumoto) 2001/06/19

まつもと ゆきひろです

[#13622] Re: yield *[[]] — matz@... (Yukihiro Matsumoto) 2001/06/22

まつもと ゆきひろです

[#13628] Re: yield *[[]] — matz@... (Yukihiro Matsumoto) 2001/06/23

まつもと ゆきひろです

[#13633] Re: yield *[[]] — keiju@... (石塚圭樹) 2001/06/24

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

[#13647] Re: yield *[[]] — "KANEMITSU Masao" <masao-k@...> 2001/06/25

金光です。

[#13567] Parallel Assignment — Shin-ichiro HARA <sinara@...> 2001/06/13

原です。

[#13577] Re: Parallel Assignment — matz@... (Yukihiro Matsumoto) 2001/06/13

まつもと ゆきひろです

[#13650] Re: [ruby-ext:01803] Re: Ruby/SDL on PS2 LinuxKit — WATANABE Hirofumi <eban@...>

わたなべです。

56 messages 2001/06/26
[#13653] Re: [ruby-ext:01803] Re: Ruby/SDL on PS2 LinuxKit — matz@... (Yukihiro Matsumoto) 2001/06/26

まつもと ゆきひろです

[#13659] library search path — matz@... (Yukihiro Matsumoto) 2001/06/26

まつもと ゆきひろです

[#13906] Re: library search path — nobu.nakada@... 2001/07/16

なかだです。

[#13978] Re: library search path — nobu.nakada@... 2001/07/21

なかだです。

[#13990] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/22

まつもと ゆきひろです

[#14002] Re: library search path — nobu.nakada@... 2001/07/23

なかだです。

[#14011] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/23

まつもと ゆきひろです

[#14017] Re: library search path — "U.Nakamura" <usa@...> 2001/07/24

こんにちは、なかむら(う)です。

[#14020] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/24

まつもと ゆきひろです

[#14036] Re: library search path — nobu.nakada@... 2001/07/24

なかだです。

[#14075] Re: library search path — nobu.nakada@... 2001/07/25

なかだです。

[#14079] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/25

まつもと ゆきひろです

[#14090] Re: library search path — nobu.nakada@... 2001/07/25

なかだです。

[#14095] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/26

まつもと ゆきひろです

[#14115] Re: library search path — akira yamada / やまだあきら <akira@...> 2001/07/26

[#14121] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/26

まつもと ゆきひろです

[#14136] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/27

まつもと ゆきひろです

[#14137] Re: library search path — nobu.nakada@... 2001/07/27

なかだです。

[#14138] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/27

まつもと ゆきひろです

[#14141] Re: library search path — nobu.nakada@... 2001/07/27

なかだです。

[#14142] Re: library search path — matz@... (Yukihiro Matsumoto) 2001/07/27

まつもと ゆきひろです

[#14148] Re: library search path — nobu.nakada@... 2001/07/28

なかだです。

[#13666] net/http.rb warnings — nobu.nakada@...

なかだです。

14 messages 2001/06/26

[#13668] ruby_m17n make error — TAKAHASHI Masayoshi <maki@...>

高橋征義です。

43 messages 2001/06/26
[#14038] Re: m17n ruby 特に TRON 文字コード — "TOYOFUKU Chikanobu" <toyofuku@...> 2001/07/24

豊福です。

[#13705] eval(code, true, filename) — Shugo Maeda <shugo@...>

前田です。

14 messages 2001/06/29

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

From: nobu.nakada@...
Date: 2001-06-16 14:13:49 UTC
List: ruby-dev #13604
なかだです。

At Wed, 13 Jun 2001 00:04:12 +0900,
U.Nakamura <usa@osb.att.ne.jp> wrote:
> それはそれとして、符号反転しておくのが普通みたいなのでこっち
> も合わせておきます。

  一案としてこういうのは。[ruby-dev:13510]からの差分ですが、
win32/win32.c だけです。process.c は #ifndef NT を抜いた以外は
CVS HEAD と同じなので省略、win32/win32.h は CVS HEAD そのままで
す。

  それと mypopen()/mypclose() に関しても、ChildRecord にまとめ
てみました。


Index: win32.c
===================================================================
RCS file: /cvs/ruby/src/ruby/win32/win32.c,v
retrieving revision 1.45.0.1
diff -u -2 -p -r1.45.0.1 win32.c
--- win32/win32.c	2001/06/11 14:17:07 2001	1.45.0.1
+++ win32/win32.c	2001/06/13 13:24:02
@@ -73,5 +73,5 @@ extern char **environ;
 #endif
 
-static pid_t win32_exec_and_nowait(char *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
+static struct ChildRecord *CreateChild(char *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
 static bool NtHasRedirection (char *);
 static int valid_filename(char *s);
@@ -298,72 +298,70 @@ char *getlogin()
 #define MAXCHILDNUM 256	/* max num of child processes */
 
-struct {
-    int inuse;		/* use or unuse */
+struct ChildRecord {
     HANDLE hProcess;	/* process handle */
     pid_t pid;		/* process id */
+    FILE* pipe;		/* pipe */
 } ChildRecord[MAXCHILDNUM];
 
-static int FindChildSlot(pid_t pid)
-{
-    int slot;
+#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)
 
-    for (slot = 0; slot < MAXCHILDNUM; slot++) {
-	if (ChildRecord[slot].inuse == TRUE && ChildRecord[slot].pid == pid) {
-	    return slot;
-	}
-    }
-
-    return -1;
+static struct ChildRecord *
+FindFirstChildSlot(void)
+{
+    FOREACH_CHILD(child) {
+	if (child->pid) return child;
+    } END_FOREACH_CHILD;
+    return NULL;
 }
 
-static BOOL CloseChildHandle(pid_t pid)
+static struct ChildRecord *
+FindChildSlot(pid_t pid)
 {
-    int slot;
-
-    slot = FindChildSlot(pid);
-    if (slot < 0) {
-	return FALSE;
-    }
-    ChildRecord[slot].inuse = FALSE;
 
-    return CloseHandle(ChildRecord[slot].hProcess);
+    FOREACH_CHILD(child) {
+	if (child->pid == pid) {
+	    return child;
+	}
+    } END_FOREACH_CHILD;
+    return NULL;
 }
 
-static int FindFreeChildSlot(void)
+static struct ChildRecord *
+FindPipedChildSlot(FILE *fp)
 {
-    int slot;
-
-    for (slot = 0; slot < MAXCHILDNUM && ChildRecord[slot].inuse; slot++)
-	;
-    if (slot >= MAXCHILDNUM) {
-	return -1;
-    }
-
-    ChildRecord[slot].inuse = TRUE;
-    ChildRecord[slot].pid = -1;
-    ChildRecord[slot].hProcess = NULL;
-
-    return slot;
+    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;
+}
 
-// popen stuff
-
-//
-// use these so I can remember which index is which
-//
-
-#define NtPipeRead  0	   // index of pipe read descriptor
-#define NtPipeWrite 1	   // index of pipe write descriptor
-
-#define NtPipeSize  1024   // size of pipe buffer
-
-#define MYPOPENSIZE 256	   // size of book keeping structure
-
-struct {
-    int inuse;
-    int pid;
-    FILE *pipe;
-} MyPopenRecord[MYPOPENSIZE];
 
 int SafeFree(char **vec, int vecc)
@@ -452,33 +450,9 @@ mypopen (char *cmd, char *mode) 
     int reading;
     int pipemode;
-    int pid;
-    int slot;
+    struct ChildRecord* child;
     BOOL fRet;
     HANDLE hInFile, hOutFile;
     SECURITY_ATTRIBUTES sa;
     int fd;
-    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;
-    }
 
     //
@@ -503,8 +477,14 @@ mypopen (char *cmd, char *mode) 
 
     if (reading) {
-	pid = win32_exec_and_nowait(cmd, &sa, NULL, hOutFile, NULL);
+	child = CreateChild(cmd, &sa, NULL, hOutFile, NULL);
     }
     else {
-	pid = win32_exec_and_nowait(cmd, &sa, hInFile, NULL, NULL);
+	child = CreateChild(cmd, &sa, hInFile, NULL, NULL);
+    }
+
+    if (!child) {
+	CloseHandle(hInFile);
+	CloseHandle(hOutFile);
+	rb_sys_fail("mypopen: CreateChild");
     }
 
@@ -520,5 +500,5 @@ mypopen (char *cmd, char *mode) 
     if (fd == -1) {
 	CloseHandle(reading ? hInFile : hOutFile);
-	CloseChildHandle(pid);
+	CloseChildHandle(child);
 	rb_sys_fail("mypopen: _open_osfhandle");
     }
@@ -526,11 +506,9 @@ mypopen (char *cmd, char *mode) 
     if ((fp = (FILE *) fdopen(fd, mode)) == NULL) {
 	_close(fd);
-	CloseChildHandle(pid);
+	CloseChildHandle(child);
 	rb_sys_fail("mypopen: fdopen");
     }
 
-    MyPopenRecord[slot].inuse = TRUE;
-    MyPopenRecord[slot].pipe  = fp;
-    MyPopenRecord[slot].pid   = pid;
+    child->pipe = fp;
 
     return fp;
@@ -542,39 +520,23 @@ int
 mypclose(FILE *fp)
 {
-    int i;
-    int status = -1;
-    int ret;
+    struct ChildRecord *child = FindPipedChildSlot(fp);
 
-    Sleep(100);
-    for (i = 0; i < MYPOPENSIZE; i++) {
-	if (MyPopenRecord[i].inuse && MyPopenRecord[i].pipe == fp)
-	    break;
-    }
-    if (i >= MYPOPENSIZE) {
-                rb_fatal("Invalid file pointer passed to mypclose!\n");
+    if (!child) {
+	rb_fatal("Invalid file pointer passed to mypclose!\n");
     }
 
     //
-    // get the return status of the process
-    //
-    rb_syswait(MyPopenRecord[i].pid);
-    status = NUM2INT(rb_last_status);
-
-    //
     // 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 status;
+    rb_syswait(child->pid);
+    return NUM2INT(rb_last_status);
 }
 #endif
@@ -583,15 +545,20 @@ mypclose(FILE *fp)
 
 
-pid_t fork_and_exec(char *cmd)
+int
+do_spawn(cmd)
+char *cmd;
 {
-    return win32_exec_and_nowait(cmd, NULL, NULL, NULL, NULL);
+    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 pid_t win32_exec_and_nowait(char *cmd, SECURITY_ATTRIBUTES *psa, HANDLE hInput, HANDLE hOutput, HANDLE hError)
+static struct ChildRecord *
+CreateChild(char *cmd, SECURITY_ATTRIBUTES *psa, HANDLE hInput, HANDLE hOutput, HANDLE hError)
 {
     BOOL fRet;
-    LPCSTR lpApplicationName = NULL;
-    LPTSTR lpCommandLine;
-    LPTSTR lpCmd2 = NULL;
     DWORD  dwCreationFlags;
     STARTUPINFO aStartupInfo;
@@ -599,18 +566,10 @@ static pid_t win32_exec_and_nowait(char 
     SECURITY_ATTRIBUTES sa;
     char *shell;
-    int slot;
-    static int initialized = 0;
-
+    struct ChildRecord *child;
 
-    if (!initialized++) {
-	for (slot = 0; slot < MAXCHILDNUM; slot++) {
-	    ChildRecord[slot].inuse = FALSE;
-	}
-    }
-
-    slot = FindFreeChildSlot();
-    if (slot < 0) {
-	errno = ENOMEM;	/* or EAGAIN? */
-	return -1;
+    child = FindFreeChildSlot();
+    if (!child) {
+	errno = EAGAIN;
+	return NULL;
     }
 
@@ -647,41 +606,42 @@ static pid_t win32_exec_and_nowait(char 
     dwCreationFlags = (NORMAL_PRIORITY_CLASS);
 
-    lpCommandLine = cmd;
-
-    if ((shell = getenv("RUBY_SHELL")) && NtHasRedirection(cmd)) {
-	lpApplicationName = shell;
-	lpCmd2 = ALLOC_N(char, strlen(lpApplicationName) + 1 + strlen(cmd) + sizeof (" -c "));
-	sprintf(lpCmd2, "%s %s%s", lpApplicationName, " -c ", cmd);
-	lpCommandLine = lpCmd2;
+    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))) {
-	lpApplicationName = shell;
-	lpCmd2 = ALLOC_N(char, strlen(lpApplicationName) + 1 + strlen(cmd) + sizeof (" /c "));
-	sprintf(lpCmd2, "%s %s%s", lpApplicationName, " /c ", cmd);
-	lpCommandLine = lpCmd2;
+	char *tmp = ALLOCA_N(char, strlen(shell) + strlen(cmd) + sizeof (" /c "));
+	sprintf(tmp, "%s /c %s", shell, cmd);
+	cmd = tmp;
+    }
+    else {
+	shell = NULL;
     }
 
     RUBY_CRITICAL({
-	fRet = CreateProcess(lpApplicationName, lpCommandLine, psa, psa,
+	fRet = CreateProcess(shell, cmd, psa, psa,
 			     psa->bInheritHandle, dwCreationFlags, NULL, NULL,
 			     &aStartupInfo, &aProcessInformation);
 	errno = GetLastError();
     });
-    if (lpCmd2)
-    	free(lpCmd2);
 
     if (!fRet) {
-	ChildRecord[slot].inuse = FALSE;
-	rb_sys_fail("win32_exec_and_wait: CreateProcess");
+	child->pid = 0;		/* release the slot */
+	return NULL;
     }
 
     CloseHandle(aProcessInformation.hThread);
 
-    ChildRecord[slot].hProcess = aProcessInformation.hProcess;
-    ChildRecord[slot].pid = (pid_t)aProcessInformation.dwProcessId;
+    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 ChildRecord[slot].pid;
+    return child;
 }
 
@@ -2314,20 +2274,15 @@ waitpid (pid_t pid, int *stat_loc, int o
     DWORD exitcode;
     int ret;
-    int slot;
+    struct ChildRecord* child;
 
     if (pid == -1) {
-	for (slot = 0; slot < MAXCHILDNUM && !ChildRecord[slot].inuse; slot++)
-	    ;
-	if (slot >= MAXCHILDNUM) {
-	    errno = ECHILD;
-	    return -1;
-	}
+	child = FindFirstChildSlot();
     }
     else {
-	slot = FindChildSlot(pid);
-	if (slot < 0) {
-	    errno = ECHILD;
-	    return -1;
-	}
+	child = FindChildSlot(pid);
+    }
+    if (!child) {
+	errno = ECHILD;
+	return -1;
     }
 
@@ -2339,5 +2294,5 @@ waitpid (pid_t pid, int *stat_loc, int o
 
     for (;;) {
-	if (!GetExitCodeProcess(ChildRecord[slot].hProcess, &exitcode)) {
+	if (!GetExitCodeProcess(child->hProcess, &exitcode)) {
 	    /* If an error occured, return immediatly. */
 	    errno = GetLastError();
@@ -2345,6 +2300,5 @@ waitpid (pid_t pid, int *stat_loc, int o
 		errno = ECHILD;
 	    }
-	    CloseHandle(ChildRecord[slot].hProcess);
-	    ChildRecord[slot].inuse = FALSE;
+	    CloseChildHandle(child);
 	    pid = -1;
 	    break;
@@ -2352,13 +2306,12 @@ waitpid (pid_t pid, int *stat_loc, int o
 	else if (exitcode != STILL_ACTIVE) {
 	    /* If already died, return immediatly. */
-	    pid = ChildRecord[slot].pid;
-	    CloseHandle(ChildRecord[slot].hProcess);
-	    ChildRecord[slot].inuse = FALSE;
-	    *stat_loc = exitcode << 8;
+	    pid = child->pid;
+	    CloseChildHandle(child);
+	    if (stat_loc) *stat_loc = exitcode << 8;
 	    break;
 	}
 
 	/* wait... */
-	if (wait_events(ChildRecord[slot].hProcess, timeout) != WAIT_OBJECT_0) {
+	if (wait_events(child->hProcess, timeout) != WAIT_OBJECT_0) {
 	    /* still active */
 	    pid = 0;


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread