summaryrefslogtreecommitdiff
path: root/ext/pty
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-11-19 05:03:03 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-11-19 05:03:03 +0000
commitdf96f994f1a224070ffaa61eb2bcb969d0109246 (patch)
tree2e4bd7b58a1bc0a2b8d0e136f79a2997323e54d6 /ext/pty
parentd550569264a16e96121d05423f7516ce726d96c9 (diff)
* parse.y (parse_regx): should raise error on untermitated
expression interpolation. * pack.c (pack_unpack): should give length to utf8_to_uv(). * pack.c (utf8_to_uv): add length check. * massages: replace "wrong #" by "wrong number". * marshal.c (w_float): output Infinity and NaN explicitly. * marshal.c (r_object): support new explicit float format. * eval.c (rb_thread_wait_for): select may cause ERESTART on Solaris. * eval.c (rb_thread_select): ditto. * array.c (rb_ary_join): dumped core if sep is not T_STRING nor T_NIL. * array.c (rb_ary_join): buffer size calculattion was wrong. * array.c (rb_ary_to_s): if rb_output_fs is nil, insert newlines between array elements (use rb_default_rs as newline litral) [experimental]. * gc.c (init_mark_stack): no need to clear mark_stack. * gc.c (gc_mark_all): need to handle finalizer mark. * gc.c (gc_mark_rest): use MEMCPY instead of memcpy. * gc.c (rb_gc_mark): earlier const check to avoid pusing special constants into mark stack. * numeric.c (fix_to_s): 'to_s' now takes optional argument to specify radix. [new] * bignum.c (rb_big_to_s): ditto. [new] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1842 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/pty')
-rw-r--r--ext/pty/pty.c103
-rw-r--r--ext/pty/shl.rb8
2 files changed, 51 insertions, 60 deletions
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 7488698..c3a3a6f 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -1,6 +1,7 @@
#include "config.h"
#include <stdio.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>
@@ -31,6 +32,7 @@
#if !defined(HAVE_OPENPTY)
#ifdef __hpux
+static
char *MasterDevice = "/dev/ptym/pty%s",
*SlaveDevice = "/dev/pty/tty%s",
*deviceNo[] = {
@@ -54,6 +56,7 @@ char *MasterDevice = "/dev/ptym/pty%s",
};
#else /* NOT HPUX */
#ifdef _IBMESA /* AIX/ESA */
+static
char *MasterDevice = "/dev/ptyp%s",
*SlaveDevice = "/dev/ttyp%s",
*deviceNo[] = {
@@ -75,6 +78,7 @@ char *MasterDevice = "/dev/ptyp%s",
"f0","f1","f2","f3","f4","f5","f6","f7","f8","f9","fa","fb","fc","fd","fe","ff",
};
#else
+static
char *MasterDevice = "/dev/pty%s",
*SlaveDevice = "/dev/tty%s",
*deviceNo[] = {
@@ -90,7 +94,7 @@ char *MasterDevice = "/dev/pty%s",
#endif /* HPUX */
#endif /* !defined(HAVE_OPENPTY) */
-char SlaveName[DEVICELEN];
+static char SlaveName[DEVICELEN];
extern int errno;
@@ -107,64 +111,69 @@ extern int errno;
#endif /* NO_SETEUID */
struct pty_info {
- int fd;
- pid_t child_pid;
+ int fd;
+ pid_t child_pid;
+ VALUE thread;
};
static void
-pty_raise(cpid)
+pty_raise(thread, cpid, stop)
+ VALUE thread;
int cpid;
+ int stop;
{
char buf[1024];
- snprintf(buf, sizeof(buf),
- "eval %%Q{Thread.main.raise 'pty - stopped: %d'}, nil, \"%s\", %d",
- cpid, ruby_sourcefile, ruby_sourceline);
- rb_eval_string(buf);
+ snprintf(buf, sizeof(buf), "pty - %s: %d", stop ? "stopped" : "changed", cpid);
+ rb_funcall(thread, rb_intern("raise"), 1, rb_str_new2(buf));
}
static VALUE
-pty_syswait(pid)
- int pid;
+pty_syswait(info)
+ struct pty_info *info;
{
int cpid, status;
- cpid = rb_waitpid(pid, &status, WUNTRACED);
-
- printf("PTY command (%d) finished (%d:%d)\n", pid, cpid, status);
+ cpid = rb_waitpid(info->child_pid, &status, WUNTRACED);
+ printf("cpid: %d (%d)\n", cpid, status);
+
if (cpid == 0 || cpid == -1)
return Qnil;
#ifdef IF_STOPPED
if (IF_STOPPED(status)) { /* suspend */
- pty_raise(cpid);
+ pty_raise(info->thread, cpid, Qtrue);
}
#else
#ifdef WIFSTOPPED
if (WIFSTOPPED(status)) { /* suspend */
- pty_raise(cpid);
+ pty_raise(info->thread, cpid, Qtrue);
}
#else
---->> Either IF_STOPPED or WIFSTOPPED is needed <<----
#endif /* WIFSTOPPED */
#endif /* IF_STOPPED */
+ pty_raise(info->thread, cpid, Qfalse);
return Qnil;
}
static void getDevice _((int*, int*));
static void
-establishShell(shellname, info)
- char *shellname;
+establishShell(argc, argv, info)
+ int argc;
+ VALUE *argv;
struct pty_info *info;
{
- static int i,j,master,slave,currentPid;
+ static int i,master,slave,currentPid;
char *p,*getenv();
struct passwd *pwent;
- RETSIGTYPE chld_changed();
-
- if (shellname[0] == '\0') {
+ VALUE v;
+
+ if (argc == 0) {
+ char *shellname;
+
if ((p = getenv("SHELL")) != NULL) {
shellname = p;
}
@@ -175,17 +184,20 @@ establishShell(shellname, info)
else
shellname = "/bin/sh";
}
+ v = rb_str_new2(shellname);
+ argc = 1;
+ argv = &v;
}
getDevice(&master,&slave);
currentPid = getpid();
- if((i = vfork()) < 0) {
+ if((i = fork()) < 0) {
rb_sys_fail("fork failed");
}
if(i == 0) { /* child */
- int argc;
- char *argv[1024];
+ /* int argc;
+ char *argv[1024]; */
currentPid = getpid();
/*
@@ -232,23 +244,11 @@ establishShell(shellname, info)
dup2(slave,1);
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);
+ rb_f_exec(argc, argv);
sleep(1);
_exit(1);
}
@@ -361,8 +361,10 @@ freeDevice()
/* ruby function: getpty */
static VALUE
-pty_getpty(self, command)
- VALUE self, command;
+pty_getpty(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
{
VALUE res, th;
struct pty_info info;
@@ -373,35 +375,28 @@ pty_getpty(self, command)
MakeOpenFile(rport, rfptr);
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(argc, argv, &info);
rfptr->mode = rb_io_mode_flags("r");
rfptr->f = fdopen(info.fd, "r");
- rfptr->path = strdup(RSTRING(command)->ptr);
+ rfptr->path = 0; /*strdup(RSTRING(command)->ptr); */
wfptr->mode = rb_io_mode_flags("w");
wfptr->f = fdopen(dup(info.fd), "w");
- wfptr->path = strdup(RSTRING(command)->ptr);
+ wfptr->path = 0; /* strdup(RSTRING(command)->ptr); */
res = rb_ary_new2(3);
rb_ary_store(res,0,(VALUE)rport);
rb_ary_store(res,1,(VALUE)wport);
rb_ary_store(res,2,INT2FIX(info.child_pid));
- printf("start watching PTY command (%d)\n", info.child_pid);
- th = rb_thread_create(pty_syswait, (void*)info.child_pid);
+ info.thread = rb_thread_current();
+ th = rb_thread_create(pty_syswait, (void*)&info);
if (rb_block_given_p()) {
res = rb_yield((VALUE)res);
rb_funcall(th, rb_intern("kill"), 0, 0);
- return res;
- }
- else {
- return res;
}
+ return res;
}
/* ruby function: protect_signal - obsolete */
@@ -429,8 +424,8 @@ void
Init_pty()
{
cPTY = rb_define_module("PTY");
- rb_define_module_function(cPTY,"getpty",pty_getpty,1);
- rb_define_module_function(cPTY,"spawn",pty_getpty,1);
+ rb_define_module_function(cPTY,"getpty",pty_getpty,-1);
+ rb_define_module_function(cPTY,"spawn",pty_getpty,-1);
rb_define_module_function(cPTY,"protect_signal",pty_protect,0);
rb_define_module_function(cPTY,"reset_signal",pty_reset_signal,0);
}
diff --git a/ext/pty/shl.rb b/ext/pty/shl.rb
index 0c04a27..cdaf8d7 100644
--- a/ext/pty/shl.rb
+++ b/ext/pty/shl.rb
@@ -18,9 +18,7 @@ $r_pty = nil
$w_pty = nil
def writer
- PTY.protect_signal do
- system "stty -echo raw"
- end
+ system "stty -echo raw"
begin
while true
c = STDIN.getc
@@ -35,9 +33,7 @@ def writer
$reader.raise(nil)
return 'Exit'
ensure
- PTY.protect_signal do
- system "stty echo -raw"
- end
+ system "stty echo -raw"
end
end