aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--include/ruby/win32.h2
-rw-r--r--win32/win32.c48
3 files changed, 45 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 1009aa5c32..b7dda9472e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Tue Jan 13 02:21:43 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * win32/win32.c (internal_cmd_match): extracted from
+ is_internal_cmd.
+
+ * win32/win32.c (argv_size, join_argv): escapes redirection, pipe
+ and carret punctuations with carrets.
+
+ * win32/win32.c (rb_w32_aspawn): ditto, and redirections and pipe
+ have no meanings.
+
Tue Jan 13 02:07:38 2009 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb: use Encoding.find("locale") instaed of
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index 582348d338..46388a3ae2 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -247,8 +247,6 @@ extern int chown(const char *, int, int);
extern int link(const char *, const char *);
extern int gettimeofday(struct timeval *, struct timezone *);
extern rb_pid_t waitpid (rb_pid_t, int *, int);
-extern int rb_w32_argv_size(char *const *);
-extern char *rb_w32_join_argv(char *, char *const *);
extern rb_pid_t rb_w32_spawn(int, const char *, const char*);
extern rb_pid_t rb_w32_aspawn(int, const char *, char *const *);
extern int kill(int, int);
diff --git a/win32/win32.c b/win32/win32.c
index 27e55bcae9..e8907b6647 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -668,10 +668,12 @@ is_command_com(const char *interp)
return 0;
}
+static int internal_cmd_match(const char *cmdname, int nt);
+
static int
is_internal_cmd(const char *cmd, int nt)
{
- char cmdname[9], *b = cmdname, c, **nm;
+ char cmdname[9], *b = cmdname, c;
do {
if (!(c = *cmd++)) return 0;
@@ -691,6 +693,14 @@ is_internal_cmd(const char *cmd, int nt)
return 0;
}
*b = 0;
+ return internal_cmd_match(cmdname, nt);
+}
+
+static int
+internal_cmd_match(const char *cmdname, int nt)
+{
+ char **nm;
+
nm = bsearch(cmdname, szInternalCmds,
sizeof(szInternalCmds) / sizeof(*szInternalCmds),
sizeof(*szInternalCmds),
@@ -706,8 +716,8 @@ rb_w32_get_osfhandle(int fh)
return _get_osfhandle(fh);
}
-int
-rb_w32_argv_size(char *const *argv)
+static int
+argv_size(char *const *argv, BOOL escape)
{
const char *p;
char *const *t;
@@ -719,6 +729,10 @@ rb_w32_argv_size(char *const *argv)
case '\\':
++bs;
break;
+ case '<': case '>': case '|': case '^':
+ bs = 0;
+ if (escape && !quote) n++;
+ break;
case '"':
n += bs + 1; bs = 0;
quote = 1;
@@ -737,8 +751,8 @@ rb_w32_argv_size(char *const *argv)
return len;
}
-char *
-rb_w32_join_argv(char *cmd, char *const *argv)
+static char *
+join_argv(char *cmd, char *const *argv, BOOL escape)
{
const char *p, *s;
char *q, *const *t;
@@ -760,6 +774,12 @@ rb_w32_join_argv(char *cmd, char *const *argv)
memcpy(q, s, n = p - s); q += n; s = p;
memset(q, '\\', ++bs); q += bs; bs = 0;
break;
+ case '<': case '>': case '|': case '^':
+ if (escape && !quote) {
+ memcpy(q, s, n = p - s); q += n; s = p;
+ *q++ = '^';
+ break;
+ }
default:
bs = 0;
p = CharNext(p) - 1;
@@ -990,7 +1010,8 @@ 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, differ = 0, c_switch = 0;
+ BOOL ntcmd = FALSE;
const char *shell;
char *cmd, fbuf[MAXPATHLEN];
@@ -998,8 +1019,7 @@ rb_w32_aspawn(int mode, const char *prog, char *const *argv)
if (!prog) prog = argv[0];
if ((shell = getenv("COMSPEC")) &&
- (has_redirection(prog) ||
- is_internal_cmd(prog, !is_command_com(shell)))) {
+ internal_cmd_match(prog, ntcmd = !is_command_com(shell))) {
prog = shell;
c_switch = 1;
differ = 1;
@@ -1022,18 +1042,18 @@ rb_w32_aspawn(int mode, const char *prog, char *const *argv)
char *progs[2];
progs[0] = (char *)prog;
progs[1] = NULL;
- len = rb_w32_argv_size(progs);
+ len = argv_size(progs, ntcmd);
if (c_switch) len += 3;
- if (argv[0]) len += rb_w32_argv_size(argv);
+ if (argv[0]) len += argv_size(argv, ntcmd);
cmd = ALLOCA_N(char, len);
- rb_w32_join_argv(cmd, progs);
+ join_argv(cmd, progs, ntcmd);
if (c_switch) strlcat(cmd, " /c", len);
- if (argv[0]) rb_w32_join_argv(cmd + strlcat(cmd, " ", len), argv);
+ if (argv[0]) join_argv(cmd + strlcat(cmd, " ", len), argv, ntcmd);
}
else {
- len = rb_w32_argv_size(argv);
+ len = argv_size(argv, FALSE);
cmd = ALLOCA_N(char, len);
- rb_w32_join_argv(cmd, argv);
+ join_argv(cmd, argv, FALSE);
}
return child_result(CreateChild(cmd, prog, NULL, NULL, NULL, NULL), mode);
}