[前][次][番号順一覧][スレッド一覧]

ruby-changes:11408

From: nobu <ko1@a...>
Date: Sun, 22 Mar 2009 14:52:11 +0900 (JST)
Subject: [ruby-changes:11408] Ruby:r23031 (trunk): * win32/win32.c (rb_w32_spawn, rb_w32_aspawn): use NULL as

nobu	2009-03-22 14:51:58 +0900 (Sun, 22 Mar 2009)

  New Revision: 23031

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=23031

  Log:
    * win32/win32.c (rb_w32_spawn, rb_w32_aspawn): use NULL as
      application name for batch files.

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/test_process.rb
    trunk/version.h
    trunk/win32/win32.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 23030)
+++ ChangeLog	(revision 23031)
@@ -1,3 +1,8 @@
+Sun Mar 22 14:51:55 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* win32/win32.c (rb_w32_spawn, rb_w32_aspawn): use NULL as
+	  application name for batch files.
+
 Sat Mar 21 15:54:41 2009  Tanaka Akira  <akr@f...>
 
 	* ext/openssl/ossl_ssl.c (write_would_block): defined.
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 23030)
+++ win32/win32.c	(revision 23031)
@@ -1005,6 +1005,18 @@
     return child;
 }
 
+static int
+is_batch(const char *cmd)
+{
+    int len = strlen(cmd);
+    if (len <= 4) return 0;
+    cmd += len - 4;
+    if (*cmd++ != '.') return 0;
+    if (strcasecmp(cmd, "bat") == 0) return 1;
+    if (strcasecmp(cmd, "cmd") == 0) return 1;
+    return 0;
+}
+
 rb_pid_t
 rb_w32_spawn(int mode, const char *cmd, const char *prog)
 {
@@ -1043,45 +1055,52 @@
 	}
 	else {
 	    int len = 0, quote = (*cmd == '"') ? '"' : 0;
-	    shell = NULL;
+	    const char *comspec = shell;
 	    for (prog = cmd + !!quote;; prog = CharNext(prog)) {
 		if (!*prog) {
 		    len = prog - cmd;
 		    shell = cmd;
 		    break;
 		}
-		if (*prog == quote) {
+		if ((unsigned char)*prog == quote) {
 		    len = prog++ - cmd - 1;
 		    STRNDUPA(p, cmd + 1, len);
 		    shell = p;
 		    break;
 		}
 		if (quote) continue;
-		if (strchr("*?\"", *prog)) {
+		if (ISSPACE(*prog) || strchr("<>|*?\"", *prog)) {
 		    len = prog - cmd;
 		    STRNDUPA(p, cmd, len);
 		    shell = p;
 		    break;
 		}
-		if (ISSPACE(*prog) || strchr("<>|", *prog)) {
-		    len = prog - cmd;
-		    STRNDUPA(p, cmd, len);
-		    shell = p;
-		    break;
-		}
 	    }
 	    shell = dln_find_exe_r(shell, NULL, fbuf, sizeof(fbuf));
-	    if (shell == fbuf) {
-		len += strlen(prog) + (quote ? 2 : 0) + 1;
-		cmd = p = ALLOCA_N(char, len);
-		if (quote) *p++ = '"';
-		p += strlcpy(p, fbuf, --len);
-		if (quote) *p++ = '"';
-		p += strlcpy(p, prog, --len);
-		if (quote) shell = NULL;
+	    if (!shell) {
+		shell = comspec;
 	    }
 	    else {
-		shell = p;
+		len = strlen(shell);
+		if (strchr(shell, ' ')) quote = -1;
+		if (shell == fbuf) {
+		    p = fbuf;
+		}
+		else if (shell != p && strchr(shell, '/')) {
+		    STRNDUPA(p, shell, len);
+		    shell = p;
+		}
+		if (p) translate_char(p, '/', '\\');
+		if (is_batch(shell)) {
+		    int alen = strlen(prog);
+		    cmd = p = ALLOCA_N(char, len + alen + (quote ? 2 : 0) + 1);
+		    if (quote) *p++ = '"';
+		    memcpy(p, shell, len);
+		    p += len;
+		    if (quote) *p++ = '"';
+		    memcpy(p, prog, alen + 1);
+		    shell = 0;
+		}
 	    }
 	}
     }
@@ -1092,7 +1111,7 @@
 rb_pid_t
 rb_w32_aspawn(int mode, const char *prog, char *const *argv)
 {
-    int len, differ = 0, c_switch = 0;
+    int len, c_switch = 0;
     BOOL ntcmd = FALSE, tmpnt;
     const char *shell;
     char *cmd, fbuf[MAXPATHLEN];
@@ -1105,40 +1124,41 @@
 	ntcmd = tmpnt;
 	prog = shell;
 	c_switch = 1;
-	differ = 1;
     }
     else if ((cmd = dln_find_exe_r(prog, NULL, fbuf, sizeof(fbuf)))) {
 	if (cmd == prog) strlcpy(cmd = fbuf, prog, sizeof(fbuf));
 	translate_char(cmd, '/', '\\');
 	prog = cmd;
-	argv++;
-	differ = 1;
     }
     else if (strchr(prog, '/')) {
-	strlcpy(fbuf, prog, sizeof(fbuf));
-	translate_char(fbuf, '/', '\\');
-	prog = fbuf;
-	argv++;
-	differ = 1;
+	len = strlen(prog);
+	if (len < sizeof(fbuf))
+	    strlcpy(cmd = fbuf, prog, sizeof(fbuf));
+	else
+	    STRNDUPA(cmd, prog, len);
+	translate_char(cmd, '/', '\\');
+	prog = cmd;
     }
-    if (differ) {
+    if (c_switch || is_batch(prog)) {
 	char *progs[2];
 	progs[0] = (char *)prog;
 	progs[1] = NULL;
 	len = argv_size(progs, ntcmd);
 	if (c_switch) len += 3;
+	else ++argv;
 	if (argv[0]) len += argv_size(argv, ntcmd);
 	cmd = ALLOCA_N(char, len);
 	join_argv(cmd, progs, ntcmd);
 	if (c_switch) strlcat(cmd, " /c", len);
 	if (argv[0]) join_argv(cmd + strlcat(cmd, " ", len), argv, ntcmd);
-	prog = 0;
+	prog = c_switch ? shell : 0;
     }
     else {
 	len = argv_size(argv, FALSE);
 	cmd = ALLOCA_N(char, len);
 	join_argv(cmd, argv, FALSE);
     }
+
     return child_result(CreateChild(cmd, prog, NULL, NULL, NULL, NULL), mode);
 }
 
Index: version.h
===================================================================
--- version.h	(revision 23030)
+++ version.h	(revision 23031)
@@ -1,5 +1,5 @@
 #define RUBY_VERSION "1.9.2"
-#define RUBY_RELEASE_DATE "2009-03-21"
+#define RUBY_RELEASE_DATE "2009-03-22"
 #define RUBY_PATCHLEVEL -1
 #define RUBY_BRANCH_NAME "trunk"
 
@@ -8,7 +8,7 @@
 #define RUBY_VERSION_TEENY 1
 #define RUBY_RELEASE_YEAR 2009
 #define RUBY_RELEASE_MONTH 3
-#define RUBY_RELEASE_DAY 21
+#define RUBY_RELEASE_DAY 22
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
Index: test/ruby/test_process.rb
===================================================================
--- test/ruby/test_process.rb	(revision 23030)
+++ test/ruby/test_process.rb	(revision 23031)
@@ -824,6 +824,15 @@
       assert_match(/\Ataka pid=\d+ ppid=\d+\z/, result1)
       assert_match(/\Ataki pid=\d+ ppid=\d+\z/, result2)
       assert_not_equal(result1[/\d+/].to_i, status.pid)
+
+      if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+        Dir.mkdir(path = "path with space")
+        write_file(bat = path + "/bat test.bat", "@echo %1>out")
+        system(bat, "foo 'bar'")
+        assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
+        system(%[#{bat.dump} "foo 'bar'"])
+        assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
+      end
     }
   end
 
@@ -847,6 +856,23 @@
       assert_match(/\Ataku pid=\d+ ppid=\d+\z/, result1)
       assert_match(/\Atake pid=\d+ ppid=\d+\z/, result2)
       assert_not_equal(result1[/\d+/].to_i, status.pid)
+
+      if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+        Dir.mkdir(path = "path with space")
+        write_file(bat = path + "/bat test.bat", "@echo %1>out")
+        pid = spawn(bat, "foo 'bar'")
+        Process.wait pid
+        status = $?
+        assert(status.exited?)
+        assert(status.success?)
+        assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
+        pid = spawn(%[#{bat.dump} "foo 'bar'"])
+        Process.wait pid
+        status = $?
+        assert(status.exited?)
+        assert(status.success?)
+        assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
+      end
     }
   end
 
@@ -871,9 +897,11 @@
 
       if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
         Dir.mkdir(path = "path with space")
-        write_file(bat = path + "/battest.bat", "@echo %1")
+        write_file(bat = path + "/bat test.bat", "@echo %1")
         r = IO.popen([bat, "foo 'bar'"]) {|f| f.read}
         assert_equal(%["foo 'bar'"\n], r, '[ruby-core:22960]')
+        r = IO.popen(%[#{bat.dump} "foo 'bar'"]) {|f| f.read}
+        assert_equal(%["foo 'bar'"\n], r, '[ruby-core:22960]')
       end
     }
   end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]