aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--test/ruby/test_process.rb30
-rw-r--r--version.h4
-rw-r--r--win32/win32.c78
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 <nobu@ruby-lang.org>
+
+ * 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@fsij.org>
* 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);
}