summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-08-06 03:05:23 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-08-06 03:05:23 +0000
commitf33a61c28dadf8ff2bb86d36d6428f487b671708 (patch)
tree6794731dfe7e2d526808376060893846f2ddc6c2 /ext
parent439b453e3aa244e7b824a55aa11768dca3d4a6f4 (diff)
* 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.c126
-rw-r--r--ext/socket/socket.c74
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");