mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29171 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									163b4dee96
								
							
						
					
					
						commit
						aa5c05b8ba
					
				
					 4 changed files with 124 additions and 58 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,11 @@
 | 
			
		|||
Fri Sep  3 06:40:44 2010  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* 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@fsij.org>
 | 
			
		||||
 | 
			
		||||
	* ext/pathname/pathname.c (path_pipe_p): Pathname#pipe?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,18 +135,6 @@ struct pty_info {
 | 
			
		|||
 | 
			
		||||
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 @@ chfunc(void *data, char *errbuf, size_t errbuf_len)
 | 
			
		|||
    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 @@ chfunc(void *data, char *errbuf, size_t errbuf_len)
 | 
			
		|||
    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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										88
									
								
								io.c
									
										
									
									
									
								
							
							
						
						
									
										88
									
								
								io.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -556,30 +556,36 @@ wsplit_p(rb_io_t *fptr)
 | 
			
		|||
    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 @@ rb_read_internal(int fd, void *buf, size_t count)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
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 @@ make_writeconv(rb_io_t *fptr)
 | 
			
		|||
struct binwrite_arg {
 | 
			
		||||
    rb_io_t *fptr;
 | 
			
		||||
    VALUE str;
 | 
			
		||||
    long offset;
 | 
			
		||||
    const char *ptr;
 | 
			
		||||
    long length;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -825,15 +831,14 @@ io_binwrite_string(VALUE arg)
 | 
			
		|||
{
 | 
			
		||||
    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 @@ io_binwrite(VALUE str, rb_io_t *fptr, int nosync)
 | 
			
		|||
                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 @@ io_binwrite(VALUE str, rb_io_t *fptr, int nosync)
 | 
			
		|||
	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 @@ io_binwrite(VALUE str, rb_io_t *fptr, int nosync)
 | 
			
		|||
        }
 | 
			
		||||
        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 @@ io_binwrite(VALUE str, rb_io_t *fptr, int nosync)
 | 
			
		|||
            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,7 +946,18 @@ static long
 | 
			
		|||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -1520,33 +1536,31 @@ read_buffered_data(char *ptr, long len, rb_io_t *fptr)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
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 @@ io_fread(VALUE str, long offset, rb_io_t *fptr)
 | 
			
		|||
	    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 @@ copy_stream_body(VALUE arg)
 | 
			
		|||
        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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										60
									
								
								process.c
									
										
									
									
									
								
							
							
						
						
									
										60
									
								
								process.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -137,6 +137,9 @@ static VALUE rb_cProcessTms;
 | 
			
		|||
	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 @@ pipe_nocrash(int filedes[2], VALUE fds)
 | 
			
		|||
    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 @@ rb_fork_err(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALU
 | 
			
		|||
    int err, state = 0;
 | 
			
		||||
#ifdef FD_CLOEXEC
 | 
			
		||||
    int ep[2];
 | 
			
		||||
    VALUE io = Qnil;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define prefork() (		\
 | 
			
		||||
| 
						 | 
				
			
			@ -2507,19 +2530,30 @@ rb_fork_err(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALU
 | 
			
		|||
    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 @@ rb_fork_err(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALU
 | 
			
		|||
#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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue