[#11952] NORETURN — "Nobuyoshi.Nakada" <nobu.nakada@...>

なかだです。

24 messages 2001/01/10
[#11956] Re: NORETURN — WATANABE Hirofumi <eban@...> 2001/01/10

わたなべです.

[#11957] Re: NORETURN — matz@... (Yukihiro Matsumoto) 2001/01/10

まつもと ゆきひろです

[#11958] Re: NORETURN — WATANABE Hirofumi <eban@...> 2001/01/10

わたなべです.

[#11959] CVS branches (Re: Re: NORETURN) — matz@... (Yukihiro Matsumoto) 2001/01/10

[#12087] string#index, gsub, []= のバグ? — Beyond <beyond@...>

18 messages 2001/01/27
[#12091] Re: string#index, gsub, []= のバグ? — matz@... (Yukihiro Matsumoto) 2001/01/27

まつもと ゆきひろです

[ruby-dev:12084] [patch] mswin32 system()

From: "U.Nakamura" <usa@...>
Date: 2001-01-27 10:02:19 UTC
List: ruby-dev #12084
こんにちは、なかむら(う)です。

いろいろ考えてみたのですが、do_spawn()の中でどんなに工夫して引数を
分割しても、結局のところspawnvpe()の中でくっつけてCreateProcess()を
呼んでいるわけなので、いっそのこと分割しないで自前でCreateProcess()
を呼んだ方がいいんじゃないかと思い始めました。

というわけで、実験的パッチです。
ご意見よろしくお願いします。

--- current/win32/win32.c	Sun Jan 14 18:25:20 2001
+++ mytree/win32/win32.c	Sat Jan 27 18:46:54 2001
@@ -729,20 +729,19 @@ int
 do_spawn(cmd)
 char *cmd;
 {
-    register char **a;
-    register char *s;
-    char **argv;
+    register char *s, *p;
     int status = -1;
-    char *shell, *cmd2;
+    char *shell;
     int mode = NtSyncProcess ? P_WAIT : P_NOWAIT;
-    char quote;
     char *exec;
+    PROCESS_INFORMATION pi;
+    STARTUPINFO si;
+
 
     /* 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));
 
@@ -774,55 +773,67 @@ char *cmd;
 	}
     }
 
-    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++;
+    exec = ALLOC_N(char, (strlen(cmd) + 1));
+    p = exec;
+    s = cmd;
+    if (*cmd == '"') {
+	*s++;
+	for ( ; ; ) {
+	    if (*s == '"' || *s == '\0') {
+	        break;
+	    }
+	    else if (*s == '\\' && *(s + 1) == '"') {
+		*s++;
+		*p++ = *s++;
+	    }
+	    else if (IsDBCSLeadByte(*s)) {
+		*p++ = *s++;
+		*p++ = *s++;
+	    }
+	    else {
+	        *p++ = *s++;
 	    }
 	}
-	else if (*s) {
-	    *(a++) = s;
-	    while (*s && !isspace(*s)) s++;
-	}
-	if (*s)
-	    *s++ = '\0';
+	*p = '\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;
+    else {
+	for ( ; ; ) {
+	    if (*s == ' ' || *s == '\t' || *s == '\0') {
+		break;
+	    }
+	    else if (*s == '\\' && *(s + 1) == '"') {
+		*s++;
+		*p++ = *s++;
+	    }
+	    else if (IsDBCSLeadByte(*s)) {
+		*p++ = *s++;
+		*p++ = *s++;
+	    }
+	    else {
+	        *p++ = *s++;
+	    }
 	}
+	*p = '\0';
     }
+
+    memset(&si, 0, sizeof(si));
+    si.cb = sizeof(si);
+    if (!CreateProcess(exec, cmd, NULL, NULL, TRUE, 0, environ, NULL, &si, &pi)) {
+	free(exec);
+	return -1;
+    }
+
+    if (NtSyncProcess) {
+	WaitForSingleObject(pi.hProcess, -1);
+	GetExitCodeProcess(pi.hProcess, &status);
+	CloseHandle(pi.hProcess);
+    }
+    else {
+	status = (int)pi.hProcess;
+    }
+    CloseHandle(pi.hThread);
+
     free(exec);
-    free(cmd2);
-    free(argv);
     return (int)((status & 0xff) << 8);
 }
 


それでは。

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

In This Thread

Prev Next