From 6a64e9e4ac2318cba4f9e70c66cf82885da9f46a Mon Sep 17 00:00:00 2001 From: nobu Date: Sun, 22 Mar 2009 05:51:58 +0000 Subject: * win32/win32.c (rb_w32_spawn, rb_w32_aspawn): use NULL as application name for batch files. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23031 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++ test/ruby/test_process.rb | 30 +++++++++++++++++- version.h | 4 +-- win32/win32.c | 78 +++++++++++++++++++++++++++++------------------ 4 files changed, 85 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 67184f7601..d0e4c5ef0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sun Mar 22 14:51:55 2009 Nobuyoshi Nakada + + * 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 * ext/openssl/ossl_ssl.c (write_would_block): defined. diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 57084f6f84..4e6097bbc1 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -824,6 +824,15 @@ class TestProcess < Test::Unit::TestCase 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 @@ class TestProcess < Test::Unit::TestCase 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 @@ class TestProcess < Test::Unit::TestCase 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 diff --git a/version.h b/version.h index b8dcfbf739..329f02f8d2 100644 --- a/version.h +++ b/version.h @@ -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[]; diff --git a/win32/win32.c b/win32/win32.c index e907422dbe..5ffe59807e 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -1005,6 +1005,18 @@ CreateChild(const char *cmd, const char *prog, SECURITY_ATTRIBUTES *psa, 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,27 +1055,21 @@ rb_w32_spawn(int mode, const char *cmd, const char *prog) } 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)) { - len = prog - cmd; - STRNDUPA(p, cmd, len); - shell = p; - break; - } - if (ISSPACE(*prog) || strchr("<>|", *prog)) { + if (ISSPACE(*prog) || strchr("<>|*?\"", *prog)) { len = prog - cmd; STRNDUPA(p, cmd, len); shell = p; @@ -1071,17 +1077,30 @@ rb_w32_spawn(int mode, const char *cmd, const char *prog) } } 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_w32_spawn(int mode, const char *cmd, const char *prog) 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 @@ rb_w32_aspawn(int mode, const char *prog, char *const *argv) 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); } -- cgit v1.2.3