ruby-changes:29657
From: nobu <ko1@a...>
Date: Sun, 30 Jun 2013 10:59:49 +0900 (JST)
Subject: [ruby-changes:29657] nobu:r41710 (trunk): win32.c: use backslash
nobu 2013-06-30 10:59:25 +0900 (Sun, 30 Jun 2013) New Revision: 41710 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41710 Log: win32.c: use backslash * win32/win32.c (join_argv): use backslash instead of slash in program path, otherwise cannot invoke "./c\u{1ee7}a.exe" for some reason. [ruby-core:24309] [Bug #1771] Modified files: trunk/ChangeLog trunk/test/ruby/test_process.rb trunk/win32/win32.c Index: ChangeLog =================================================================== --- ChangeLog (revision 41709) +++ ChangeLog (revision 41710) @@ -1,4 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 -Sun Jun 30 10:59:18 2013 Nobuyoshi Nakada <nobu@r...> +Sun Jun 30 10:59:23 2013 Nobuyoshi Nakada <nobu@r...> + + * win32/win32.c (join_argv): use backslash instead of slash in program + path, otherwise cannot invoke "./c\u{1ee7}a.exe" for some reason. + [ruby-core:24309] [Bug #1771] * io.c (spawnv, spawn): use UTF-8 spawn family. [Bug #1771] Index: win32/win32.c =================================================================== --- win32/win32.c (revision 41709) +++ win32/win32.c (revision 41710) @@ -980,7 +980,7 @@ rb_w32_get_osfhandle(int fh) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L980 /* License: Ruby's */ static int -join_argv(char *cmd, char *const *argv, BOOL escape, UINT cp) +join_argv(char *cmd, char *const *argv, BOOL escape, UINT cp, int backslash) { const char *p, *s; char *q, *const *t; @@ -1034,6 +1034,11 @@ join_argv(char *cmd, char *const *argv, https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L1034 if (quote) len++; if (q) { memcpy(q, s, n); + if (backslash > 0) { + --backslash; + q[n] = 0; + translate_char(q, '/', '\\', cp); + } q += n; if (quote) *q++ = '"'; *q++ = ' '; @@ -1205,6 +1210,8 @@ w32_spawn(int mode, const char *cmd, con https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L1210 rb_pid_t ret = -1; VALUE v = 0; VALUE v2 = 0; + int sep = 0; + char *cmd_sep = NULL; if (check_spawn_mode(mode)) return -1; @@ -1222,8 +1229,11 @@ w32_spawn(int mode, const char *cmd, con https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L1229 int nt; while (ISSPACE(*cmd)) cmd++; if ((shell = getenv("RUBYSHELL")) && (redir = has_redirection(cmd, cp))) { - char *tmp = ALLOCV(v, strlen(shell) + strlen(cmd) + sizeof(" -c ") + 2); - sprintf(tmp, "%s -c \"%s\"", shell, cmd); + size_t shell_len = strlen(shell); + char *tmp = ALLOCV(v, shell_len + strlen(cmd) + sizeof(" -c ") + 2); + memcpy(tmp, shell, shell_len + 1); + translate_char(tmp, '/', '\\', cp); + sprintf(tmp + shell_len, " -c \"%s\"", cmd); cmd = tmp; } else if ((shell = getenv("COMSPEC")) && @@ -1236,27 +1246,44 @@ w32_spawn(int mode, const char *cmd, con https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L1246 } else { int len = 0, quote = (*cmd == '"') ? '"' : (*cmd == '\'') ? '\'' : 0; + int slash = 0; for (prog = cmd + !!quote;; prog = CharNextExA(cp, prog, 0)) { + if (*prog == '/') slash = 1; if (!*prog) { len = prog - cmd; + if (slash) { + STRNDUPV(p, v2, cmd, len); + cmd = p; + } shell = cmd; break; } if ((unsigned char)*prog == quote) { len = prog++ - cmd - 1; - STRNDUPV(p, v2, cmd + 1, len); + STRNDUPV(p, v2, cmd + 1 - slash, len + (slash ? strlen(prog) + 2 : 0)); + if (slash) { + cmd = p++; + sep = *(cmd_sep = &p[len + 1]); + *cmd_sep = '\0'; + } shell = p; break; } if (quote) continue; if (ISSPACE(*prog) || strchr("<>|*?\"", *prog)) { len = prog - cmd; - STRNDUPV(p, v2, cmd, len); + STRNDUPV(p, v2, cmd, len + (slash ? strlen(prog) : 0)); + if (slash) { + cmd = p; + sep = *(cmd_sep = &p[len]); + *cmd_sep = '\0'; + } shell = p; break; } } shell = dln_find_exe_r(shell, NULL, fbuf, sizeof(fbuf)); + if (p && slash) translate_char(p, '/', '\\', cp); if (!shell) { shell = p ? p : cmd; } @@ -1285,10 +1312,11 @@ w32_spawn(int mode, const char *cmd, con https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L1312 } } - if (!e && cmd && !(wcmd = mbstr_to_wstr(cp, cmd, -1, NULL))) e = E2BIG; - if (v) ALLOCV_END(v); if (!e && shell && !(wshell = mbstr_to_wstr(cp, shell, -1, NULL))) e = E2BIG; if (v2) ALLOCV_END(v2); + if (cmd_sep) *cmd_sep = sep; + if (!e && cmd && !(wcmd = mbstr_to_wstr(cp, cmd, -1, NULL))) e = E2BIG; + if (v) ALLOCV_END(v); if (!e) { ret = child_result(CreateChild(wcmd, wshell, NULL, NULL, NULL, NULL, 0), mode); @@ -1355,20 +1383,20 @@ w32_aspawn_flags(int mode, const char *p https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L1383 char *progs[2]; progs[0] = (char *)prog; progs[1] = NULL; - len = join_argv(NULL, progs, ntcmd, cp); + len = join_argv(NULL, progs, ntcmd, cp, 1); if (c_switch) len += 3; else ++argv; - if (argv[0]) len += join_argv(NULL, argv, ntcmd, cp); + if (argv[0]) len += join_argv(NULL, argv, ntcmd, cp, 0); cmd = ALLOCV(v, len); - join_argv(cmd, progs, ntcmd, cp); + join_argv(cmd, progs, ntcmd, cp, 1); if (c_switch) strlcat(cmd, " /c", len); - if (argv[0]) join_argv(cmd + strlcat(cmd, " ", len), argv, ntcmd, cp); + if (argv[0]) join_argv(cmd + strlcat(cmd, " ", len), argv, ntcmd, cp, 0); prog = c_switch ? shell : 0; } else { - len = join_argv(NULL, argv, FALSE, cp); + len = join_argv(NULL, argv, FALSE, cp, 1); cmd = ALLOCV(v, len); - join_argv(cmd, argv, FALSE, cp); + join_argv(cmd, argv, FALSE, cp, 1); } if (!e && cmd && !(wcmd = mbstr_to_wstr(cp, cmd, -1, NULL))) e = E2BIG; Index: test/ruby/test_process.rb =================================================================== --- test/ruby/test_process.rb (revision 41709) +++ test/ruby/test_process.rb (revision 41710) @@ -1618,7 +1618,7 @@ EOS https://github.com/ruby/ruby/blob/trunk/test/ruby/test_process.rb#L1618 [ "\u{7d05 7389}", "zuf\u{00E4}llige_\u{017E}lu\u{0165}ou\u{010D}k\u{00FD}_\u{10D2 10D0 10DB 10D4 10DD 10E0 10D4 10D1}_\u{0440 0430 0437 043B 043E 0433 0430}_\u{548C 65B0 52A0 5761 4EE5 53CA 4E1C}", - # "c\u{1EE7}a", # work with a backslash, but not with a slash, for some reason. + "c\u{1EE7}a", ].each do |name| msg = "#{bug1771} #{name}" exename = "./#{name}.exe" -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/