ruby-changes:2492
From: ko1@a...
Date: 20 Nov 2007 17:12:49 +0900
Subject: [ruby-changes:2492] akr - Ruby:r13983 (trunk): * io.c (rb_io_close_on_exec_p): new method IO#close_on_exec?.
akr 2007-11-20 17:12:34 +0900 (Tue, 20 Nov 2007) New Revision: 13983 Modified files: trunk/ChangeLog trunk/io.c Log: * io.c (rb_io_close_on_exec_p): new method IO#close_on_exec?. (rb_io_set_close_on_exec): new method IO#close_on_exec=. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13983&r2=13982 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/io.c?r1=13983&r2=13982 Index: ChangeLog =================================================================== --- ChangeLog (revision 13982) +++ ChangeLog (revision 13983) @@ -1,3 +1,8 @@ +Tue Nov 20 17:10:11 2007 Tanaka Akira <akr@f...> + + * io.c (rb_io_close_on_exec_p): new method IO#close_on_exec?. + (rb_io_set_close_on_exec): new method IO#close_on_exec=. + Tue Nov 20 16:24:31 2007 Tanaka Akira <akr@f...> * gc.c (gc_mark_children): obj->as.file.fptr may be 0 for T_FILE. Index: io.c =================================================================== --- io.c (revision 13982) +++ io.c (revision 13983) @@ -2295,6 +2295,99 @@ return Qtrue; } +/* + * call-seq: + * ios.close_on_exec? => true or false + * + * Returns <code>true</code> if <em>ios</em> will be closed on exec. + * + * f = open("/dev/null") + * f.close_on_exec? #=> false + * f.close_on_exec = true + * f.close_on_exec? #=> true + * f.close_on_exec = false + * f.close_on_exec? #=> false + */ + +static VALUE +rb_io_close_on_exec_p(VALUE io) +{ +#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) + rb_io_t *fptr; + VALUE write_io; + int fd, ret; + + write_io = GetWriteIO(io); + if (io != write_io) { + GetOpenFile(write_io, fptr); + if (fptr && 0 <= (fd = fptr->fd)) { + if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail(fptr->path); + if (!(ret & FD_CLOEXEC)) return Qfalse; + } + } + + GetOpenFile(io, fptr); + if (fptr && 0 <= (fd = fptr->fd)) { + if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail(fptr->path); + if (!(ret & FD_CLOEXEC)) return Qfalse; + } + return Qtrue; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif +} + +/* + * call-seq: + * ios.close_on_exec = bool => true or false + * + * Sets a close-on-exec flag. + * + * f = open("/dev/null") + * f.close_on_exec = true + * system("cat", "/proc/self/fd/#{f.fileno}") # cat: /proc/self/fd/3: No such file or directory + * f.closed? #=> false + */ + +static VALUE +rb_io_set_close_on_exec(VALUE io, VALUE arg) +{ +#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) + int flag = RTEST(arg) ? FD_CLOEXEC : 0; + rb_io_t *fptr; + VALUE write_io; + int fd, ret; + + write_io = GetWriteIO(io); + if (io != write_io) { + GetOpenFile(write_io, fptr); + if (fptr && 0 <= (fd = fptr->fd)) { + if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) rb_sys_fail(fptr->path); + if ((ret & FD_CLOEXEC) != flag) { + ret = (ret & ~FD_CLOEXEC) | flag; + ret = fcntl(fd, F_SETFD, ret); + if (ret == -1) rb_sys_fail(fptr->path); + } + } + + } + + GetOpenFile(io, fptr); + if (fptr && 0 <= (fd = fptr->fd)) { + if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail(fptr->path); + if ((ret & FD_CLOEXEC) != flag) { + ret = (ret & ~FD_CLOEXEC) | flag; + ret = fcntl(fd, F_SETFD, ret); + if (ret == -1) rb_sys_fail(fptr->path); + } + } +#else + rb_notimplement(); +#endif + return Qnil; +} + #define FMODE_PREP (1<<16) #define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP) #define PREP_STDIO_NAME(f) ((f)->path) @@ -6021,6 +6114,9 @@ rb_define_method(rb_cIO, "eof", rb_io_eof, 0); rb_define_method(rb_cIO, "eof?", rb_io_eof, 0); + rb_define_method(rb_cIO, "close_on_exec?", rb_io_close_on_exec_p, 0); + rb_define_method(rb_cIO, "close_on_exec=", rb_io_set_close_on_exec, 1); + rb_define_method(rb_cIO, "close", rb_io_close_m, 0); rb_define_method(rb_cIO, "closed?", rb_io_closed, 0); rb_define_method(rb_cIO, "close_read", rb_io_close_read, 0); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml