なかだです。

 $0に長い文字列をセットするとSEGVします。

$ ruby -e '$0="x"*10000'
-e:1: [BUG] Segmentation fault
ruby 1.7.1 (2001-08-23) [i686-linux]
アボートしました

 それと、どうも途中のどこかでorigargvが書き換えられてしまうよ
うで、長さは最初に調べておかないとまずいようです。

$ ruby -e '$0="x";sleep' &
[1] 26539
$ ps ww $!|cat -e
  PID TTY      STAT   TIME COMMAND$
26539 pts/0    S      0:00 x sr/bin/ruby -e $0="x";sleep$
$ od -tc /proc/$!/cmdline
0000000   x  \0   s   r   /   b   i   n   /   r   u   b   y  \0   -   e
0000020  \0   $   0   =   "   x   "   ;   s   l   e   e   p  \0
0000036

$ ./i686-linux/miniruby -e '$0="x";sleep' &
[1] 26546
$ ps ww $!|cat -e; od -tc /proc/$!/cmdline
  PID TTY      STAT   TIME COMMAND$
26726 pts/0    S      0:00 x                                    $
0000000   x  \0                                                        
0000020                                                                
0000040                      \0
0000052

 ついでに、ふたつ目のパッチのようにするとlinuxではちょっぴり幸
せな感じ。

$ ./i686-linux/miniruby.new -e '$0="x";sleep' &
[1] 26726
$ ps ww $!|cat -e
  PID TTY      STAT   TIME COMMAND$
26546 pts/0    S      0:00 x$
$ od -tc /proc/$!/cmdline
0000000   x
0000001


Index: ruby.c =================================================================== RCS file: /cvs/ruby/src/ruby/ruby.c,v retrieving revision 1.49 diff -u -2 -p -r1.49 ruby.c --- ruby.c 2001/07/14 15:17:19 1.49 +++ ruby.c 2001/08/24 09:50:58 @@ -61,5 +62,5 @@ static VALUE do_split = Qfalse; static char *script; -static int origargc; +static int origargc, origarglen; static char **origargv; @@ -883,26 +883,14 @@ set_arg0(val, id) char *s; int i; - static int len; + int len = origarglen; if (origargv == 0) rb_raise(rb_eRuntimeError, "$0 not initialized"); -#ifndef __hpux - if (len == 0) { - s = origargv[0]; - s += strlen(s); - /* See if all the arguments are contiguous in memory */ - for (i = 1; i < origargc; i++) { - if (origargv[i] == s + 1) - s += strlen(++s); /* this one is ok too */ - } - len = s - origargv[0]; - } -#endif StringValue(val); s = RSTRING(val)->ptr; i = RSTRING(val)->len; #ifndef __hpux - if (i < len) { - memcpy(origargv[0], s, i); - origargv[0][i] = '\0'; + if (i >= len) { + memcpy(origargv[0], s, len); + origargv[0][len] = '\0'; } else { @@ -1027,4 +1019,17 @@ ruby_process_options(argc, argv) { origargc = argc; origargv = argv; +#ifndef __hpux + if (origarglen == 0) { + int i; + char *s = origargv[0]; + s += strlen(s); + /* See if all the arguments are contiguous in memory */ + for (i = 1; i < origargc; i++) { + if (origargv[i] == s + 1) + s += strlen(++s); /* this one is ok too */ + } + origarglen = s - origargv[0]; + } +#endif ruby_script(argv[0]); /* for the time being */ rb_argv0 = rb_progname;
--- ruby.c~ 2001/08/24 09:50:58 +++ ruby.c 2001/08/24 09:51:15 @@ -898,6 +898,14 @@ set_arg0(val, id) s = origargv[0]+i; *s++ = '\0'; - while (++i < len) + while (++i < len) { +#ifndef __linux__ *s++ = ' '; +#else + *s++ = '\0'; +#endif + } +#ifdef __linux__ + origargv[0][len] = ' '; +#endif } rb_progname = rb_tainted_str_new2(origargv[0]);
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦