$NetBSD: patch-am,v 1.1 2004/03/12 04:59:20 taca Exp $ --- ext/pty/pty.c.orig 2002-01-27 02:15:53.000000000 +0900 +++ ext/pty/pty.c @@ -202,17 +202,41 @@ chld_changed() static void getDevice _((int*, int*)); -static void -establishShell(shellname, info) - char *shellname; +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); +} + +establishShell(command, info) + VALUE command; struct pty_info *info; { static int i,j,master,slave,currentPid; 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; } @@ -223,18 +247,21 @@ establishShell(shellname, info) else shellname = "/bin/sh"; } + v = rb_str_new2(shellname); + argc = 1; + argv = &v; } getDevice(&master,&slave); 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(); /* @@ -286,19 +313,10 @@ establishShell(shellname, info) 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; + arg.argc = argc; + arg.argv = argv; + rb_protect(pty_exec, (VALUE)&arg, &status); execvp(argv[0],argv); - sleep(1); _exit(1); } @@ -442,11 +460,7 @@ pty_getpty(self, command) OBJSETUP(wport, rb_cFile, T_FILE); 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"); rfptr->f = fdopen(info.fd, "r");