diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-08-06 03:05:23 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-08-06 03:05:23 +0000 |
commit | f33a61c28dadf8ff2bb86d36d6428f487b671708 (patch) | |
tree | 6794731dfe7e2d526808376060893846f2ddc6c2 /ext | |
parent | 439b453e3aa244e7b824a55aa11768dca3d4a6f4 (diff) | |
download | ruby-f33a61c28dadf8ff2bb86d36d6428f487b671708.tar.gz |
* string.c (rb_str_lstrip_bang): new method.
* string.c (rb_str_rstrip_bang): new method.
* string.c (rb_str_associate): should consider STR_ASSOC too.
* eval.c (rb_undefined): do not recurse if method_missing is
undefined.
* process.c (proc_waitpid): now all arguments are optional.
* process.c (Init_process): waitpid is now alias to wait.
* process.c (Init_process): waitpid2 is now alias to wait2.
* process.c (rb_waitpid): made public.
* ext/pty/pty.c (pty_getpty): avoid disturbing SIGCHLD using
thread and rb_waitpid.
* process.c (proc_getpgrp): now takes no argument on all
platforms.
* process.c (proc_setpgrp): ditto.
* ext/socket/socket.c (sock_s_pack_sockaddr_in): added
Socket::pack_sockaddr_in(). [new]
* ext/socket/socket.c (sock_s_pack_sockaddr_un): added
Socket::pack_sockaddr_un(). [new]
* ext/socket/socket.c (sock_s_pack_sockaddr_in): added
Socket::unpack_sockaddr_in(). [new]
* ext/socket/socket.c (sock_s_pack_sockaddr_un): added
Socket::unpack_sockaddr_un(). [new]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1666 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r-- | ext/pty/pty.c | 126 | ||||
-rw-r--r-- | ext/socket/socket.c | 74 |
2 files changed, 101 insertions, 99 deletions
diff --git a/ext/pty/pty.c b/ext/pty/pty.c index 12063f958d..9d2fb52bcf 100644 --- a/ext/pty/pty.c +++ b/ext/pty/pty.c @@ -94,10 +94,6 @@ char SlaveName[DEVICELEN]; extern int errno; -#define MAX_PTY 16 -static int n_pty,last_pty; -static int chld_pid[MAX_PTY]; - #ifndef HAVE_SETEUID # ifdef HAVE_SETREUID # define seteuid(e) setreuid(-1, (e)) @@ -116,88 +112,44 @@ struct pty_info { }; static void -set_signal_action(action) - RETSIGTYPE (*action)(); +pty_raise(cpid) + int cpid; { -#ifdef __hpux - struct sigvec sv; - /* - * signal SIGCHLD should be delivered on stop of the child - */ - sv.sv_handler = action; - sv.sv_mask = sigmask(SIGCHLD); - sv.sv_flags = SV_BSDSIG; - sigvector(SIGCHLD, &sv, (struct sigvec *) 0); -#else /* not HPUX */ -#if defined(SA_NOCLDSTOP) - struct sigaction sa; - /* - * signal SIGCHLD should be delivered on stop of the child - * (for SVR4) - */ - sa.sa_handler = action; - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGCHLD); - sa.sa_flags = 0; /* SA_NOCLDSTOP flag is removed */ - sigaction(SIGCHLD, &sa, (struct sigaction *) 0); -#else - signal(SIGCHLD,action); -#endif -#endif /* not HPUX */ + 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); } -static void -reset_signal_action() +static VALUE +pty_syswait(pid) + int pid; { - set_signal_action(SIG_DFL); -} + int cpid, status; -static RETSIGTYPE -chld_changed() -{ - int cpid; - int i,n = -1; - int statusp; + cpid = rb_waitpid(pid, &status, WUNTRACED); - for (;;) { -#ifdef HAVE_WAITPID - cpid = waitpid(-1, &statusp, WUNTRACED|WNOHANG); -#else - cpid = wait3(&statusp, WUNTRACED|WNOHANG, 0); -#endif - if (cpid == 0 || cpid == -1) - return; - for (i = 0; i < last_pty; i++) { - if (chld_pid[i] == cpid) { - n = i; - goto catched; - } - } - rb_raise(rb_eRuntimeError, "fork: %d", cpid); - } - catched: + printf("PTY command (%d) finished (%d:%d)\n", pid, cpid, status); + if (cpid == 0 || cpid == -1) + return Qnil; #ifdef IF_STOPPED - if (IF_STOPPED(statusp)) { /* suspend */ - rb_raise(rb_eRuntimeError, "Stopped: %d",cpid); + if (IF_STOPPED(status)) { /* suspend */ + pty_raise(cpid); } #else #ifdef WIFSTOPPED - if (WIFSTOPPED(statusp)) { /* suspend */ - rb_raise(rb_eRuntimeError, "Stopped: %d",cpid); + if (WIFSTOPPED(status)) { /* suspend */ + pty_raise(cpid); } #else ---->> Either IF_STOPPED or WIFSTOPPED is needed <<---- #endif /* WIFSTOPPED */ #endif /* IF_STOPPED */ - if (n >= 0) { - chld_pid[n] = 0; - n_pty--; - if (n_pty == 0) - reset_signal_action(); - } - rb_raise(rb_eRuntimeError, "Child_changed: %d",cpid); + + return Qnil; } static void getDevice _((int*, int*)); @@ -227,7 +179,6 @@ establishShell(shellname, info) getDevice(&master,&slave); currentPid = getpid(); - set_signal_action(chld_changed); if((i = vfork()) < 0) { rb_sys_fail("fork failed"); } @@ -304,19 +255,6 @@ establishShell(shellname, info) close(slave); - if (n_pty == last_pty) { - chld_pid[n_pty] = i; - n_pty++; - last_pty++; - } - else { - for (j = 0; j < last_pty; j++) { - if (chld_pid[j] == 0) { - chld_pid[j] = i; - n_pty++; - } - } - } info->child_pid = i; info->fd = master; } @@ -426,16 +364,12 @@ static VALUE pty_getpty(self, shell) VALUE self, shell; { - VALUE res; + VALUE res, th; struct pty_info info; OpenFile *wfptr,*rfptr; NEWOBJ(rport, struct RFile); NEWOBJ(wport, struct RFile); - if (n_pty == MAX_PTY+1) { - rb_raise(rb_eRuntimeError, "Too many ptys are open"); - } - OBJSETUP(rport, rb_cFile, T_FILE); MakeOpenFile(rport, rfptr); @@ -457,32 +391,34 @@ pty_getpty(self, shell) 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); if (rb_block_given_p()) { - rb_yield((VALUE)res); - reset_signal_action(); - return Qnil; + res = rb_yield((VALUE)res); + rb_funcall(th, rb_intern("kill"), 0, 0); + return res; } else { return (VALUE)res; } } -/* ruby function: protect_signal */ +/* ruby function: protect_signal - obsolete */ static VALUE pty_protect(self) VALUE self; { - reset_signal_action(); + rb_warn("PTY::protect_signal is no longer needed"); rb_yield(Qnil); - set_signal_action(chld_changed); return self; } +/* ruby function: reset_signal - obsolete */ static VALUE pty_reset_signal(self) VALUE self; { - reset_signal_action(); + rb_warn("PTY::reset_signal is no longer needed"); return self; } diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 86f9dfcc28..d3e3fd53f0 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -1562,7 +1562,7 @@ static VALUE sock_s_socketpair(class, domain, type, protocol) VALUE class, domain, type, protocol; { -#if !defined(NT) && !defined(__BEOS__) && !defined(__EMX__) +#if !defined(NT) && !defined(__BEOS__) && !defined(__EMX__) && !defined(__QNXNTO__) int d, t, sp[2]; setup_domain_and_type(domain, &d, type, &t); @@ -1806,11 +1806,20 @@ sock_s_gethostbyaddr(argc, argv) { VALUE addr, type; struct hostent *h; + struct sockaddr *sa; + int t = AF_INET; rb_scan_args(argc, argv, "11", &addr, &type); - StringValue(addr); - h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len, - NIL_P(type)?AF_INET:NUM2INT(type)); + sa = (struct sockaddr*)StringValuePtr(addr); + if (!NIL_P(type)) { + t = NUM2INT(type); + } +#ifdef INET6 + else if (RSTRING(addr)->len == 16) { + t = AF_INET6; + } +#endif + h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len, t); return mkhostent(h); } @@ -2055,6 +2064,57 @@ sock_s_getnameinfo(argc, argv) rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error)); } +static VALUE +sock_s_pack_sockaddr_in(self, port, host) + VALUE self, port, host; +{ + struct addrinfo *res = ip_addrsetup(host, port); + VALUE addr = rb_str_new((char*)res->ai_addr, res->ai_addrlen); + + freeaddrinfo(res); + OBJ_INFECT(addr, port); + OBJ_INFECT(addr, host); + + return addr; +} + +static VALUE +sock_s_pack_sockaddr_un(self, path) + VALUE self, path; +{ + struct sockaddr_un sockaddr; + VALUE addr; + + MEMZERO(&sockaddr, struct sockaddr_un, 1); + sockaddr.sun_family = AF_UNIX; + strncpy(sockaddr.sun_path, StringValuePtr(path), sizeof(sockaddr.sun_path)-1); + addr = rb_str_new((char*)&sockaddr, sizeof(sockaddr)); + OBJ_INFECT(addr, path); + + return addr; +} + +static VALUE +sock_s_unpack_sockaddr_in(self, addr) + VALUE self, addr; +{ + struct sockaddr_in * sockaddr; + + sockaddr = (struct sockaddr_in*)StringValuePtr(addr); + return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), mkipaddr(sockaddr)); +} + +static VALUE +sock_s_unpack_sockaddr_un(self, addr) + VALUE self, addr; +{ + struct sockaddr_un * sockaddr; + + sockaddr = (struct sockaddr_un*)StringValuePtr(addr); + /* xxx: should I check against sun_path size? */ + return rb_tainted_str_new2(sockaddr->sun_path); +} + static VALUE mConst; static void @@ -2164,6 +2224,12 @@ Init_socket() rb_define_singleton_method(rb_cSocket, "getservbyname", sock_s_getservbyaname, -1); rb_define_singleton_method(rb_cSocket, "getaddrinfo", sock_s_getaddrinfo, -1); rb_define_singleton_method(rb_cSocket, "getnameinfo", sock_s_getnameinfo, -1); + rb_define_singleton_method(rb_cSocket, "sockaddr_in", sock_s_pack_sockaddr_in, 2); + rb_define_singleton_method(rb_cSocket, "sockaddr_un", sock_s_pack_sockaddr_un, 1); + rb_define_singleton_method(rb_cSocket, "pack_sockaddr_in", sock_s_pack_sockaddr_in, 2); + rb_define_singleton_method(rb_cSocket, "pack_sockaddr_un", sock_s_pack_sockaddr_un, 1); + rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_in", sock_s_unpack_sockaddr_in, 1); + rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_un", sock_s_unpack_sockaddr_un, 1); /* constants */ mConst = rb_define_module_under(rb_cSocket, "Constants"); |