Skip to content

Commit

Permalink
implement rb_close_before_exec()
Browse files Browse the repository at this point in the history
  • Loading branch information
Watson1978 committed Jun 20, 2012
1 parent 077288b commit 6e11241
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
34 changes: 34 additions & 0 deletions io.c
Expand Up @@ -32,6 +32,10 @@
#include <sys/syscall.h>
#include <spawn.h>

#if !defined NOFILE
# define NOFILE 64
#endif

#define IS_FD_OF_STDIO(x) (x <= 2)
#define CLOSE_FD(fd) \
do { \
Expand Down Expand Up @@ -90,6 +94,8 @@ struct foreach_arg {
#define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
#define ARGF argf_of(argf)

static int max_file_descriptor = NOFILE;

static VALUE
pop_last_hash(int *argc_p, VALUE *argv)
{
Expand Down Expand Up @@ -494,6 +500,33 @@ rb_io_synchronized(rb_io_t *io_struct)
io_struct->mode |= FMODE_SYNC;
}

void
rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
{
int fd, ret;
int max = max_file_descriptor;
if (max < maxhint)
max = maxhint;
for (fd = lowfd; fd <= max; fd++) {
if (!NIL_P(noclose_fds) &&
RTEST(rb_hash_lookup(noclose_fds, INT2FIX(fd))))
continue;
#ifdef FD_CLOEXEC
ret = fcntl(fd, F_GETFD);
if (ret != -1 && !(ret & FD_CLOEXEC)) {
fcntl(fd, F_SETFD, ret|FD_CLOEXEC);
}
#else
ret = close(fd);
#endif
#define CONTIGUOUS_CLOSED_FDS 20
if (ret != -1) {
if (max < fd + CONTIGUOUS_CLOSED_FDS)
max = fd + CONTIGUOUS_CLOSED_FDS;
}
}
}

/*
* call-seq:
* ios.syswrite(string) => integer
Expand Down Expand Up @@ -578,6 +611,7 @@ io_write(VALUE io, SEL sel, VALUE data)
rb_io_t *io_struct = ExtractIOStruct(io);
rb_io_assert_writable(io_struct);

rb_thread_fd_writable(io_struct->write_fd);
ssize_t code = write(io_struct->write_fd, buffer, length);
if (code == -1) {
rb_sys_fail("write() failed");
Expand Down
2 changes: 1 addition & 1 deletion process.c
Expand Up @@ -2273,7 +2273,7 @@ rb_run_exec_options_err(const struct rb_exec_arg *e, struct rb_exec_arg *s, char
#ifdef HAVE_FORK
obj = rb_ary_entry(options, EXEC_OPTION_CLOSE_OTHERS);
if (obj != Qfalse) {
// TODO rb_close_before_exec(3, FIX2INT(obj), e->redirect_fds);
rb_close_before_exec(3, FIX2INT(obj), e->redirect_fds);
}
#endif

Expand Down

0 comments on commit 6e11241

Please sign in to comment.