diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-02-16 06:45:32 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-02-16 06:45:32 +0000 |
commit | ccf234f713b0f0b345ecb7acde180032f5aa3a69 (patch) | |
tree | c284a1b3d52c3b37a17591fd6327f2011438653a /win32 | |
parent | 3a3afe8802f260bbde60817101f5d68b0c5e50d1 (diff) | |
download | ruby-ccf234f713b0f0b345ecb7acde180032f5aa3a69.tar.gz ruby-ccf234f713b0f0b345ecb7acde180032f5aa3a69.tar.xz ruby-ccf234f713b0f0b345ecb7acde180032f5aa3a69.zip |
* configure.in: check functions, fork spawnv.
* io.c (rb_io_s_popen): accept argv not only single command line.
* process.c (rb_proc_exec_n): export.
* process.c (rb_check_argv): check if arguments are safe to invoke.
* process.c (rb_fork): retry to fork.
* process.c (rb_spawn): spawn child process asynchronously.
* process.c (rb_f_system): raise an exception if the command could not
execute.
* win32/win32.c (rb_w32_argv_size): count necessary size for joined
arguments.
* win32/win32.c (rb_w32_join_argv): join arguments with quoting.
* win32/win32.c (rb_w32_pipe_exec, rb_w32_spawn, rb_w32_aspawn):
accept program name adding to command line.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@5725 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r-- | win32/win32.c | 170 | ||||
-rw-r--r-- | win32/win32.h | 8 |
2 files changed, 85 insertions, 93 deletions
diff --git a/win32/win32.c b/win32/win32.c index 443646469..7eea4b76b 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -589,8 +589,79 @@ rb_w32_get_osfhandle(int fh) return _get_osfhandle(fh); } +int +rb_w32_argv_size(argv) + char **argv; +{ + char *p, **t; + int len, n, bs, quote; + + for (t = argv, len = 0; *t; t++) { + for (p = *t, n = quote = bs = 0; *p; ++p) { + switch (*p) { + case '\\': + ++bs; + break; + case '"': + n += bs + 1; bs = 0; + quote = 1; + break; + case ' ': case '\t': + quote = 1; + default: + bs = 0; + p = CharNext(p) - 1; + break; + } + } + len += p - *t + n + 1; + if (quote) len += 2; + } + return len; +} + +char * +rb_w32_join_argv(cmd, argv) + char *cmd; + char **argv; +{ + char *p, *q, *s, **t; + int n, bs, quote; + + for (t = argv, q = cmd; p = *t; t++) { + quote = 0; + s = p; + if (!*p || strpbrk(p, " \t\"")) { + quote = 1; + *q++ = '"'; + } + for (bs = 0; *p; ++p) { + switch (*p) { + case '\\': + ++bs; + break; + case '"': + memcpy(q, s, n = p - s); q += n; s = p; + memset(q, '\\', ++bs); q += bs; bs = 0; + break; + default: + bs = 0; + p = CharNext(p) - 1; + break; + } + } + memcpy(q, s, n = p - s); + q += n; + if (quote) *q++ = '"'; + *q++ = ' '; + } + if (q > cmd) --q; + *q = '\0'; + return cmd; +} + pid_t -pipe_exec(char *cmd, int mode, FILE **fpr, FILE **fpw) +rb_w32_pipe_exec(char *cmd, char *prog, int mode, FILE **fpr, FILE **fpw) { struct ChildRecord* child; HANDLE hReadIn, hReadOut; @@ -667,7 +738,7 @@ pipe_exec(char *cmd, int mode, FILE **fpr, FILE **fpw) CloseHandle(hCurProc); /* create child process */ - child = CreateChild(cmd, NULL, &sa, hWriteIn, hReadOut, NULL); + child = CreateChild(cmd, prog, &sa, hWriteIn, hReadOut, NULL); if (!child) { if (reading) { CloseHandle(hReadOut); @@ -729,9 +800,10 @@ pipe_exec(char *cmd, int mode, FILE **fpr, FILE **fpw) extern VALUE rb_last_status; int -do_spawn(mode, cmd) +rb_w32_spawn(mode, cmd, prog) int mode; char *cmd; +char *prog; { struct ChildRecord *child; DWORD exitcode; @@ -746,7 +818,7 @@ char *cmd; return -1; } - child = CreateChild(cmd, NULL, NULL, NULL, NULL, NULL); + child = CreateChild(cmd, prog, NULL, NULL, NULL, NULL); if (!child) { return -1; } @@ -768,97 +840,15 @@ char *cmd; } int -do_aspawn(mode, prog, argv) +rb_w32_aspawn(mode, prog, argv) int mode; char *prog; char **argv; { - char *cmd, *p, *q, *s, **t; - int len, n, bs, quote; - struct ChildRecord *child; - DWORD exitcode; - - switch (mode) { - case P_WAIT: - case P_NOWAIT: - case P_OVERLAY: - break; - default: - errno = EINVAL; - return -1; - } + int len = rb_w32_argv_size(argv); + char *cmd = ALLOCA_N(char, len); - for (t = argv, len = 0; *t; t++) { - for (p = *t, n = quote = bs = 0; *p; ++p) { - switch (*p) { - case '\\': - ++bs; - break; - case '"': - n += bs + 1; bs = 0; - quote = 1; - break; - case ' ': case '\t': - quote = 1; - default: - bs = 0; - p = CharNext(p) - 1; - break; - } - } - len += p - *t + n + 1; - if (quote) len += 2; - } - cmd = ALLOCA_N(char, len); - for (t = argv, q = cmd; p = *t; t++) { - quote = 0; - s = p; - if (!*p || strpbrk(p, " \t\"")) { - quote = 1; - *q++ = '"'; - } - for (bs = 0; *p; ++p) { - switch (*p) { - case '\\': - ++bs; - break; - case '"': - memcpy(q, s, n = p - s); q += n; s = p; - memset(q, '\\', ++bs); q += bs; bs = 0; - break; - default: - bs = 0; - p = CharNext(p) - 1; - break; - } - } - memcpy(q, s, n = p - s); - q += n; - if (quote) *q++ = '"'; - *q++ = ' '; - } - if (q > cmd) --q; - *q = '\0'; - - child = CreateChild(cmd, prog, NULL, NULL, NULL, NULL); - if (!child) { - return -1; - } - - switch (mode) { - case P_WAIT: - rb_syswait(child->pid); - return NUM2INT(rb_last_status); - case P_NOWAIT: - return child->pid; - case P_OVERLAY: - WaitForSingleObject(child->hProcess, INFINITE); - GetExitCodeProcess(child->hProcess, &exitcode); - CloseChildHandle(child); - _exit(exitcode); - default: - return -1; /* not reached */ - } + return rb_w32_spawn(mode, rb_w32_join_argv(cmd, argv), prog); } static struct ChildRecord * diff --git a/win32/win32.h b/win32/win32.h index 82bc90ed7..ed930ae6b 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -120,7 +120,7 @@ extern "C++" { #undef stat #define stat(path,st) rb_w32_stat(path,st) #undef execv -#define execv(path,argv) do_aspawn(P_OVERLAY,path,argv) +#define execv(path,argv) rb_w32_aspawn(P_OVERLAY,path,argv) #ifdef __MINGW32__ struct timezone { @@ -175,8 +175,10 @@ extern int chown(const char *, int, int); extern int link(const char *, const char *); extern int gettimeofday(struct timeval *, struct timezone *); extern pid_t waitpid (pid_t, int *, int); -extern int do_spawn(int, char *); -extern int do_aspawn(int, char *, char **); +extern int rb_w32_argv_size(char **); +extern char *rb_w32_join_argv(char *, char **); +extern int rb_w32_spawn(int, char *, char*); +extern int rb_w32_aspawn(int, char *, char **); extern int kill(int, int); extern pid_t rb_w32_getpid(void); |