From: nobu.nakada@... Date: 2003-12-12T17:19:03+09:00 Subject: [ruby-list:38899] Re: pty problem なかだです。 At Fri, 12 Dec 2003 12:32:44 +0900, Takahiro Kambe wrote: > > > execvp の直前で timer を clear するよう以下のような修正をしたところ、 > > > RuntimeError が上がる現象がおさまるようになりました。 > > > > 1.8では、rb_f_exec()、つまりKernel#execを使うように修正されてい > > ます。1.6にバックポートしてもいいのですが、もう1.6.9は出ないと > > いうことになっていますから、1.8への移行をお勧めします。 > 1.6でも、単純にrb_f_exec()を使うように直せば済むのでしょうか。 1.6だとrb_f_exec()はstaticなので、単純には無理ですね。 > 1.6.9は出なくとも、CVSの1.6のブランチで確実な修正がされていると嬉しい > ケースは存在しますので、できればバックポートしていただきたいと思います。 > > 1.8への移行が困難な場合や、パッケージ・システムで1.8ベースのrubyがサポー > トされるのに、まだ時間がかかりそうなOSもありますので...。 今から1.6系を各環境で確認するのが面倒というのが、あまりやりたく ない理由です。やっぱりリリースされないとなかなか。 これで直るでしょうか。 Index: pty.c =================================================================== RCS file: /cvs/ruby/src/ruby/ext/pty/pty.c,v retrieving revision 1.5.2.5 diff -u -2 -p -r1.5.2.5 pty.c --- ext/pty/pty.c 28 Jan 2002 08:42:38 -0000 1.5.2.5 +++ ext/pty/pty.c 12 Dec 2003 08:05:01 -0000 @@ -203,7 +203,19 @@ chld_changed() static void getDevice _((int*, int*)); +struct exec_info { + int argc; + VALUE *argv; +}; + +static VALUE +pty_exec(arg) + struct exec_info *arg; +{ + return rb_funcall2(Qnil, rb_intern("exec"), arg->argc, arg->argv); +} + static void -establishShell(shellname, info) - char *shellname; +establishShell(command, info) + VALUE command; struct pty_info *info; { @@ -211,7 +223,20 @@ establishShell(shellname, info) char *p,*getenv(); struct passwd *pwent; - RETSIGTYPE chld_changed(); - - if (shellname[0] == '\0') { + VALUE v, *argv; + struct exec_info arg; + int status, argc; + + if (TYPE(command) == T_ARRAY) { + argc = RARRAY(command)->len; + argv = RARRAY(command)->ptr; + } + else { + Check_SafeStr(command); + argc = RSTRING(command)->len ? 1 : 0; + argv = &command; + } + if (argc == 0) { + char *shellname; + if ((p = getenv("SHELL")) != NULL) { shellname = p; @@ -224,4 +249,7 @@ establishShell(shellname, info) shellname = "/bin/sh"; } + v = rb_str_new2(shellname); + argc = 1; + argv = &v; } getDevice(&master,&slave); @@ -229,11 +257,11 @@ establishShell(shellname, info) currentPid = getpid(); set_signal_action(chld_changed); - if((i = vfork()) < 0) { + if((i = fork()) < 0) { + close(master); + close(slave); rb_sys_fail("fork failed"); } if(i == 0) { /* child */ - int argc; - char *argv[1024]; currentPid = getpid(); @@ -282,21 +310,11 @@ establishShell(shellname, info) dup2(slave,2); close(slave); - #if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID) seteuid(getuid()); #endif - argc = 0; - for (i = 0; shellname[i];) { - while (isspace(shellname[i])) i++; - for (j = i; shellname[j] && !isspace(shellname[j]); j++); - argv[argc] = (char*)xmalloc(j-i+1); - strncpy(argv[argc],&shellname[i],j-i); - argv[argc][j-i] = 0; - i = j; - argc++; - } - argv[argc] = NULL; - execvp(argv[0],argv); + arg.argc = argc; + arg.argv = argv; + rb_protect(pty_exec, (VALUE)&arg, &status); sleep(1); _exit(1); @@ -443,9 +461,5 @@ pty_getpty(self, command) MakeOpenFile(wport, wfptr); - if (TYPE(command) == T_ARRAY) - command = rb_ary_join(command,rb_str_new2(" ")); - Check_SafeStr(command); - - establishShell(RSTRING(command)->ptr,&info); + establishShell(command, &info); rfptr->mode = rb_io_mode_flags("r"); -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦