diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-08-16 20:47:28 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-08-16 22:53:00 +0900 |
commit | 7d3634a121736eea1a43a332b9abd0540d3a6300 (patch) | |
tree | 4ca6d2d68a670b5405bb23772356f512d9df3abb /io.c | |
parent | f0edcd8283e1aeda9ff2d04926ec8041b421f890 (diff) |
Extract GC for fd parts as `TRY_WITH_GC `
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 57 |
1 files changed, 22 insertions, 35 deletions
@@ -1063,20 +1063,24 @@ rb_gc_for_fd(int err) return 0; } +/* try `expr` upto twice while it returns false and `errno` + * is to GC. Each `errno`s are available as `first_errno` and + * `retried_errno` respectively */ +#define TRY_WITH_GC(expr) \ + for (int first_errno, retried_errno = 0, retried = 0; \ + (!retried && \ + !(expr) && \ + (!rb_gc_for_fd(first_errno = errno) || !(expr)) && \ + (retried_errno = errno, 1)); \ + (void)retried_errno, retried = 1) + static int ruby_dup(int orig) { - int fd; + int fd = -1; - fd = rb_cloexec_dup(orig); - if (fd < 0) { - int e = errno; - if (rb_gc_for_fd(e)) { - fd = rb_cloexec_dup(orig); - } - if (fd < 0) { - rb_syserr_fail(e, 0); - } + TRY_WITH_GC((fd = rb_cloexec_dup(orig)) >= 0) { + rb_syserr_fail(first_errno, 0); } rb_update_max_fd(fd); return fd; @@ -6945,7 +6949,7 @@ rb_sysopen_internal(struct sysopen_struct *data) static int rb_sysopen(VALUE fname, int oflags, mode_t perm) { - int fd; + int fd = -1; struct sysopen_struct data; data.fname = rb_str_encode_ospath(fname); @@ -6953,15 +6957,8 @@ rb_sysopen(VALUE fname, int oflags, mode_t perm) data.oflags = oflags; data.perm = perm; - fd = rb_sysopen_internal(&data); - if (fd < 0) { - int e = errno; - if (rb_gc_for_fd(e)) { - fd = rb_sysopen_internal(&data); - } - if (fd < 0) { - rb_syserr_fail_path(e, fname); - } + TRY_WITH_GC((fd = rb_sysopen_internal(&data)) >= 0) { + rb_syserr_fail_path(first_errno, fname); } return fd; } @@ -6988,15 +6985,10 @@ fdopen_internal(int fd, const char *modestr) FILE * rb_fdopen(int fd, const char *modestr) { - FILE *file = fdopen_internal(fd, modestr); - if (!file) { - int e = errno; - if (rb_gc_for_fd(e)) { - file = fdopen_internal(fd, modestr); - } - if (!file) { - rb_syserr_fail(e, 0); - } + FILE *file = 0; + + TRY_WITH_GC((file = fdopen_internal(fd, modestr)) != 0) { + rb_syserr_fail(first_errno, 0); } /* xxx: should be _IONBF? A buffer in FILE may have trouble. */ @@ -7287,12 +7279,7 @@ int rb_pipe(int *pipes) { int ret; - ret = rb_cloexec_pipe(pipes); - if (ret < 0) { - if (rb_gc_for_fd(errno)) { - ret = rb_cloexec_pipe(pipes); - } - } + TRY_WITH_GC((ret = rb_cloexec_pipe(pipes)) >= 0); if (ret == 0) { rb_update_max_fd(pipes[0]); rb_update_max_fd(pipes[1]); |