IO.popen("echo a") clear O_APPEND of other fds

e$B0J2<$N$h$&$K!"e(BIO.popen(“echo a”) e$B$,4X78$J$$B>$Ne(B IO e$B$Ne(B
O_APPEND e$B$r>C$7$F$7$^$&$h$&$G$9!#e(B

% ./ruby -rfcntl -ve ’
p File::APPEND.to_s(16)
open(“z”, File::RDWR|File::APPEND|File::TRUNC|File::CREAT)
{|f|
f.print " "
f.rewind; f.print “x”; f.rewind; p f.read
f.rewind; f.print “x”; f.rewind; p f.read
f.rewind; f.print “x”; f.rewind; p f.read
p f.fcntl(Fcntl::F_GETFL).to_s(16)
IO.popen(“echo a”) {|q| q.read }
p f.fcntl(Fcntl::F_GETFL).to_s(16)
f.rewind; f.print “x”; f.rewind; p f.read
}’
ruby 1.9.0 (2006-07-02) [i686-linux]
“400”
" x"
" xx"
" xxx"
“8402”
“8002”
“x xxx”

e$B2?2s$+e(B f.rewind; f.print “x” e$B$7$F$$$^$9$,!"e(Bf e$B$K$Oe(B
O_APPEND
e$B$,$D$$$F$$$k$N$Ge(B write e$B$7$?$b$N$O%U%!%$%k$NKvHx$K=q$-9~$^$le(B
e$B$k$O$:$G$9!#e(B

e$B<B:]!"e(BIO.popen(“echo a”)
e$B$9$k$^$G$O$=$&$J$C$F$$$k$o$1$G$9$,!“e(B
IO.popen(“echo a”) e$B$7$?8e$Ne(B 1e$B2s$O$=$&$J$C$F$*$i$:!”%U%!%$%ke(B
e$B$N:G=i$K=q$-9~$^$l$F$$$^$9!#e(B

e$B$3$l$O$I$&$be(B IO.popen(“echo a”) e$B$,e(B f e$B$Ne(B O_APPEND
(0x400) e$B$re(B
e$B>C$7$F$7$^$&$?$a$J$N$G$9$,!"$3$l$OJQ$G$O$J$$$G$7$g$&$+!#e(B

e$B$J$+$@$G$9!#e(B

At Sun, 2 Jul 2006 23:13:48 +0900,
Tanaka A. wrote in [ruby-dev:28924]:

e$B0J2<$N$h$&$K!"e(BIO.popen(“echo a”) e$B$,4X78$J$$B>$Ne(B IO e$B$Ne(B
O_APPEND e$B$r>C$7$F$7$^$&$h$&$G$9!#e(B

3e$B0J>e$Ne(Bfde$B$Ke(BCLOEXECe$B%U%i%0$r%;%C%H$9$k$H$-$K!"85$N%U%i%0$r8+$F$$e(B
e$B$^$;$s$G$7$?!#$b$7$+$7$?$iC1$Ke(Bclosee$B$9$k$@$1$N$[$&$,$$$$$N$+$b$7e(B
e$B$l$^$;$s!#e(B

Index: io.c

RCS file: /cvs/ruby/src/ruby/io.c,v
retrieving revision 1.411
diff -p -U 2 -r1.411 io.c
— io.c 2 Jul 2006 02:25:11 -0000 1.411
+++ io.c 2 Jul 2006 16:40:22 -0000
@@ -2952,5 +2952,7 @@ popen_exec(void *pp)
for (fd = 3; fd < NOFILE; fd++) {
#ifdef FD_CLOEXEC

  • fcntl(fd, F_SETFL, FD_CLOEXEC);
  • int flag = fcntl(fd, F_GETFL);
  • if ((flag == -1) || (flag & FD_CLOEXEC)) continue;
  • fcntl(fd, F_SETFL, flag | FD_CLOEXEC);
    #else
    close(fd);

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:28930] Re: IO.popen(“echo a”) clear O_APPEND
of other fds.”
on Mon, 3 Jul 2006 01:44:02 +0900, [email protected] writes:

|At Sun, 2 Jul 2006 23:13:48 +0900,
|Tanaka A. wrote in [ruby-dev:28924]:
|> e$B0J2<$N$h$&$K!"e(BIO.popen(“echo a”) e$B$,4X78$J$$B>$Ne(B IO e$B$Ne(B
|> O_APPEND e$B$r>C$7$F$7$^$&$h$&$G$9!#e(B
|
|3e$B0J>e$Ne(Bfde$B$Ke(BCLOEXECe$B%U%i%0$r%;%C%H$9$k$H$-$K!"85$N%U%i%0$r8+$F$$e(B
|e$B$^$;$s$G$7$?!#$b$7$+$7$?$iC1$Ke(Bclosee$B$9$k$@$1$N$[$&$,$$$$$N$+$b$7e(B
|e$B$l$^$;$s!#e(B

e$B$9$0$Ke(Bexece$B$9$k$o$1$G$9$+$i$M$(!#e(Bclosee$B$7$^$7$g$&$+!#e(B

e$B$7$+$7!"$=$l$O$=$l$H$7$F!"$$$A$$$Ae(BGETFLe$B$7$F$+$i$G$J$$$H$^$He(B
e$B$b$Ke(BSETFLe$B$G$-$J$$;EMM$O%G%-$,0-$$$J!#e(B

In article [email protected],
[email protected] writes:

3e$B0J>e$Ne(Bfde$B$Ke(BCLOEXECe$B%U%i%0$r%;%C%H$9$k$H$-$K!"85$N%U%i%0$r8+$F$$e(B
e$B$^$;$s$G$7$?!#$b$7$+$7$?$iC1$Ke(Bclosee$B$9$k$@$1$N$[$&$,$$$$$N$+$b$7e(B
e$B$l$^$;$s!#e(B

e$B$($'$H!"e(BCLOEXEC e$B$Oe(B F_SETFD e$B$G$Oe(B? F_SETFL
e$B$G$O$J$/!#e(B

e$B$H$3$m$G!"e(BF_SETFD e$B$NBP>]$G!“e(BCLOEXEC
e$B0J30$K$J$K$+B8:_$9$k%7%9e(B
e$B%F%`$C$F$”$j$^$7$?$C$1e(B?

e$B$J$/$F$b$=$&$$$&$N$,B8:_$9$k%7%9%F%`$,$I$3$+$Ke(B
(e$B$b$7$/$O>-Mhe(B)
e$B$“$k$+$b$7$l$J$$$+$i85$N%U%i%0$r8+$k!”$H$$$&$N$O$^$C$?$/$b$Ce(B
e$B$F@5$7$$$N$G$9$,!#e(B

e$B$J$+$@$G$9!#e(B

At Mon, 3 Jul 2006 02:21:40 +0900,
Tanaka A. wrote in [ruby-dev:28932]:

e$B$($’$H!"e(BCLOEXEC e$B$Oe(B F_SETFD e$B$G$Oe(B? F_SETFL e$B$G$O$J$/!#e(B

e$B$&$O!#e(B

At Mon, 3 Jul 2006 01:58:42 +0900,
Yukihiro M. wrote in [ruby-dev:28931]:

e$B$9$0$Ke(Bexece$B$9$k$o$1$G$9$+$i$M$(!#e(Bclosee$B$7$^$7$g$&$+!#e(B

e$B$3$C$A$K$7$^$7$g$&!#e(B

e$B$H$3$m$G!"e(BF_SETFD e$B$NBP>]$G!“e(BCLOEXEC e$B0J30$K$J$K$+B8:_$9$k%7%9e(B
e$B%F%`$C$F$”$j$^$7$?$C$1e(B?

e$BJ9$$$?$3$H$O$J$$$G$9!#e(B

In article [email protected],
Yukihiro M. [email protected] writes:

e$B$7$+$7!“$=$l$O$=$l$H$7$F!”$$$A$$$Ae(BGETFLe$B$7$F$+$i$G$J$$$H$^$He(B
e$B$b$Ke(BSETFLe$B$G$-$J$$;EMM$O%G%-$,0-$$$J!#e(B

e$B$3$N=PMh$N0-$5$re(B Ruby e$B%l%Y%k$G$I$&$K$+$9$k$?$a$Ke(B
IO#file_flags e$B$re(B GETFL,
IO#file_flags= e$B$re(B SETFL e$B$K$7$F!“e(B
io.file_flags |= File::NONBLOCK
e$B$H$G$-$k$h$&$K$7$?$i$I$&$+!”$H9M$($?$3$H$O$"$j$^$9!#e(B

e$BF1MM$Ke(B
IO#descriptor_flags e$B$re(B GETFD,
IO#descriptor_flags= e$B$re(B SETFD e$B$K$7$F!“e(B
io.descriptor_flags |= Fcntl::FD_CLOEXEC
e$B$H=PMh$k$h$&$K$9$k!”$H$$$&$3$H$b9M$($i$l$^$9!#e(B

e$B$?$@!“e(BNONBLOCK e$B$K4X$7$F$O!“e(BGETFL/SETFL
e$B$,4JC1$K$J$k$@$1$G$Oe(B
e$B$[$H$s$ILdBj$,2r7h$7$J$$!”$H$$$&$3$H$G$B"F~$j$K$7$F!"e(B
IO#
_nonblock e$B$r9M$($?$o$1$G$9$,!”$=$C$A$Oe(B (e$B$D$$$Ke(B)
e$BJRIU$$$?e(B
e$B$N$G!“e(BIO#file_flags= e$B$r8!F$$9$k$N$b$”$j$+$b$7$l$^$;$s!#e(B

… e$B$H;W$C$F9M$($F$_$k$H!“e(BIO#file_flags e$B$,e(B Windows
e$B$GF0$+$Je(B
e$B$$$+$i%]!<%?%S%j%F%#$KFq$”$j!"$+$J!#e(B

e$B$J$+$@$G$9!#e(B

At Mon, 3 Jul 2006 02:34:14 +0900,
Tanaka A. wrote in [ruby-dev:28933]:

e$B$H=PMh$k$h$&$K$9$k!"$H$$$&$3$H$b9M$($i$l$^$9!#e(B
IO#close_on_exec e$B$N$h$&$K8DJL$K$7$?$[$&$,!“e(Bfile_flagse$B$He(B
descriptor_flagse$B$N$I$C$A$@$C$1!”$H$+G:$^$:$K$9$`$s$8$c$J$$$G$7$ge(B
e$B$&$+!#$=$l$H$bAa$9$.$kBUBF2=e(B?

… e$B$H;W$C$F9M$($F$_$k$H!“e(BIO#file_flags e$B$,e(B Windows e$B$GF0$+$Je(B
e$B$$$+$i%]!<%?%S%j%F%#$KFq$”$j!"$+$J!#e(B

e$B$J$1$j$c$J$$$GL$Dj5A$G$$$$$s$G$O!#e(B

  • io.c (rb_io_cloexec_get, rb_io_cloexec_set): new methods, get/set
    FD_CLOEXEC flag.

Index: io.c

RCS file: /cvs/ruby/src/ruby/io.c,v
retrieving revision 1.411
diff -p -u -2 -r1.411 io.c
— io.c 2 Jul 2006 02:25:11 -0000 1.411
+++ io.c 3 Jul 2006 01:17:08 -0000
@@ -2693,4 +2693,56 @@ rb_io_modenum_mode(int flags)
}

+#ifdef FD_CLOEXEC
+/*

    • call-seq:
    • ios.close_on_exec    => true/false
      
    • Returns true if ios will be closed on +exec+.
    • def fd(io)
    •  path = "/proc/self/fd/#{io.fileno.to_s}"
      
    •  system("readlink", path) or puts "#{path} is not opened"
      
    • end
    • f = open("/dev/null")
    • fd(f) # => /dev/null
    • f.close_on_exec = true
    • fd(f) # => /proc/self/fd/3 is not opened
  • */

+static VALUE
+rb_io_cloexec_get(VALUE io)
+{

  • OpenFile *fptr;
  • int flag;
  • GetOpenFile(io, fptr);
  • flag = fcntl(fptr->fd, F_GETFD);
  • if (flag == -1) rb_sys_fail(0);
  • return (flag & FD_CLOEXEC) ? Qtrue : Qfalse;
    +}

+static VALUE
+rb_io_cloexec_set(VALUE io, VALUE val)
+{

  • OpenFile *fptr;
  • int oflag, flag;
  • GetOpenFile(io, fptr);
  • flag = fcntl(fptr->fd, F_GETFD);
  • if (flag == -1) rb_sys_fail(0);
  • oflag = flag;
  • if (RTEST(val)) {
  • flag |= FD_CLOEXEC;
  • }
  • else {
  • flag &= ~FD_CLOEXEC;
  • }
  • if (oflag != flag && fcntl(fptr->fd, F_SETFD, flag) == -1)
  • rb_sys_fail(0);
  • return (oflag & FD_CLOEXEC) ? Qtrue : Qfalse;
    +}
    +#endif

static int
rb_sysopen(char *fname, int flags, unsigned int mode)
@@ -5696,4 +5748,8 @@ Init_IO(void)
rb_define_method(rb_cIO, “eof”, rb_io_eof, 0);
rb_define_method(rb_cIO, “eof?”, rb_io_eof, 0);
+#ifdef FD_CLOEXEC

  • rb_define_method(rb_cIO, “close_on_exec”, rb_io_cloexec_get, 0);

  • rb_define_method(rb_cIO, “close_on_exec=”, rb_io_cloexec_set, 1);
    +#endif

    rb_define_method(rb_cIO, “close”, rb_io_close_m, 0);

In article [email protected],
[email protected] writes:

IO#close_on_exec e$B$N$h$&$K8DJL$K$7$?$[$&$,!“e(Bfile_flagse$B$He(B
descriptor_flagse$B$N$I$C$A$@$C$1!”$H$+G:$^$:$K$9$`$s$8$c$J$$$G$7$ge(B
e$B$&$+!#$=$l$H$bAa$9$.$kBUBF2=e(B?

e$BJ}8~$O$$$$$H;W$$$^$9!#e(B|= e$B$G5/$3$k0J2<$NLdBj$b$J$$$G$9$7!#e(B

… e$B$H;W$C$F9M$($F$_$k$H!“e(BIO#file_flags e$B$,e(B Windows e$B$GF0$+$Je(B
e$B$$$+$i%]!<%?%S%j%F%#$KFq$”$j!"$+$J!#e(B

e$B$J$1$j$c$J$$$GL$Dj5A$G$$$$$s$G$O!#e(B

e$BL$Dj5A$de(B NotImplementedError e$B$K$J$C$F$k$H!"e(B|=
e$B$,;H$($J$$$N$,e(B
e$B$A$g$C$HLdBj$G$9!#e(B

% ruby -e ’
class C
def v
raise NotImplementedError
end
def v=(x)
end
end
C.new.v |= 1’
-e:4:in `C#v’: NotImplementedError (NotImplementedError)
from -e:9

e$B$J$N$G!“MQ0U$9$k$J$i8DJL$N$[$&$,$$$$$N$G$9$,!”$=$b$=$b%a%=%Ce(B
e$B%I$rMQ0U$9$k$[$IIQHK$K;H$&%U%i%0$,$“$k$N$+!”$H$$$&E@$K5?Ld$,e(B
e$B$"$j$^$9!#e(B

e$B8D?ME*$J463P$H$7$F$O!“e(BO_NONBLOCK e$B$,0lHV$h$/;H$o$l$k$H;W$&$se(B
e$B$G$9$,!”$3$l$O$`$7$me(B (e$B%=%1%C%H$KBP$7$Fe(B)
e$B%G%U%)%k%H$GIU$1$F$7e(B
e$B$^$&$N$,$$$$$H;W$&$N$G%a%=%C%I$O:GA1$NJ}K!$G$OL5$$$H;W$$$^$9e(B
e$B$7!“<!$KNI$/;H$o$l$k$b$N$Oe(B FD_CLOEXEC e$B$N$h$&$J5$$,$7$^$9$,!“e(B
e$B$=$s$J$K;H$&$+$H$$$&$H!”$”$^$j$=$s$J5$$O$7$^$;$s!#e(B