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

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/

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