[#21039] Happy new year and... moving Ruby development to Git? — Michael Klishin <michael.s.klishin@...>

Happy new year everyone.

94 messages 2009/01/01
[#21040] Re: Happy new year and... moving Ruby development to Git? — James Gray <james@...> 2009/01/01

On Jan 1, 2009, at 6:42 AM, Michael Klishin wrote:

[#21041] Re: Happy new year and... moving Ruby development to Git? — brabuhr@... 2009/01/01

On Thu, Jan 1, 2009 at 11:22 AM, James Gray <james@grayproductions.net> wrote:

[#21042] Re: Happy new year and... moving Ruby development to Git? — Federico Builes <federico.builes@...> 2009/01/01

brabuhr@gmail.com writes:

[#21049] Re: Happy new year and... moving Ruby development to Git? — Michael Klishin <michael.s.klishin@...> 2009/01/01

[#21053] Re: Happy new year and... moving Ruby development to Git? — znmeb@... 2009/01/01

Quoting Michael Klishin <michael.s.klishin@gmail.com>:

[#21068] Re: Happy new year and... moving Ruby development to Git? — Yukihiro Matsumoto <matz@...> 2009/01/02

Hi,

[#21069] Re: Happy new year and... moving Ruby development to Git? — Florian Gilcher <flo@...> 2009/01/02

-----BEGIN PGP SIGNED MESSAGE-----

[#21070] Re: Happy new year and... moving Ruby development to Git? — "Luis Lavena" <luislavena@...> 2009/01/02

T24gRnJpLCBKYW4gMiwgMjAwOSBhdCAxMjoxOCBQTSwgRmxvcmlhbiBHaWxjaGVyIDxmbG9AYW5k

[#21073] Re: Happy new year and... moving Ruby development to Git? — mathew <meta@...> 2009/01/02

My opinion:

[#21078] Re: Happy new year and... moving Ruby development to Git? — "Eust痃uio Rangel" <eustaquiorangel@...> 2009/01/02

My two cents:

[#21101] Re: Happy new year and... moving Ruby development to Git? — "M. Edward (Ed) Borasky" <znmeb@...> 2009/01/03

Eust=E1quio Rangel wrote:

[#21102] Re: Happy new year and... moving Ruby development to Git? — "Nikolai Weibull" <now@...> 2009/01/03

On Sat, Jan 3, 2009 at 21:40, M. Edward (Ed) Borasky <znmeb@cesmail.net> wrote:

[#21104] Re: Happy new year and... moving Ruby development to Git? — "M. Edward (Ed) Borasky" <znmeb@...> 2009/01/03

Nikolai Weibull wrote:

[#21106] Re: Happy new year and... moving Ruby development to Git? — "Giuseppe Bilotta" <giuseppe.bilotta@...> 2009/01/04

On Sat, Jan 3, 2009 at 10:39 PM, M. Edward (Ed) Borasky

[#21114] Re: Happy new year and... moving Ruby development to Git? — Joel VanderWerf <vjoel@...> 2009/01/04

Giuseppe Bilotta wrote:

[#21132] Re: Happy new year and... moving Ruby development to Git? — Michael Klishin <michael.s.klishin@...> 2009/01/05

[#21134] Re: Happy new year and... moving Ruby development to Git? — Daniel Berger <djberg96@...> 2009/01/05

Michael Klishin wrote:

[#21080] Re: Happy new year and... moving Ruby development to Git? — Eric Hodel <drbrain@...7.net> 2009/01/02

On Jan 1, 2009, at 04:42 AM, Michael Klishin wrote:

[#21083] Re: Happy new year and... moving Ruby development to Git? — "Nikolai Weibull" <now@...> 2009/01/03

On Sat, Jan 3, 2009 at 00:34, Eric Hodel <drbrain@segment7.net> wrote:

[#21089] Re: Happy new year and... moving Ruby development to Git? — Michael Klishin <michael.s.klishin@...> 2009/01/03

[#21147] Re: Happy new year and... moving Ruby development to Git? — Paul Brannan <pbrannan@...> 2009/01/05

On Sat, Jan 03, 2009 at 12:48:09PM +0900, Michael Klishin wrote:

[#21160] Re: Happy new year and... moving Ruby development to Git? — Eric Hodel <drbrain@...7.net> 2009/01/05

On Jan 2, 2009, at 17:25 PM, Nikolai Weibull wrote:

[#21165] Re: Happy new year and... moving Ruby development to Git? — Sylvain Joyeux <sylvain.joyeux@...4x.org> 2009/01/06

> I think I'm entitled to an opinion on the subject because I am a

[#21097] [Bug #977] caller for all threads patch — Roger Pack <redmine@...>

Bug #977: caller for all threads patch

15 messages 2009/01/03
[#23760] Re: [Bug #977] caller for all threads patch — SASADA Koichi <ko1@...> 2009/06/08

I made a patch to Thread#caller(lev=1). It may be more flexible than

[#21244] [Bug #999] SSL & ZIP missing from ruby-1.9.1-preview1-i386-mswin32 — William Mason <redmine@...>

Bug #999: SSL & ZIP missing from ruby-1.9.1-preview1-i386-mswin32

14 messages 2009/01/10

[#21259] Do I need a special build arg to get irb to accept utf characters on OSX — Dave Thomas <dave@...>

I'm seeing very strange behavior at the irb prompt with ruby 1.9.1 =20

10 messages 2009/01/11

[#21310] [Bug #1008] Missing shell version of ruby-1.9 commands (gem, rake, ...) for MinGW installation — Chauk-Mean Proum <redmine@...>

Bug #1008: Missing shell version of ruby-1.9 commands (gem, rake, ...) for MinGW installation

8 messages 2009/01/13

[#21339] [Bug #1010] Ruby-1.9's rake sh doesn't work on Windows (but fix provided) — Chauk-Mean Proum <redmine@...>

Bug #1010: Ruby-1.9's rake sh doesn't work on Windows (but fix provided)

10 messages 2009/01/14

[#21399] Proposal: Module#copy_method — Yehuda Katz <wycats@...>

I'd like it to be possible to copy methods from one module to another. The

38 messages 2009/01/18
[#21428] Re: Proposal: Module#copy_method — Yukihiro Matsumoto <matz@...> 2009/01/19

Hi,

[#21550] [Feature #1046] request: ability to run without specifying .rb — Roger Pack <redmine@...>

Feature #1046: request: ability to run without specifying .rb

13 messages 2009/01/24

[#21552] [Feature #1047] request: getters, setters for the GC — Roger Pack <redmine@...>

Feature #1047: request: getters, setters for the GC

15 messages 2009/01/24

[#21613] [Bug #1063] in `write': Not enough space - <STDOUT> (Errno::ENOMEM) on Windows XP — Nick Gorbikoff <redmine@...>

Bug #1063: in `write': Not enough space - <STDOUT> (Errno::ENOMEM) on Windows XP

11 messages 2009/01/27

[#21640] [Bug #1068] Ruby Cannot Handle Some UIDs — James Gray <redmine@...>

Bug #1068: Ruby Cannot Handle Some UIDs

12 messages 2009/01/28
[#21642] Re: [Bug #1068] Ruby Cannot Handle Some UIDs — Ondrej Bilka <neleai@...> 2009/01/28

On Wed, Jan 28, 2009 at 05:00:05PM +0100, James Gray wrote:

[#21663] Re: [Bug #1068] Ruby Cannot Handle Some UIDs — Nobuyoshi Nakada <nobu@...> 2009/01/29

Hi,

[#21701] [Feature #1081] add File::write() convenience method — Suraj Kurapati <redmine@...>

Feature #1081: add File::write() convenience method

34 messages 2009/01/31
[#28450] [Feature #1081] add File::write() convenience method — Yusuke Endoh <redmine@...> 2010/03/03

Issue #1081 has been updated by Yusuke Endoh.

[#28455] Re: [Feature #1081] add File::write() convenience method — Yukihiro Matsumoto <matz@...> 2010/03/04

Hi,

[#28472] Re: [Feature #1081] add File::write() convenience method — Yusuke ENDOH <mame@...> 2010/03/04

Hi,

[#21702] [Feature #1082] add Object#singleton_class method — Suraj Kurapati <redmine@...>

Feature #1082: add Object#singleton_class method

54 messages 2009/01/31
[#27372] [Feature #1082] add Object#singleton_class method — Suraj Kurapati <redmine@...> 2010/01/02

Issue #1082 has been updated by Suraj Kurapati.

[#27384] Re: [Feature #1082] add Object#singleton_class method — Yukihiro Matsumoto <matz@...> 2010/01/04

Hi,

[#27394] Re: [Feature #1082] add Object#singleton_class method — Yusuke ENDOH <mame@...> 2010/01/04

Hi,

[#27407] Re: [Feature #1082] add Object#singleton_class method — Shugo Maeda <shugo@...> 2010/01/05

Hi,

[#27409] Re: [Feature #1082] add Object#singleton_class method — Yukihiro Matsumoto <matz@...> 2010/01/05

Hi,

[#28304] Re: [Feature #1082] add Object#singleton_class method — Shugo Maeda <shugo@...> 2010/02/23

Hi,

[ruby-core:21421] Re: [Bug #907] Various system() and backticks problems on Windows

From: Jim Deville <jdeville@...>
Date: 2009-01-18 21:21:17 UTC
List: ruby-core #21421
COMSPEC is still cmd by default. Win7 doesn't change that even though Power=
shell is in the box. Installing Powershell doesn't change it either.

JD

-----Original Message-----
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
Sent: January 18, 2009 12:46 PM
To: ruby-core@ruby-lang.org <ruby-core@ruby-lang.org>
Subject: [ruby-core:21417] Re: [Bug #907] Various system() and backticks pr=
oblems on Windows


Hi,

At Tue, 6 Jan 2009 22:31:49 +0900,
James M. Lawrence wrote in [ruby-core:21167]:
> Latest trunk passes the spec except for the following case: I
> expected system("echo", "1") to fail since echo only exists
> as a built-in shell command, while multi-arg system() should
> not invoke the shell.  However I see the lookup on the
> cmd.exe command list and the join on argv, so presumably the
> current behavior is intended.

Yes.

> Note there are other popular Windows shells such the
> PowerShell, so the general strategy of checking for built-in
> shell commands cannot work.

Is COMSPEC the PowerShell by the default on such systems?

> Also, is a backport to 1.8 planned?  This affects Rake.

Could you test the following patch?


Index: io.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- io.c        (revision 21607)
+++ io.c        (working copy)
@@ -3189,5 +3189,5 @@ pipe_open(pstr, pname, mode)
 #ifdef _WIN32
 retry:
-    pid =3D pipe_exec(pname, rb_io_mode_modenum(mode), &fpr, &fpw);
+    pid =3D rb_w32_pipe_exec(pname, rb_io_mode_modenum(mode), &fpr, &fpw);
     if (pid =3D=3D -1) {           /* exec failed */
        if (errno =3D=3D EAGAIN) {
Index: process.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- process.c   (revision 21607)
+++ process.c   (working copy)
@@ -1036,5 +1036,5 @@ rb_proc_exec(str)
 #ifdef _WIN32
     before_exec();
-    do_spawn(P_OVERLAY, (char *)str);
+    rb_w32_spawn(P_OVERLAY, (char *)str, NULL);
     after_exec();
 #else
@@ -1087,4 +1087,7 @@ rb_proc_exec(str)

 #if defined(__human68k__) || defined(__DJGPP__) || defined(_WIN32)
+#if defined(_WIN32)
+#define proc_spawn_v(argv, prog) rb_w32_aspawn(P_WAIT, prog, argv)
+#elif defined(__human68k__) || defined(__DJGPP__)
 static int
 proc_spawn_v(argv, prog)
@@ -1129,12 +1132,10 @@ proc_spawn_v(argv, prog)
 #endif
     before_exec();
-#if defined(_WIN32)
-    status =3D do_aspawn(P_WAIT, prog, argv);
-#else
     status =3D spawnv(P_WAIT, prog, argv);
-#endif
+    rb_last_status_set(status =3D=3D -1 ? 127 : status, 0);
     after_exec();
     return status;
 }
+#endif

 static int
@@ -1149,9 +1150,6 @@ proc_spawn_n(argc, argv, prog)
     args =3D ALLOCA_N(char*, argc + 1);
     for (i =3D 0; i < argc; i++) {
-       SafeStringValue(argv[i]);
-       args[i] =3D StringValueCStr(argv[i]);
+       args[i] =3D RSTRING_PTR(argv[i]);
     }
-    if (prog)
-       SafeStringValue(prog);
     args[i] =3D (char*) 0;
     if (args[0])
@@ -1160,16 +1158,15 @@ proc_spawn_n(argc, argv, prog)
 }

-#if !defined(_WIN32)
+#if defined(_WIN32)
+#define proc_spawn(str) rb_w32_spawn(P_WAIT, str, 0)
+#else
 static int
-proc_spawn(sv)
-    VALUE sv;
-{
+proc_spawn(str)
     char *str;
+{
     char *s, *t;
     char **argv, **a;
     int status;

-    SafeStringValue(sv);
-    str =3D s =3D StringValueCStr(sv);
     for (s =3D str; *s; s++) {
        if (*s !=3D ' ' && !ISALPHA(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n"=
,*s)) {
@@ -1177,4 +1174,5 @@ proc_spawn(sv)
            before_exec();
            status =3D shell?spawnl(P_WAIT,shell,"sh","-c",str,(char*)NULL)=
:system(str);
+           last_status_set(status =3D=3D -1 ? 127 : status, 0);
            after_exec();
            return status;
@@ -1287,5 +1285,4 @@ rb_f_exec(argc, argv)
        prog =3D RARRAY(tmp)->ptr[0];
        argv[0] =3D RARRAY(tmp)->ptr[1];
-       SafeStringValue(prog);
     }
     proc_prepare_args(&earg, argc, argv, prog);
@@ -1471,100 +1468,66 @@ rb_f_system(argc, argv)
     VALUE *argv;
 {
-    int status;
-#if defined(__EMX__)
+    int status, i;
+#if defined(__EMX__) || defined(__VMS)
     VALUE cmd;
+#else
+    volatile VALUE prog =3D 0;
+# if !(defined(__human68k__) || defined(__DJGPP__) || defined(_WIN32))
+    int pid;
+    struct rb_exec_arg earg;
+    RETSIGTYPE (*chfunc)(int);
+# endif
+#endif

+#if !defined(__VMS)
     fflush(stdout);
     fflush(stderr);
+#endif
     if (argc =3D=3D 0) {
        rb_last_status =3D Qnil;
        rb_raise(rb_eArgError, "wrong number of arguments");
     }
-
     if (TYPE(argv[0]) =3D=3D T_ARRAY) {
        if (RARRAY(argv[0])->len !=3D 2) {
            rb_raise(rb_eArgError, "wrong first argument");
        }
+#if defined(__EMX__) || defined(__VMS)
        argv[0] =3D RARRAY(argv[0])->ptr[0];
+#else
+       prog =3D RARRAY(argv[0])->ptr[0];
+       argv[0] =3D RARRAY(argv[0])->ptr[1];
+#endif
+    }
+    if (prog && !(argc > 0 && argv[0] =3D=3D prog)) {
+       SafeStringValue(prog);
+       StringValueCStr(prog);
+    }
+    for (i =3D 0; i < argc; ++i) {
+       SafeStringValue(argv[i]);
+       StringValueCStr(argv[i]);
     }
+#if defined(__EMX__) || defined(__VMS)
     cmd =3D rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));

     SafeStringValue(cmd);
-    status =3D do_spawn(RSTRING(cmd)->ptr);
+# if defined(__EMX__)
+    status =3D do_spawn(StringValueCStr(cmd));
     last_status_set(status, 0);
+# else
+    status =3D system(StringValueCStr(cmd));
+    last_status_set((status & 0xff) << 8, 0);
+# endif
 #elif defined(__human68k__) || defined(__DJGPP__) || defined(_WIN32)
-    volatile VALUE prog =3D 0;
-
-    fflush(stdout);
-    fflush(stderr);
-    if (argc =3D=3D 0) {
-       rb_last_status =3D Qnil;
-       rb_raise(rb_eArgError, "wrong number of arguments");
-    }
-
-    if (TYPE(argv[0]) =3D=3D T_ARRAY) {
-       if (RARRAY(argv[0])->len !=3D 2) {
-           rb_raise(rb_eArgError, "wrong first argument");
-       }
-       prog =3D RARRAY(argv[0])->ptr[0];
-       argv[0] =3D RARRAY(argv[0])->ptr[1];
-    }
-
     if (argc =3D=3D 1 && prog =3D=3D 0) {
-#if defined(_WIN32)
-       SafeStringValue(argv[0]);
-       status =3D do_spawn(P_WAIT, StringValueCStr(argv[0]));
-#else
-       status =3D proc_spawn(argv[0]);
-#endif
+       status =3D proc_spawn(RSTRING_PTR(argv[0]));
     }
     else {
        status =3D proc_spawn_n(argc, argv, prog);
     }
-#if !defined(_WIN32)
-    last_status_set(status =3D=3D -1 ? 127 : status, 0);
-#else
+# if defined(_WIN32)
     if (status =3D=3D -1)
        last_status_set(0x7f << 8, 0);
-#endif
-#elif defined(__VMS)
-    VALUE cmd;
-
-    if (argc =3D=3D 0) {
-       rb_last_status =3D Qnil;
-       rb_raise(rb_eArgError, "wrong number of arguments");
-    }
-
-    if (TYPE(argv[0]) =3D=3D T_ARRAY) {
-       if (RARRAY(argv[0])->len !=3D 2) {
-           rb_raise(rb_eArgError, "wrong first argument");
-       }
-       argv[0] =3D RARRAY(argv[0])->ptr[0];
-    }
-    cmd =3D rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
-
-    SafeStringValue(cmd);
-    status =3D system(StringValueCStr(cmd));
-    last_status_set((status & 0xff) << 8, 0);
+# endif
 #else
-    volatile VALUE prog =3D 0;
-    int pid;
-    struct rb_exec_arg earg;
-    RETSIGTYPE (*chfunc)(int);
-
-    fflush(stdout);
-    fflush(stderr);
-    if (argc =3D=3D 0) {
-       rb_last_status =3D Qnil;
-       rb_raise(rb_eArgError, "wrong number of arguments");
-    }
-
-    if (TYPE(argv[0]) =3D=3D T_ARRAY) {
-       if (RARRAY(argv[0])->len !=3D 2) {
-           rb_raise(rb_eArgError, "wrong first argument");
-       }
-       prog =3D RARRAY(argv[0])->ptr[0];
-       argv[0] =3D RARRAY(argv[0])->ptr[1];
-    }
     proc_prepare_args(&earg, argc, argv, prog);

Index: win32/win32.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- win32/win32.c       (revision 21607)
+++ win32/win32.c       (working copy)
@@ -28,7 +28,7 @@
 #include <wincon.h>
 #include <shlobj.h>
+#include <mbstring.h>
 #ifdef __MINGW32__
 #include <mswsock.h>
-#include <mbstring.h>
 #endif
 #include "win32.h"
@@ -47,8 +47,4 @@
 #undef setsockopt

-#ifndef bool
-#define bool int
-#endif
-
 #if defined __BORLANDC__ || defined _WIN32_WCE
 #  define _filbuf _fgetc
@@ -86,5 +82,5 @@

 static struct ChildRecord *CreateChild(const char *, const char *, SECURIT=
Y_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
-static bool has_redirection(const char *);
+static int has_redirection(const char *);
 static void StartSockets ();
 static DWORD wait_events(HANDLE event, DWORD timeout);
@@ -390,4 +386,15 @@ exit_handler(void)
 }

+static inline char *
+translate_char(char *p, int from, int to)
+{
+    while (*p) {
+       if ((unsigned char)*p =3D=3D from)
+           *p =3D to;
+       p =3D CharNext(p);
+    }
+    return p;
+}
+
 #ifndef CSIDL_PROFILE
 #define CSIDL_PROFILE 40
@@ -435,9 +442,5 @@ init_env(void)
        }
        if (f) {
-           char *p =3D env;
-           while (*p) {
-               if (*p =3D=3D '\\') *p =3D '/';
-               p =3D CharNext(p);
-           }
+           char *p =3D translate_char(env, '\\', '/');
            if (p - env =3D=3D 2 && env[1] =3D=3D ':') {
                *p++ =3D '/';
@@ -643,8 +646,10 @@ is_command_com(const char *interp)
 }

+static int internal_cmd_match(const char *cmdname, int nt);
+
 static int
 is_internal_cmd(const char *cmd, int nt)
 {
-    char cmdname[9], *b =3D cmdname, c, **nm;
+    char cmdname[9], *b =3D cmdname, c;

     do {
@@ -666,4 +671,12 @@ is_internal_cmd(const char *cmd, int nt)
     }
     *b =3D 0;
+    return internal_cmd_match(cmdname, nt);
+}
+
+static int
+internal_cmd_match(const char *cmdname, int nt)
+{
+    char **nm;
+
     nm =3D bsearch(cmdname, szInternalCmds,
                 sizeof(szInternalCmds) / sizeof(*szInternalCmds),
@@ -675,5 +688,4 @@ is_internal_cmd(const char *cmd, int nt)
 }

-
 SOCKET
 rb_w32_get_osfhandle(int fh)
@@ -683,5 +695,5 @@ rb_w32_get_osfhandle(int fh)

 rb_pid_t
-pipe_exec(const char *cmd, int mode, FILE **fpr, FILE **fpw)
+rb_w32_pipe_exec(const char *cmd, int mode, FILE **fpr, FILE **fpw)
 {
     struct ChildRecord* child;
@@ -821,58 +833,10 @@ pipe_exec(const char *cmd, int mode, FIL
 extern VALUE rb_last_status;

-int
-do_spawn(int mode, const char *cmd)
-{
-    struct ChildRecord *child;
-    DWORD exitcode;
-
-    switch (mode) {
-      case P_WAIT:
-      case P_NOWAIT:
-      case P_OVERLAY:
-       break;
-      default:
-       errno =3D EINVAL;
-       return -1;
-    }
-
-    child =3D CreateChild(cmd, NULL, 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 */
-    }
-}
-
-int
-do_aspawn(int mode, const char *prog, char **argv)
+static int
+argv_size(char *const *argv, BOOL escape)
 {
-    char *cmd, *p, *q, *s, **t;
+    const char *p;
+    char *const *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 =3D EINVAL;
-       return -1;
-    }

     for (t =3D argv, len =3D 0; *t; t++) {
@@ -882,4 +846,8 @@ do_aspawn(int mode, const char *prog, ch
                ++bs;
                break;
+             case '<': case '>': case '|': case '^':
+               bs =3D 0;
+               if (escape && !quote) n++;
+               break;
              case '"':
                n +=3D bs + 1; bs =3D 0;
@@ -895,7 +863,16 @@ do_aspawn(int mode, const char *prog, ch
        }
        len +=3D p - *t + n + 1;
-       if (quote) len +=3D 2;
+       if (p - *t =3D=3D 0 || quote) len +=3D 2;
     }
-    cmd =3D ALLOCA_N(char, len);
+    return len;
+}
+
+static char *
+join_argv(char *cmd, char *const *argv, BOOL escape)
+{
+    const char *p, *s;
+    char *q, *const *t;
+    int n, bs, quote;
+
     for (t =3D argv, q =3D cmd; p =3D *t; t++) {
        quote =3D 0;
@@ -914,4 +891,10 @@ do_aspawn(int mode, const char *prog, ch
                memset(q, '\\', ++bs); q +=3D bs; bs =3D 0;
                break;
+             case '<': case '>': case '|': case '^':
+               if (escape && !quote) {
+                   memcpy(q, s, n =3D p - s); q +=3D n; s =3D p;
+                   *q++ =3D '^';
+                   break;
+               }
              default:
                bs =3D 0;
@@ -927,6 +910,35 @@ do_aspawn(int mode, const char *prog, ch
     if (q > cmd) --q;
     *q =3D '\0';
+    return cmd;
+}
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#else
+# define MAXPATHLEN 512
+#endif
+
+#define STRNDUPA(ptr, src, len) \
+    (((char *)memcpy(((ptr) =3D ALLOCA_N(char, (len) + 1)), (src), (len)))=
[len] =3D 0)
+
+static int
+check_spawn_mode(int mode)
+{
+    switch (mode) {
+      case P_WAIT:
+      case P_NOWAIT:
+      case P_OVERLAY:
+       return 0;
+      default:
+       errno =3D EINVAL;
+       return -1;
+    }
+}
+
+static rb_pid_t
+child_result(struct ChildRecord *child, int mode)
+{
+    DWORD exitcode;

-    child =3D CreateChild(cmd, prog, NULL, NULL, NULL, NULL);
     if (!child) {
        return -1;
@@ -958,7 +970,5 @@ CreateChild(const char *cmd, const char
     PROCESS_INFORMATION aProcessInformation;
     SECURITY_ATTRIBUTES sa;
-    const char *shell;
     struct ChildRecord *child;
-    char *p =3D NULL;

     if (!cmd && !prog) {
@@ -1007,4 +1017,37 @@ CreateChild(const char *cmd, const char
     dwCreationFlags =3D (NORMAL_PRIORITY_CLASS);

+    RUBY_CRITICAL({
+       fRet =3D CreateProcess(prog, (char *)cmd, psa, psa,
+                            psa->bInheritHandle, dwCreationFlags, NULL, NU=
LL,
+                            &aStartupInfo, &aProcessInformation);
+       errno =3D map_errno(GetLastError());
+    });
+
+    if (!fRet) {
+       child->pid =3D 0;         /* release the slot */
+       return NULL;
+    }
+
+    CloseHandle(aProcessInformation.hThread);
+
+    child->hProcess =3D aProcessInformation.hProcess;
+    child->pid =3D (rb_pid_t)aProcessInformation.dwProcessId;
+
+    if (!IsWinNT()) {
+       /* On Win9x, make pid positive similarly to cygwin and perl */
+       child->pid =3D -child->pid;
+    }
+
+    return child;
+}
+
+rb_pid_t
+rb_w32_spawn(int mode, const char *cmd, const char *prog)
+{
+    char *p =3D NULL;
+    const char *shell =3D NULL;
+
+    if (check_spawn_mode(mode)) return -1;
+
     if (prog) {
        if (!(p =3D dln_find_exe(prog, NULL))) {
@@ -1014,21 +1057,9 @@ CreateChild(const char *cmd, const char
     else {
        int redir =3D -1;
-       int len =3D 0;
        int nt;
        while (ISSPACE(*cmd)) cmd++;
-       for (prog =3D cmd; *prog; prog =3D CharNext(prog)) {
-           if (ISSPACE(*prog)) {
-               len =3D prog - cmd;
-               do ++prog; while (ISSPACE(*prog));
-               if (!*prog--) break;
-           }
-           else {
-               len =3D 0;
-           }
-       }
-       if (!len) len =3D strlen(cmd);
        if ((shell =3D getenv("RUBYSHELL")) && (redir =3D has_redirection(c=
md))) {
-           char *tmp =3D ALLOCA_N(char, strlen(shell) + len + sizeof(" -c =
") + 2);
-           sprintf(tmp, "%s -c \"%.*s\"", shell, len, cmd);
+           char *tmp =3D ALLOCA_N(char, strlen(shell) + strlen(cmd) + size=
of(" -c ") + 2);
+           sprintf(tmp, "%s -c \"%s\"", shell, cmd);
            cmd =3D tmp;
        }
@@ -1037,10 +1068,30 @@ CreateChild(const char *cmd, const char
                  (redir < 0 ? has_redirection(cmd) : redir) ||
                  is_internal_cmd(cmd, nt))) {
-           char *tmp =3D ALLOCA_N(char, strlen(shell) + len + sizeof(" /c =
")
+           char *tmp =3D ALLOCA_N(char, strlen(shell) + strlen(cmd) + size=
of(" /c ")
                                 + (nt ? 2 : 0));
-           sprintf(tmp, nt ? "%s /c \"%.*s\"" : "%s /c %.*s", shell, len, =
cmd);
+           sprintf(tmp, nt ? "%s /c \"%s\"" : "%s /c %s", shell, cmd);
            cmd =3D tmp;
        }
        else {
+           int len =3D 0;
+           if (*cmd =3D=3D '"') {
+               for (prog =3D cmd + 1; *prog && *prog !=3D '"'; prog =3D Ch=
arNext(prog));
+               len =3D prog - cmd - 1;
+               STRNDUPA(p, cmd + 1, len);
+               p =3D dln_find_exe(p, NULL);
+               if (p) goto command_found;
+           }
+           for (prog =3D cmd; *prog; prog =3D CharNext(prog)) {
+               if (ISSPACE(*prog)) {
+                   len =3D prog - cmd;
+                   do ++prog; while (ISSPACE(*prog));
+                   break;
+               }
+               else {
+                   len =3D 0;
+               }
+           }
+           if (!len) len =3D strlen(cmd);
+
            shell =3D NULL;
            prog =3D cmd;
@@ -1050,18 +1101,14 @@ CreateChild(const char *cmd, const char
                    break;
                }
-               if (strchr(".:*?\"/\\", *prog)) {
+               if (strchr(":*?\"/\\", *prog)) {
                    if (cmd[len]) {
-                       char *tmp =3D ALLOCA_N(char, len + 1);
-                       memcpy(tmp, cmd, len);
-                       tmp[len] =3D 0;
-                       cmd =3D tmp;
+                       STRNDUPA(p, cmd, len);
                    }
+                   p =3D dln_find_exe(p ? p : cmd, NULL);
                    break;
                }
                if (ISSPACE(*prog) || strchr("<>|", *prog)) {
                    len =3D prog - cmd;
-                   p =3D ALLOCA_N(char, len + 1);
-                   memcpy(p, cmd, len);
-                   p[len] =3D 0;
+                   STRNDUPA(p, cmd, len);
                    p =3D dln_find_exe(p, NULL);
                    break;
@@ -1072,35 +1119,73 @@ CreateChild(const char *cmd, const char
     }
     if (p) {
+      command_found:
        shell =3D p;
-       while (*p) {
-           if ((unsigned char)*p =3D=3D '/')
-               *p =3D '\\';
-           p =3D CharNext(p);
-       }
+       translate_char(p, '/', '\\');
     }

-    RUBY_CRITICAL({
-       fRet =3D CreateProcess(shell, (char *)cmd, psa, psa,
-                            psa->bInheritHandle, dwCreationFlags, NULL, NU=
LL,
-                            &aStartupInfo, &aProcessInformation);
-       errno =3D map_errno(GetLastError());
-    });
-
-    if (!fRet) {
-       child->pid =3D 0;         /* release the slot */
-       return NULL;
-    }
+    return child_result(CreateChild(cmd, shell, NULL, NULL, NULL, NULL), m=
ode);
+}

-    CloseHandle(aProcessInformation.hThread);
+rb_pid_t
+rb_w32_aspawn(int mode, const char *prog, char *const *argv)
+{
+    int len, differ =3D 0, c_switch =3D 0;
+    BOOL ntcmd =3D FALSE, tmpnt;
+    const char *shell;
+    char *cmd;

-    child->hProcess =3D aProcessInformation.hProcess;
-    child->pid =3D (rb_pid_t)aProcessInformation.dwProcessId;
+    if (check_spawn_mode(mode)) return -1;

-    if (!IsWinNT()) {
-       /* On Win9x, make pid positive similarly to cygwin and perl */
-       child->pid =3D -child->pid;
+    if (!prog) prog =3D argv[0];
+    if ((shell =3D getenv("COMSPEC")) &&
+       internal_cmd_match(prog, tmpnt =3D !is_command_com(shell))) {
+       ntcmd =3D tmpnt;
+       prog =3D shell;
+       c_switch =3D 1;
+       differ =3D 1;
+    }
+    else if ((cmd =3D dln_find_exe(prog, NULL))) {
+       if (cmd =3D=3D prog) {
+           cmd =3D ALLOCA_N(char, strlen(cmd));
+           strcpy(cmd, prog);
+       }
+       translate_char(cmd, '/', '\\');
+       prog =3D cmd;
+       argv++;
+       differ =3D 1;
+    }
+    else if (strchr(prog, '/')) {
+       cmd =3D ALLOCA_N(char, strlen(cmd));
+       strcpy(cmd, prog);
+       translate_char(cmd, '/', '\\');
+       argv++;
+       differ =3D 1;
+    }
+    if (differ) {
+       char *progs[2];
+       int cmdlen;
+       progs[0] =3D (char *)prog;
+       progs[1] =3D NULL;
+       len =3D argv_size(progs, ntcmd);
+       cmdlen =3D len - 1;
+       if (c_switch) len +=3D 3;
+       if (argv[0]) len +=3D argv_size(argv, ntcmd);
+       cmd =3D ALLOCA_N(char, len);
+       join_argv(cmd, progs, ntcmd);
+       if (c_switch) {
+           memcpy(cmd + cmdlen, " /c", 4);
+           cmdlen +=3D 3;
+       }
+       if (argv[0]) {
+           cmd[cmdlen++] =3D ' ';
+           join_argv(cmd + cmdlen, argv, ntcmd);
+       }
     }
-
-    return child;
+    else {
+       len =3D argv_size(argv, FALSE);
+       cmd =3D ALLOCA_N(char, len);
+       join_argv(cmd, argv, FALSE);
+    }
+    return child_result(CreateChild(cmd, prog, NULL, NULL, NULL, NULL), mo=
de);
 }

@@ -1139,10 +1224,4 @@ insert(const char *path, VALUE vinfo)
 }

-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#else
-# define MAXPATHLEN 512
-#endif
-

 static NtCmdLineElement **
@@ -1157,5 +1236,5 @@ cmdglob(NtCmdLineElement *patt, NtCmdLin
        if (!(buf =3D malloc(patt->len + 1))) return 0;

-    strncpy (buf, patt->str, patt->len);
+    memcpy(buf, patt->str, patt->len + 1);
     buf[patt->len] =3D '\0';
     for (p =3D buf; *p; p =3D CharNext(p))
@@ -1178,5 +1257,5 @@ cmdglob(NtCmdLineElement *patt, NtCmdLin
 //

-static bool
+static int
 has_redirection(const char *cmd)
 {
@@ -1208,4 +1287,10 @@ has_redirection(const char *cmd)
            break;

+         case '%':
+           if (*++ptr !=3D '_' && !ISALPHA(*ptr)) break;
+           while (*++ptr =3D=3D '_' || ISALNUM(*ptr));
+           if (*ptr++ =3D=3D '%') return TRUE;
+           break;
+
          case '\\':
            ptr++;
Index: win32/win32.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- win32/win32.h       (revision 21607)
+++ win32/win32.h       (working copy)
@@ -139,5 +139,5 @@ extern DWORD rb_w32_osid(void);
 #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)
 #if !defined(__BORLANDC__) && !defined(_WIN32_WCE)
 #undef isatty
@@ -161,5 +161,5 @@ struct timezone {
 extern void   NtInitialize(int *, char ***);
 extern int    rb_w32_cmdvector(const char *, char ***);
-extern rb_pid_t pipe_exec(const char *, int, FILE **, FILE **);
+extern rb_pid_t rb_w32_pipe_exec(const char *, int, FILE **, FILE **);
 extern int    flock(int fd, int oper);
 extern int    rb_w32_accept(int, struct sockaddr *, int *);
@@ -207,6 +207,6 @@ extern int link(char *, char *);
 extern int gettimeofday(struct timeval *, struct timezone *);
 extern rb_pid_t waitpid (rb_pid_t, int *, int);
-extern int do_spawn(int, const char *);
-extern int do_aspawn(int, const char *, char **);
+extern rb_pid_t rb_w32_spawn(int, const char *, const char *prog);
+extern rb_pid_t rb_w32_aspawn(int, const char *, char *const *);
 extern int kill(int, int);
 extern int fcntl(int, int, ...);


--
Nobu Nakada



In This Thread

Prev Next