[前][次][番号順一覧][スレッド一覧]

ruby-changes:17172

From: nobu <ko1@a...>
Date: Fri, 3 Sep 2010 06:41:29 +0900 (JST)
Subject: [ruby-changes:17172] Ruby:r29171 (trunk): * ext/pty/pty.c (chfunc): pass through exceptions.

nobu	2010-09-03 06:40:55 +0900 (Fri, 03 Sep 2010)

  New Revision: 29171

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29171

  Log:
    * ext/pty/pty.c (chfunc): pass through exceptions.
    
    * io.c (rb_io_bufwrite, rb_io_bufread): added.
    
    * process.c (rb_fork_err): protect from exceptions.

  Modified files:
    trunk/ChangeLog
    trunk/ext/pty/pty.c
    trunk/io.c
    trunk/process.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 29170)
+++ ChangeLog	(revision 29171)
@@ -1,3 +1,11 @@
+Fri Sep  3 06:40:44 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/pty/pty.c (chfunc): pass through exceptions.
+
+	* io.c (rb_io_bufwrite, rb_io_bufread): added.
+
+	* process.c (rb_fork_err): protect from exceptions.
+
 Fri Sep  3 06:16:07 2010  Tanaka Akira  <akr@f...>
 
 	* ext/pathname/pathname.c (path_pipe_p): Pathname#pipe?
Index: io.c
===================================================================
--- io.c	(revision 29170)
+++ io.c	(revision 29171)
@@ -556,30 +556,36 @@
     return fptr->mode & FMODE_WSPLIT;
 }
 
-struct io_internal_struct {
+struct io_internal_read_struct {
     int fd;
     void *buf;
     size_t capa;
 };
 
+struct io_internal_write_struct {
+    int fd;
+    const void *buf;
+    size_t capa;
+};
+
 static VALUE
 internal_read_func(void *ptr)
 {
-    struct io_internal_struct *iis = (struct io_internal_struct*)ptr;
+    struct io_internal_read_struct *iis = ptr;
     return read(iis->fd, iis->buf, iis->capa);
 }
 
 static VALUE
 internal_write_func(void *ptr)
 {
-    struct io_internal_struct *iis = (struct io_internal_struct*)ptr;
+    struct io_internal_write_struct *iis = ptr;
     return write(iis->fd, iis->buf, iis->capa);
 }
 
 static ssize_t
 rb_read_internal(int fd, void *buf, size_t count)
 {
-    struct io_internal_struct iis;
+    struct io_internal_read_struct iis;
     iis.fd = fd;
     iis.buf = buf;
     iis.capa = count;
@@ -588,9 +594,9 @@
 }
 
 static ssize_t
-rb_write_internal(int fd, void *buf, size_t count)
+rb_write_internal(int fd, const void *buf, size_t count)
 {
-    struct io_internal_struct iis;
+    struct io_internal_write_struct iis;
     iis.fd = fd;
     iis.buf = buf;
     iis.capa = count;
@@ -816,7 +822,7 @@
 struct binwrite_arg {
     rb_io_t *fptr;
     VALUE str;
-    long offset;
+    const char *ptr;
     long length;
 };
 
@@ -825,15 +831,14 @@
 {
     struct binwrite_arg *p = (struct binwrite_arg *)arg;
     long l = io_writable_length(p->fptr, p->length);
-    return rb_write_internal(p->fptr->fd, RSTRING_PTR(p->str)+p->offset, l);
+    return rb_write_internal(p->fptr->fd, p->ptr, l);
 }
 
 static long
-io_binwrite(VALUE str, rb_io_t *fptr, int nosync)
+io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
 {
-    long len, n, r, offset = 0;
+    long n, r, offset = 0;
 
-    len = RSTRING_LEN(str);
     if ((n = len) <= 0) return n;
     if (fptr->wbuf == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) {
         fptr->wbuf_off = 0;
@@ -852,7 +857,7 @@
                 MEMMOVE(fptr->wbuf, fptr->wbuf+fptr->wbuf_off, char, fptr->wbuf_len);
                 fptr->wbuf_off = 0;
             }
-            MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, RSTRING_PTR(str)+offset, char, len);
+            MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, ptr+offset, char, len);
             fptr->wbuf_len += (int)len;
             n = 0;
         }
@@ -868,14 +873,14 @@
 	arg.fptr = fptr;
 	arg.str = str;
       retry:
-	arg.offset = offset;
+	arg.ptr = ptr + offset;
 	arg.length = n;
 	if (fptr->write_lock) {
 	    r = rb_mutex_synchronize(fptr->write_lock, io_binwrite_string, (VALUE)&arg);
 	}
 	else {
 	    long l = io_writable_length(fptr, n);
-	    r = rb_write_internal(fptr->fd, RSTRING_PTR(str)+offset, l);
+	    r = rb_write_internal(fptr->fd, ptr+offset, l);
 	}
 	/* xxx: other threads may modify given string. */
         if (r == n) return len;
@@ -886,7 +891,7 @@
         }
         if (rb_io_wait_writable(fptr->fd)) {
             rb_io_check_closed(fptr);
-	    if (offset < RSTRING_LEN(str))
+	    if (offset < len)
 		goto retry;
         }
         return -1L;
@@ -897,7 +902,7 @@
             MEMMOVE(fptr->wbuf, fptr->wbuf+fptr->wbuf_off, char, fptr->wbuf_len);
         fptr->wbuf_off = 0;
     }
-    MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, RSTRING_PTR(str)+offset, char, len);
+    MEMMOVE(fptr->wbuf+fptr->wbuf_off+fptr->wbuf_len, ptr+offset, char, len);
     fptr->wbuf_len += (int)len;
     return len;
 }
@@ -941,9 +946,20 @@
 io_fwrite(VALUE str, rb_io_t *fptr, int nosync)
 {
     str = do_writeconv(str, fptr);
-    return io_binwrite(str, fptr, nosync);
+    return io_binwrite(str, RSTRING_PTR(str), RSTRING_LEN(str),
+		       fptr, nosync);
 }
 
+ssize_t
+rb_io_bufwrite(VALUE io, const void *buf, size_t size)
+{
+    rb_io_t *fptr;
+
+    GetOpenFile(io, fptr);
+    rb_io_check_writable(fptr);
+    return (ssize_t)io_binwrite(0, buf, (long)size, fptr, 0);
+}
+
 static VALUE
 io_write(VALUE io, VALUE str, int nosync)
 {
@@ -1520,33 +1536,31 @@
 }
 
 static long
-io_fread(VALUE str, long offset, rb_io_t *fptr)
+io_bufread(char *ptr, long len, rb_io_t *fptr)
 {
-    long len = RSTRING_LEN(str) - offset;
+    long offset = 0;
     long n = len;
     long c;
 
-    rb_str_locktmp(str);
     if (READ_DATA_PENDING(fptr) == 0) {
 	while (n > 0) {
           again:
-	    c = rb_read_internal(fptr->fd, RSTRING_PTR(str)+offset, n);
+	    c = rb_read_internal(fptr->fd, ptr+offset, n);
 	    if (c == 0) break;
 	    if (c < 0) {
                 if (rb_io_wait_readable(fptr->fd))
                     goto again;
-		rb_sys_fail_path(fptr->pathv);
+		return -1;
 	    }
 	    offset += c;
 	    if ((n -= c) <= 0) break;
 	    rb_thread_wait_fd(fptr->fd);
 	}
-	rb_str_unlocktmp(str);
 	return len - n;
     }
 
     while (n > 0) {
-	c = read_buffered_data(RSTRING_PTR(str)+offset, n, fptr);
+	c = read_buffered_data(ptr+offset, n, fptr);
 	if (c > 0) {
 	    offset += c;
 	    if ((n -= c) <= 0) break;
@@ -1557,10 +1571,32 @@
 	    break;
 	}
     }
-    rb_str_unlocktmp(str);
     return len - n;
 }
 
+static long
+io_fread(VALUE str, long offset, rb_io_t *fptr)
+{
+    long len;
+
+    rb_str_locktmp(str);
+    len = io_bufread(RSTRING_PTR(str) + offset, RSTRING_LEN(str) - offset,
+		     fptr);
+    rb_str_unlocktmp(str);
+    if (len < 0) rb_sys_fail_path(fptr->pathv);
+    return len;
+}
+
+ssize_t
+rb_io_bufread(VALUE io, void *buf, size_t size)
+{
+    rb_io_t *fptr;
+
+    GetOpenFile(io, fptr);
+    rb_io_check_readable(fptr);
+    return (ssize_t)io_bufread(buf, (long)size, fptr);
+}
+
 #define SMALLBUF 100
 
 static long
@@ -8475,7 +8511,7 @@
         rb_str_resize(str,len);
         read_buffered_data(RSTRING_PTR(str), len, src_fptr);
         if (dst_fptr) { /* IO or filename */
-            if (io_binwrite(str, dst_fptr, 0) < 0)
+            if (io_binwrite(str, RSTRING_PTR(str), RSTRING_LEN(str), dst_fptr, 0) < 0)
                 rb_sys_fail(0);
         }
         else /* others such as StringIO */
Index: process.c
===================================================================
--- process.c	(revision 29170)
+++ process.c	(revision 29171)
@@ -137,6 +137,9 @@
 	do {int saved_errno = errno; stmts; errno = saved_errno;} while (0)
 
 
+ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size);
+ssize_t rb_io_bufread(VALUE io, void *buf, size_t size);
+
 /*
  *  call-seq:
  *     Process.pid   -> fixnum
@@ -2430,6 +2433,25 @@
     return ret;
 }
 
+struct chfunc_protect_t {
+    int (*chfunc)(void*, char *, size_t);
+    void *arg;
+    char *errmsg;
+    size_t buflen;
+};
+
+static VALUE
+chfunc_protect(VALUE arg)
+{
+    struct chfunc_protect_t *p = (struct chfunc_protect_t *)arg;
+
+    return (VALUE)(*p->chfunc)(p->arg, p->errmsg, p->buflen);
+}
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 /*
  * Forks child process, and returns the process ID in the parent
  * process.
@@ -2461,6 +2483,7 @@
     int err, state = 0;
 #ifdef FD_CLOEXEC
     int ep[2];
+    VALUE io = Qnil;
 #endif
 
 #define prefork() (		\
@@ -2507,19 +2530,30 @@
     if (!pid) {
         forked_child = 1;
 	if (chfunc) {
+	    struct chfunc_protect_t arg;
+	    arg.chfunc = chfunc;
+	    arg.arg = charg;
+	    arg.errmsg = errmsg;
+	    arg.buflen = errmsg_buflen;
 #ifdef FD_CLOEXEC
 	    close(ep[0]);
 #endif
-	    if (!(*chfunc)(charg, errmsg, errmsg_buflen)) _exit(EXIT_SUCCESS);
+	    if (!(int)rb_protect(chfunc_protect, (VALUE)&arg, &state)) _exit(EXIT_SUCCESS);
 #ifdef FD_CLOEXEC
+	    if (write(ep[1], &state, sizeof(state)) == sizeof(state) && state) {
+		io = rb_io_fdopen(ep[1], O_WRONLY|O_BINARY, NULL);
+		rb_marshal_dump(rb_errinfo(), io);
+		rb_io_flush(io);
+	    }
 	    err = errno;
 	    if (write(ep[1], &err, sizeof(err)) < 0) err = errno;
             if (errmsg && 0 < errmsg_buflen) {
                 errmsg[errmsg_buflen-1] = '\0';
                 errmsg_buflen = strlen(errmsg);
 		if (errmsg_buflen > 0 &&write(ep[1], errmsg, errmsg_buflen) < 0)
-                  err = errno;
+		    err = errno;
             }
+	    if (!NIL_P(io)) rb_io_close(io);
 #endif
 #if EXIT_SUCCESS == 127
 	    _exit(EXIT_FAILURE);
@@ -2532,25 +2566,37 @@
 #ifdef FD_CLOEXEC
     if (pid && chfunc) {
 	ssize_t size;
+	VALUE exc = Qnil;
 	close(ep[1]);
-	if ((size = read(ep[0], &err, sizeof(err))) < 0) {
+	if ((read(ep[0], &state, sizeof(state))) == sizeof(state) && state) {
+	    io = rb_io_fdopen(ep[0], O_RDONLY|O_BINARY, NULL);
+	    exc = rb_marshal_load(io);
+	    rb_set_errinfo(exc);
+	}
+#define READ_FROM_CHILD(ptr, len) \
+	(NIL_P(io) ? read(ep[0], ptr, len) : rb_io_bufread(io, ptr, len))
+	if ((size = READ_FROM_CHILD(&err, sizeof(err))) < 0) {
 	    err = errno;
 	}
         if (size == sizeof(err) &&
             errmsg && 0 < errmsg_buflen) {
-            ssize_t ret;
-            ret = read(ep[0], errmsg, errmsg_buflen-1);
+	    ssize_t ret = READ_FROM_CHILD(errmsg, errmsg_buflen-1);
             if (0 <= ret) {
                 errmsg[ret] = '\0';
             }
         }
-	close(ep[0]);
-	if (size) {
+	if (NIL_P(io))
+	    close(ep[0]);
+	else
+	    rb_io_close(io);
+	if (state || size) {
 	    if (status) {
+		*status = state;
 		rb_protect(proc_syswait, (VALUE)pid, status);
 	    }
 	    else {
 		rb_syswait(pid);
+		if (state) rb_exc_raise(exc);
 	    }
 	    errno = err;
 	    return -1;
Index: ext/pty/pty.c
===================================================================
--- ext/pty/pty.c	(revision 29170)
+++ ext/pty/pty.c	(revision 29171)
@@ -135,18 +135,6 @@
 
 static void getDevice(int*, int*, char [DEVICELEN], int);
 
-struct exec_info {
-    int argc;
-    VALUE *argv;
-};
-
-static VALUE
-pty_exec(VALUE v)
-{
-    struct exec_info *arg = (struct exec_info *)v;
-    return rb_f_exec(arg->argc, arg->argv);
-}
-
 struct child_info {
     int master, slave;
     char *slavename;
@@ -162,10 +150,7 @@
     int slave = carg->slave;
     int argc = carg->argc;
     VALUE *argv = carg->argv;
-    VALUE exc;
 
-    struct exec_info arg;
-    int status;
 #define ERROR_EXIT(str) do { \
 	strlcpy(errbuf, str, errbuf_len); \
 	return -1; \
@@ -218,16 +203,7 @@
     seteuid(getuid());
 #endif
 
-    arg.argc = argc;
-    arg.argv = argv;
-    rb_protect(pty_exec, (VALUE)&arg, &status);
-    sleep(1);
-    errno = ENOENT;		/* last resort */
-    exc = rb_errinfo();
-    if (!NIL_P(exc)) {
-	errno = NUM2INT(rb_attr_get(exc, rb_intern("errno")));
-    }
-    ERROR_EXIT(StringValueCStr(argv[0]));
+    return rb_f_exec(argc, argv);
 #undef ERROR_EXIT
 }
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]