summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-03-20 23:17:42 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-03-20 23:17:42 +0000
commitba1a12170b972485ee5271d7d84e2b79382f27a9 (patch)
treed2c30a93d747cafc5736ddd0124b41ffd72c21a7 /win32
parent148f58c2dff689ef6b62bf5fe36be96a839e5817 (diff)
* win32/win32.c (rb_w32_spawn, rb_w32_aspawn): omit program name
if actual program path is found. [ruby-core:22960] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23023 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c167
1 files changed, 117 insertions, 50 deletions
diff --git a/win32/win32.c b/win32/win32.c
index 19b122041d..ddbbe41c8b 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -845,7 +845,7 @@ join_argv(char *cmd, char *const *argv, BOOL escape)
for (t = argv, q = cmd; p = *t; t++) {
quote = 0;
s = p;
- if (!*p || strpbrk(p, " \t\"")) {
+ if (!*p || strpbrk(p, " \t\"'")) {
quote = 1;
*q++ = '"';
}
@@ -1018,6 +1018,10 @@ rb_w32_spawn(int mode, const char *cmd, const char *prog)
if (!(p = dln_find_exe_r(prog, NULL, fbuf, sizeof(fbuf)))) {
shell = prog;
}
+ else {
+ shell = p;
+ translate_char(p, '/', '\\');
+ }
}
else {
int redir = -1;
@@ -1038,55 +1042,49 @@ rb_w32_spawn(int mode, const char *cmd, const char *prog)
cmd = tmp;
}
else {
- int len = 0;
- if (*cmd == '"') {
- for (prog = cmd + 1; *prog && *prog != '"'; prog = CharNext(prog));
- len = prog - cmd - 1;
- STRNDUPA(p, cmd + 1, len);
- p = dln_find_exe_r(p, NULL, fbuf, sizeof(fbuf));
- if (p) goto command_found;
- }
- for (prog = cmd; *prog; prog = CharNext(prog)) {
- if (ISSPACE(*prog)) {
+ int len = 0, quote = (*cmd == '"') ? '"' : 0;
+ shell = NULL;
+ for (prog = cmd + !!quote;; prog = CharNext(prog)) {
+ if (!*prog) {
len = prog - cmd;
- do ++prog; while (ISSPACE(*prog));
+ shell = cmd;
break;
}
- else {
- len = 0;
- }
- }
- if (!len) len = strlen(cmd);
-
- shell = NULL;
- prog = cmd;
- for (;;) {
- if (!*prog) {
- p = dln_find_exe_r(cmd, NULL, fbuf, sizeof(fbuf));
+ if (*prog == quote) {
+ len = prog++ - cmd - 1;
+ STRNDUPA(p, cmd + 1, len);
+ shell = p;
break;
}
- if (strchr(":*?\"/\\", *prog)) {
- if (cmd[len]) {
- STRNDUPA(p, cmd, len);
- }
- p = dln_find_exe_r(p ? p : cmd, NULL, fbuf, sizeof(fbuf));
+ if (quote) continue;
+ if (strchr("*?\"", *prog)) {
+ len = prog - cmd;
+ STRNDUPA(p, cmd, len);
+ shell = p;
break;
}
if (ISSPACE(*prog) || strchr("<>|", *prog)) {
len = prog - cmd;
STRNDUPA(p, cmd, len);
- p = dln_find_exe_r(p, NULL, fbuf, sizeof(fbuf));
+ shell = p;
break;
}
- 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;
+ }
+ else {
+ shell = p;
}
}
}
- if (p) {
- command_found:
- shell = p;
- translate_char(p, '/', '\\');
- }
return child_result(CreateChild(cmd, shell, NULL, NULL, NULL, NULL), mode);
}
@@ -1134,6 +1132,7 @@ rb_w32_aspawn(int mode, const char *prog, char *const *argv)
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;
}
else {
len = argv_size(argv, FALSE);
@@ -1665,6 +1664,17 @@ move_to_next_entry(DIR *dirp)
}
}
+static char *
+win32_conv_from_wstr(const WCHAR *wstr, long *len)
+{
+ UINT cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ char *ptr;
+ *len = WideCharToMultiByte(cp, 0, wstr, -1, NULL, 0, NULL, NULL) - 1;
+ if (!(ptr = malloc(*len + 1))) return 0;
+ WideCharToMultiByte(cp, 0, wstr, -1, ptr, *len + 1, NULL, NULL);
+ return ptr;
+}
+
//
// Readdir just returns the current string pointer and bumps the
// string pointer to the next entry.
@@ -1672,13 +1682,8 @@ move_to_next_entry(DIR *dirp)
static BOOL
win32_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *dummy)
{
- UINT cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
- entry->d_namlen =
- WideCharToMultiByte(cp, 0, file, -1, NULL, 0, NULL, NULL) - 1;
- if (!(entry->d_name = malloc(entry->d_namlen + 1)))
+ if (!(entry->d_name = win32_conv_from_wstr(file, &entry->d_namlen)))
return FALSE;
- WideCharToMultiByte(cp, 0, file, -1, entry->d_name, entry->d_namlen + 1,
- NULL, NULL);
return TRUE;
}
@@ -1708,19 +1713,25 @@ rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
return rb_str_encode(src, rb_enc_from_encoding(enc), ecflags, ecopts);
}
-static BOOL
-ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
+char *
+rb_w32_conv_from_wstr(const WCHAR *wstr, long *lenp, rb_encoding *enc)
{
- VALUE dst = rb_w32_conv_from_wchar(file, enc);
+ VALUE str = rb_w32_conv_from_wchar(wstr, enc);
+ long len;
+ char *ptr;
- if (NIL_P(dst))
- return win32_direct_conv(file, entry, NULL);
+ if (NIL_P(str)) return win32_conv_from_wstr(wstr, lenp);
+ *lenp = len = RSTRING_LEN(str);
+ memcpy(ptr = malloc(len + 1), RSTRING_PTR(str), len);
+ ptr[len] = '\0';
+ return ptr;
+}
- entry->d_namlen = RSTRING_LEN(dst);
- if (!(entry->d_name = malloc(entry->d_namlen + 1)))
+static BOOL
+ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
+{
+ if (!(entry->d_name = rb_w32_conv_from_wstr(file, &entry->d_namlen, enc)))
return FALSE;
- memcpy(entry->d_name, RSTRING_PTR(dst), entry->d_namlen);
- entry->d_name[entry->d_namlen] = '\0';
return TRUE;
}
@@ -5002,3 +5013,59 @@ rb_w32_fsopen(const char *path, const char *mode, int shflags)
return f;
}
#endif
+
+BOOL
+rb_w32_get_special_directory(int n, WCHAR *path)
+{
+ if (!get_special_folder(n, path))
+ return FALSE;
+ regulate_path(path);
+ return TRUE;
+}
+
+static VALUE
+w32_get_special_directory(VALUE self, VALUE num)
+{
+ VALUE str;
+ int n = NUM2INT(num);
+ WCHAR path[_MAX_PATH];
+
+ if (!rb_w32_get_special_directory(n, path)) {
+ rb_sys_fail(0);
+ }
+ str = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
+ OBJ_TAINT(str);
+ return str;
+}
+
+static VALUE
+w32_get_system_directory(VALUE self)
+{
+ VALUE str;
+ WCHAR path[_MAX_PATH];
+
+ if (!get_system_directory(path, numberof(path))) {
+ rb_sys_fail(0);
+ }
+ regulate_path(path);
+ str = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
+ OBJ_TAINT(str);
+ return str;
+}
+
+void
+Init_win32(void)
+{
+ VALUE mWin32 = rb_define_module("Win32");
+ VALUE dir = rb_define_module_under(mWin32, "Dir");
+ rb_define_module_function(dir, "special", w32_get_special_directory, 1);
+ rb_define_module_function(dir, "system", w32_get_system_directory, 0);
+ rb_define_const(dir, "LOCAL_APPDATA", UINT2NUM(CSIDL_LOCAL_APPDATA));
+ rb_define_const(dir, "COMMON_APPDATA", UINT2NUM(CSIDL_COMMON_APPDATA));
+ rb_define_const(dir, "WINDOWS", UINT2NUM(CSIDL_WINDOWS));
+ rb_define_const(dir, "SYSTEM", UINT2NUM(CSIDL_SYSTEM));
+ rb_define_const(dir, "PROFILE", UINT2NUM(CSIDL_PROFILE));
+ rb_define_const(dir, "PERSONAL", UINT2NUM(CSIDL_PERSONAL));
+ rb_define_const(mWin32, "Version", UINT2NUM(rb_w32_osver()));
+ rb_ivar_set(rb_mKernel, rb_intern("@__win32__"), mWin32);
+}