Feature #9328 ยป 0001-avoid-redundant-F_GETFD-when-O_CLOEXEC-works.patch
io.c | ||
---|---|---|
rb_update_max_fd(fd);
|
||
}
|
||
/* this is only called once */
|
||
static int
|
||
rb_fix_detect_o_cloexec(int fd)
|
||
{
|
||
#ifdef O_CLOEXEC
|
||
int flags = fcntl(fd, F_GETFD);
|
||
if (flags == -1)
|
||
rb_bug("rb_fix_detect_o_cloexec: fcntl(%d, F_GETFD) failed: %s", fd, strerror(errno));
|
||
if (flags & FD_CLOEXEC)
|
||
return 1;
|
||
#endif /* fall through if O_CLOEXEC does not work: */
|
||
rb_maygvl_fd_fix_cloexec(fd);
|
||
return 0;
|
||
}
|
||
int
|
||
rb_cloexec_open(const char *pathname, int flags, mode_t mode)
|
||
{
|
||
int ret;
|
||
static int o_cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */
|
||
#ifdef O_CLOEXEC
|
||
/* O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */
|
||
flags |= O_CLOEXEC;
|
||
... | ... | |
#endif
|
||
ret = open(pathname, flags, mode);
|
||
if (ret == -1) return -1;
|
||
rb_maygvl_fd_fix_cloexec(ret);
|
||
if (ret <= 2 || o_cloexec_state == 0) {
|
||
rb_maygvl_fd_fix_cloexec(ret);
|
||
} else if (o_cloexec_state > 0) {
|
||
return ret;
|
||
} else {
|
||
o_cloexec_state = rb_fix_detect_o_cloexec(ret);
|
||
}
|
||
return ret;
|
||
}
|
||