Project

General

Profile

Bug #8770 ยป 0001-process.c-avoid-EINTR-from-Process.spawn.patch

avoid EINTR from Process.spawn - normalperson (Eric Wong), 08/11/2013 11:39 AM

View differences:

process.c
3283 3283
    }
3284 3284
}
3285 3285

  
3286
static ssize_t write_retry(int fd, const void *buf, size_t len)
3287
{
3288
	ssize_t w;
3289

  
3290
	do {
3291
		w = write(fd, buf, len);
3292
	} while (w < 0 && errno == EINTR);
3293

  
3294
	return w;
3295
}
3296

  
3297
static ssize_t read_retry(int fd, void *buf, size_t len)
3298
{
3299
	ssize_t r;
3300

  
3301
	do {
3302
		r = read(fd, buf, len);
3303
	} while (r < 0 && errno == EINTR);
3304

  
3305
	return r;
3306
}
3307

  
3286 3308
static void
3287 3309
send_child_error(int fd, int state, char *errmsg, size_t errmsg_buflen, int chfunc_is_async_signal_safe)
3288 3310
{
......
3290 3312
    int err;
3291 3313

  
3292 3314
    if (!chfunc_is_async_signal_safe) {
3293
        if (write(fd, &state, sizeof(state)) == sizeof(state) && state) {
3315
        if (write_retry(fd, &state, sizeof(state)) == sizeof(state) && state) {
3294 3316
            VALUE errinfo = rb_errinfo();
3295 3317
            io = rb_io_fdopen(fd, O_WRONLY|O_BINARY, NULL);
3296 3318
            rb_marshal_dump(errinfo, io);
......
3298 3320
        }
3299 3321
    }
3300 3322
    err = errno;
3301
    if (write(fd, &err, sizeof(err)) < 0) err = errno;
3323
    if (write_retry(fd, &err, sizeof(err)) < 0) err = errno;
3302 3324
    if (errmsg && 0 < errmsg_buflen) {
3303 3325
        errmsg[errmsg_buflen-1] = '\0';
3304 3326
        errmsg_buflen = strlen(errmsg);
3305
        if (errmsg_buflen > 0 && write(fd, errmsg, errmsg_buflen) < 0)
3327
        if (errmsg_buflen > 0 && write_retry(fd, errmsg, errmsg_buflen) < 0)
3306 3328
            err = errno;
3307 3329
    }
3308 3330
    if (!NIL_P(io)) rb_io_close(io);
......
3316 3338
    ssize_t size;
3317 3339
    VALUE exc = Qnil;
3318 3340
    if (!chfunc_is_async_signal_safe) {
3319
        if ((read(fd, &state, sizeof(state))) == sizeof(state) && state) {
3341
        if ((read_retry(fd, &state, sizeof(state))) == sizeof(state) && state) {
3320 3342
            io = rb_io_fdopen(fd, O_RDONLY|O_BINARY, NULL);
3321 3343
            exc = rb_marshal_load(io);
3322 3344
            rb_set_errinfo(exc);
......
3325 3347
        *excp = exc;
3326 3348
    }
3327 3349
#define READ_FROM_CHILD(ptr, len) \
3328
    (NIL_P(io) ? read(fd, (ptr), (len)) : rb_io_bufread(io, (ptr), (len)))
3350
    (NIL_P(io) ? read_retry(fd, (ptr), (len)) : rb_io_bufread(io, (ptr), (len)))
3329 3351
    if ((size = READ_FROM_CHILD(&err, sizeof(err))) < 0) {
3330 3352
        err = errno;
3331 3353
    }
3332
-