[Bug #3515] FreeBSD wrongly raises ECONNRESET on close(2)

Bug #3515: FreeBSD wrongly raises ECONNRESET on close(2)
http://redmine.ruby-lang.org/issues/show/3515

e$B5/I<<Te(B: Yui NARUSE
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Normal
e$B%+%F%4%je(B: core
ruby -v: ruby 1.9.3dev (2010-07-02 trunk 28520) [x86_64-freebsd8.1]

FreeBSD 8 e$B$G$O8=:_0J2<$N$h$&$J%F%9%H$K<:GT$7$F$$$^$9!#e(B

  1. Error:
    test_idle(IMAPTest):
    Errno::ECONNRESET: Connection reset by peer
    /home/naruse/ruby/test/net/imap/test_imap.rb:189:in `test_idle’

  2. Failure:
    test_03(TestDRbSSLCore) [/home/naruse/ruby/test/drb/drbtest.rb:138]:
    [DRb::DRbConnError] exception expected, not
    Class: Errno::ECONNRESET
    Message: <“Connection reset by peer”>
    —Backtrace—
    /home/naruse/ruby/test/drb/drbtest.rb:139:in block in test_03' /home/naruse/ruby/test/drb/drbtest.rb:138:in test_03’


  1. Failure:
    test_07_public_private_protected_missing(TestDRbSSLCore)
    [/home/naruse/ruby/test/drb/drbtest.rb:182]:
    Exception raised:
    <#<Errno::ECONNRESET: Connection reset by peer>>.

e$B$3$l$i$K6&DL$9$k$N$O!Ve(BErrno::ECONNRESET: Connection reset by
peere$B!W$H$$$&Nc30$,H/@8$7$F$$$kE@$G$9!#e(B
e$B$3$NNc30$Oe(B socket e$B$Ne(B close(2) e$B$r8F$s$@:]$Ke(B errno
e$B$Ke(B ECONNRESET e$B$,%;%C%H$5$l$?$H$-$KH/@8$7$^$9!#e(B
e$B$7$+$7!“$3$N5sF0$Oe(B POSIX e$B;EMM30$G$”$j!"e(BFreeBSD
e$BFH<+$N$b$N$G$9!#e(B

http://www.freebsd.org/cgi/man.cgi?query=close&apropos=0&sektion=0&manpath=FreeBSD+8.0-RELEASE&format=html
http://www.opengroup.org/onlinepubs/9699919799/functions/close.html
http://netbsd.gw.com/cgi-bin/man-cgi?close++NetBSD-current
http://www.openbsd.org/cgi-bin/man.cgi?query=close&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html
http://leaf.dragonflybsd.org/cgi/web-man?command=close&section=ANY
http://www.kernel.org/doc/man-pages/online/pages/man2/close.2.html

e$B$3$l$,7k2LE*$K!“B>$Ne(B OS
e$B$G$ONc30$,Ej$2$i$l$J$$>u67$GNc30$,H/@8$9$k$H$$$&8=>]$r@8$_=P$7$F$$$^$9!#e(B
e$B0J2<$O4XO”$9$k5DO@$G$9!#e(B
http://old.nabble.com/close()-failing-with-ECONNRESET-td28817716.html
http://old.nabble.com/Re:-kern-146845:--libc--close(2)-returns-error-54-(connection-reset-by-peer)-wrongly-td28649525.html

e$B$G!"e(BRuby e$B$K$*$1$kBP:v$G$9$,!"e(Bclose(2) e$B$Ge(B errno
e$B$Ke(B ECONNRESET e$B$,%;%C%H$5$l$?>l9g!"e(B
e$B$=$l$rL5;k$9$k$Y$-$@$H;W$$$^$9!#e(B
e$B$$$+$,$=$N%Q%C%A$J$N$G$9$,$$$+$,$G$7$g$&$+!#e(B

diff --git a/io.c b/io.c
index 05b2d45…a1b49d2 100644
— a/io.c
+++ b/io.c
@@ -3436,7 +3436,7 @@ fptr_finalize(rb_io_t fptr, int noraise)
/
fptr->fd may be closed even if close fails.
* POSIX doesn’t specify it.
* We assumes it is closed. */

  •    if (close(fptr->fd) < 0 && NIL_P(err))
    
  •    if (close(fptr->fd) < 0 && NIL_P(err) && errno != ECONNRESET)
           err = noraise ? Qtrue : INT2NUM(errno);
    
    }
    skip_fd_close:

e$B%A%1%C%He(B #3515 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$BC4Ev<Te(B Yui NARUSEe$B$K%;%C%He(B
e$BM%@hEYe(B Normale$B$+$ie(BLowe$B$KJQ99e(B
Target version 1.9.2e$B$K%;%C%He(B

e$B1sF#$G$9!#e(B

2010e$BG/e(B7e$B7ne(B2e$BF|e(B12:20 Yui NARUSE [email protected]:

e$B$3$l$i$K6&DL$9$k$N$O!Ve(BErrno::ECONNRESET: Connection reset by peere$B!W$H$$$&Nc30$,H/@8$7$F$$$kE@$G$9!#e(B
e$B$3$NNc30$Oe(B socket e$B$Ne(B close(2) e$B$r8F$s$@:]$Ke(B errno e$B$Ke(B ECONNRESET e$B$,%;%C%H$5$l$?$H$-$KH/@8$7$^$9!#e(B
e$B$7$+$7!“$3$N5sF0$Oe(B POSIX e$B;EMM30$G$”$j!"e(BFreeBSD e$BFH<+$N$b$N$G$9!#e(B

snip

e$B$G!"e(BRuby e$B$K$*$1$kBP:v$G$9$,!"e(Bclose(2) e$B$Ge(B errno e$B$Ke(B ECONNRESET e$B$,%;%C%H$5$l$?>l9g!"e(B
e$B$=$l$rL5;k$9$k$Y$-$@$H;W$$$^$9!#e(B

FreeBSD e$B$,>!<j$KFH<+;EMM$KAv$C$F$$$k$N$r!“e(BRuby
e$BB&$G5[<}$9$k!V$Y$-!W$H$Oe(B
e$B;W$$$^$;$s!#$^$?!”$;$C$+$/e(B errno
e$B@_Dj$7$F$$$k$N$r!“>!<j$K0.$j$D$V$7$F$be(B
e$B$h$$$b$N$J$s$G$7$g$&$+!#$H$$$&5?Ld$,$”$k$N$G!“e(B1.9.2
e$B$KF~$l$k$N$O$”$^$je(B
e$B>h$j5$$G$J$$$G$9!#e(B

e$B$G$9$,!“:G=E$K$Oe(B FreeBSD
e$B$N%W%i%C%H%U%)!<%`%a%s%F%J$NH=CG$KG$$;$^$9!#e(B
e$B$3$N7o$Ge(B 1.9.2
e$B$N%j%j!<%9$rBT$D$Y$-$G$O$”$j$^$;$s$,!"%a%s%F%J$NH=CG$,e(B
e$B%j%j!<%9$K4V$K9g$($P%3%_%C%H$7$F$b$$$$$+$J$H;W$$$^$9!#$H$$$&$3$H$G!"e(B
e$BM%@hEY$re(B Low e$B$K$7$^$9!#e(B

redmine e$B$Ne(B wiki e$B$Ke(B FreeBSD
e$B$N%W%i%C%H%U%)!<%`%a%s%F%J$,:$C$F$$$J$$$Ne(B
e$B$G$9$,!"@.@%$5$s$G@5$7$$$G$7$g$&$+!#e(B
e$B$b$70c$C$?$i!"e(BFreeBSD e$B$Oe(B perhaps e$B$K9_3J$H$J$j$^$9!#e(B


Yusuke E. [email protected]

http://redmine.ruby-lang.org/issues/show/3515

e$B%A%1%C%He(B #3515 e$B$,99?7$5$l$^$7$?!#e(B (by Akinori MUSHA)

e$B$3$l$O0U?^$5$l$F%I%-%e%a%s%H$b$5$l$F$$$kJQ99$J$N$G!"5sF0$H$7$F$be(BPOSIXe$BE*$K$be(Bwronge$B$G$O$J$$$G$9!#e(B
e$B!Je(BSUSe$B$G$O!"e(BERRORSe$B%;%/%7%g%s$G5,Dj$5$l$F$$$k>r7o$N$$$:$l$K$b9gCW$7$J$$%1!<%9$K$D$$$FFH<+$N%(%i!<$re(B
e$BH/@8$5$;$k$3$H$O5v$5$l$F$$$k$O$:!Ke(B

e$B4vEY$+e(BMLe$B$de(BIRCe$B$G$bPY>e$K$OEP$C$F$$$^$9$,!“8=<B$N%3!<%I$H$7$F!”$1$C$3$&%7%S%"$J%M%C%H%o!<%/%W%m%0%i%`$G$be(B
close(2)e$B$NJV$jCM$r%A%'%C%/$7$J$$$b$N$,B?$/!“e(Bportse$B$H$+e(Bcontribe$B$r8+$F$b!Je(BFreeBSDe$BMQ$K!Ke(BECONNRESETe$B$NBP1~$re(B
e$BDI2C$7$F$$$k$h$&$JNc$O$[$H$s$I$”$j$^$;$s!#e(B

e$B$=$NCf$G!"e(BOpenJDKe$B$G$Oe(Bgetsockname(2)e$B$,e(BFreeBSDe$B$Ge(BECONNRESETe$B$rJV$9$H$$$&$[$\F1$8LdBj$KBP$7$F!“F1%(%i!<$re(B
e$B0.$j$D$V$9=hM}$rFH<+%Q%C%A$GDI2C$7$F$$$^$9!#$3$l$KJo$&$H$$$&$N$O3N$+$K$”$j$+$b$7$l$^$;$s!#e(B

e$BG:$^$7$$$N$O!“e(BRubye$B$,$[$\0lN’$Ke(Berrnoe$B$,H/@8$7$?$H$-$Oe(Braisee$B$9$k$H$$$&47=,$,$”$k0lJ}!“>e5-$N$h$&$Ke(Bclose(2)e$B$Ne(B
e$B<:GT$,$”$^$j8!::$5$l$J$$$H$$$&479T$r8+$?>e$G!“$=$l$G$b4:$($F%(%i!<$r8!=P$9$k%W%m%0%i%`8~$1$Ke(BFYIe$BE*$Ke(B
ECONNRESETe$B$r65$($F$”$2$k$H$$$&e(BFreeBSDe$B$N$3$N5sF0$r$I$&07$&$Y$-$+$H$$$&$H$3$m$G$9$M!#e(B

DRbe$B$Oe(BSystemCallErrore$B$K$D$$$F$O<+J,$G07$o$:e(Bpass
throughe$B$9$kJ}?K$N$h$&$@$7!"$=$&$$$&%i%$%V%i%j$O$[$+$K$be(B
e$BB?$=$&$J$N$G8_49@-$r9MN8$7$F0.$j$D$V$9$N$O;EJ}$J$$$H8@$($k$G$7$g$&$+!#e(B
e$B;d$O>C6KE*$J$,$i;?@.$G$9!#!J3:Ev2U=j$K$O%3%a%s%H$rF~$l$F$[$7$$$G$9!Ke(B

http://redmine.ruby-lang.org/issues/show/3515

e$B%A%1%C%He(B #3515 e$B$,99?7$5$l$^$7$?!#e(B (by Yui NARUSE)

FreeBSD e$B$N%a%s%F%J$Oe(B knu e$B$5$s$@$H;W$C$F$$$^$7$?!#e(B

e$B$G!"e(BFreeBSDe$B$N$3$N5sF0$rCN$i$J$$?M$K$OA[A|$b$D$+$J$$=j$GCN$i$J$$Nc30$,>e$,$k$?$a!"e(B
Rubye$BB&$H$7$F$O5[<}$;$6$k$r$($J$$$H;W$$$^$9!#e(B
e$BNc30$N$h$&$J=hM}$rCfCG$5$;$F$7$^$&J}K!0J30$GDLCN$5$l$k$J$i$^$!$h$+$C$?$N$G$7$g$&$1$I!#e(B

e$B0J2<$N$h$&$J46$8$Ge(Btrunke$B$K$O%3%_%C%H$7$h$&$H;W$$$^$9!#e(B
1.9.2e$B$O$I$&$7$^$7$g$&$+!#e(B

diff --git a/ChangeLog b/ChangeLog
index 8698b39…8853a0b 100644
— a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon Jul 5 18:33:17 2010 NARUSE, Yui [email protected]
+

  •   * io.c (fptr_finalize): ignore ECONNRESET from close(2).
    
  •     FreeBSD wrongly sets ECONNRESET on close(2) and it causes
    
  •     false-negative exceptions. [ruby-dev:41778]
    

Mon Jul 5 12:32:01 2010 Aaron P. [email protected]

    * ext/psych/lib/psych/scalar_scanner.rb (parse_string): support

diff --git a/io.c b/io.c
index 5129a14…4c817b2 100644
— a/io.c
+++ b/io.c
@@ -3445,7 +3445,12 @@ fptr_finalize(rb_io_t fptr, int noraise)
/
fptr->fd may be closed even if close fails.
* POSIX doesn’t specify it.
* We assumes it is closed. */

  •    if (close(fptr->fd) < 0 && NIL_P(err))
    
  •    if (close(fptr->fd) < 0 && NIL_P(err)
    

+#ifdef FreeBSD

  •            /* Ignore ECONNRESET of FreeBSD close(2) */
    
  •            && errno != ECONNRESET
    

+#endif

  •       )
           err = noraise ? Qtrue : INT2NUM(errno);
    
    }
    skip_fd_close:

http://redmine.ruby-lang.org/issues/show/3515

2010e$BG/e(B7e$B7ne(B2e$BF|e(B12:20 Yui NARUSE [email protected]:

e$B$3$NNc30$Oe(B socket e$B$Ne(B close(2) e$B$r8F$s$@:]$Ke(B errno e$B$Ke(B ECONNRESET e$B$,%;%C%H$5$l$?$H$-$KH/@8$7$^$9!#e(B
e$B$7$+$7!“$3$N5sF0$Oe(B POSIX e$B;EMM30$G$”$j!"e(BFreeBSD e$BFH<+$N$b$N$G$9!#e(B

e$B$A$g$C$H$7$?9%4q?4$J$s$G$9$,!"e(Bclose(fd) e$B$,e(B ECONNRESET
e$B$K$J$C$?8e!“e(B
e$B$=$Ne(B fd e$B$Oe(B close
e$B$5$l$F$$$k$s$G$7$g$&$+!”$=$l$H$b$5$l$F$$$J$$$s$G$7$g$&$+!#e(B

2010e$BG/e(B7e$B7ne(B2e$BF|e(B12:20 Yui NARUSE [email protected]:

e$B$3$NNc30$Oe(B socket e$B$Ne(B close(2) e$B$r8F$s$@:]$Ke(B errno e$B$Ke(B ECONNRESET e$B$,%;%C%H$5$l$?$H$-$KH/@8$7$^$9!#e(B
e$B$7$+$7!“$3$N5sF0$Oe(B POSIX e$B;EMM30$G$”$j!"e(BFreeBSD e$BFH<+$N$b$N$G$9!#e(B

e$B$A$g$C$H$7$?9%4q?4$J$s$G$9$,!"e(Bclose(fd) e$B$,e(B ECONNRESET e$B$K$J$C$?8e!“e(B
e$B$=$Ne(B fd e$B$Oe(B close e$B$5$l$F$$$k$s$G$7$g$&$+!”$=$l$H$b$5$l$F$$$J$$$s$G$7$g$&$+!#e(B

closee$B$5$l$F$J$+$C$?$iK=F0$,5/$-$F$b$$$$%l%Y%k$N%_%9%G%6%$%s$@$H;W$$$^$9$,!&!&!&e(B

In message
[email protected]
on Tue, 6 Jul 2010 15:44:50 +0900,
Tanaka A. [email protected] wrote:

2010e$BG/e(B7e$B7ne(B2e$BF|e(B12:20 Yui NARUSE [email protected]:

e$B$3$NNc30$Oe(B socket e$B$Ne(B close(2) e$B$r8F$s$@:]$Ke(B errno e$B$Ke(B ECONNRESET e$B$,%;%C%H$5$l$?$H$-$KH/@8$7$^$9!#e(B^M
e$B2?$,!"$3$3$K@)8fJ8;ze(B(Ctl-M)e$B$rF~$l$F$k$N$@$m$&e(B?

e$B$7$+$7!“$3$N5sF0$Oe(B POSIX e$B;EMM30$G$”$j!"e(BFreeBSD e$BFH<+$N$b$N$G$9!#e(B

e$B$A$g$C$H$7$?9%4q?4$J$s$G$9$,!"e(Bclose(fd) e$B$,e(B ECONNRESET e$B$K$J$C$?8e!“e(B
e$B$=$Ne(B fd e$B$Oe(B close e$B$5$l$F$$$k$s$G$7$g$&$+!”$=$l$H$b$5$l$F$$$J$$$s$G$7$g$&$+!#e(B
e$B$5$i$K9%4q?4$J$N$G$9$,!"e(Bclose(fd)e$B$,e(BECONNRESETe$B$K$J$k>u67$r3NG’$G$-$ke(B
e$B4JC1$J%W%m%0%i%`$O$J$$$G$7$g$&$+e(B?

e$B@.@%$G$9!#e(B

2010e$BG/e(B7e$B7ne(B6e$BF|e(B15:50 Takahiro K.
[email protected]:

e$B$5$i$K9%4q?4$J$N$G$9$,!"e(Bclose(fd)e$B$,e(BECONNRESETe$B$K$J$k>u67$r3NG’$G$-$ke(B
e$B4JC1$J%W%m%0%i%`$O$J$$$G$7$g$&$+e(B?

e$B$o$?$7$Oe(B make TESTS=‘-v drb/test_drbssl.rb -n test_03’ test-all
e$B$G3NG’$7$F$$$^$9!#e(B
Ruby e$BB&$K<j$r$$$l$D$D2?EY$+Av$i$;$l$P3NG’$O$G$-$k$+$H;W$$$^$9!#e(B

e$B@.@%$G$9!#e(B

2010e$BG/e(B7e$B7ne(B6e$BF|e(B15:44 Tanaka A. [email protected]:

2010e$BG/e(B7e$B7ne(B2e$BF|e(B12:20 Yui NARUSE [email protected]:

e$B$3$NNc30$Oe(B socket e$B$Ne(B close(2) e$B$r8F$s$@:]$Ke(B errno e$B$Ke(B ECONNRESET e$B$,%;%C%H$5$l$?$H$-$KH/@8$7$^$9!#e(B
e$B$7$+$7!“$3$N5sF0$Oe(B POSIX e$B;EMM30$G$”$j!"e(BFreeBSD e$BFH<+$N$b$N$G$9!#e(B

e$B$A$g$C$H$7$?9%4q?4$J$s$G$9$,!"e(Bclose(fd) e$B$,e(B ECONNRESET e$B$K$J$C$?8e!“e(B
e$B$=$Ne(B fd e$B$Oe(B close e$B$5$l$F$$$k$s$G$7$g$&$+!”$=$l$H$b$5$l$F$$$J$$$s$G$7$g$&$+!#e(B

http://svn.freebsd.org/viewvc/base/head/lib/libstand/close.c?revision=165906&view=markup
e$B$r8+$k$H!"8F$s$@7k2L$K$+$+$o$i$:e(B f->f_flags = 0;
e$B$7$F$$$^$9$M!#e(B

At Tue, 6 Jul 2010 15:44:50 +0900,
Tanaka A. wrote:

2010å¹´7月2æ—¥12:20 Yui NARUSE [email protected]:

この例外は socket の close(2) を呼んだ際に errno に ECONNRESET がセットされたときに発生します。
しかし、この挙動は POSIX 仕様外であり、FreeBSD 独自のものです。

ちょっとした好奇心なんですが、close(fd) が ECONNRESET になった後、
その fd は close されているんでしょうか、それともされていないんでしょうか。

 close されます。fd のチェック(EBADF なら終わり)、fd の解放、
実際の(ソケットならソケットの)クローズ処理、という流れなので、
ã©ã®ã‚¨ãƒ©ãƒ¼ã®å ´åˆã‚‚è§£æ”¾æ¼ã‚Œã¯ãªã„ã¨æ€ã„ã¾ã™ã€‚

e$B%A%1%C%He(B #3515 e$B$,99?7$5$l$^$7$?!#e(B (by Yui NARUSE)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

This issue was solved with changeset r28561.
Yui, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


http://redmine.ruby-lang.org/issues/show/3515

In message
[email protected]
on Tue, 6 Jul 2010 18:02:26 +0900,
“NARUSE, Yui” [email protected] wrote:

2010e$BG/e(B7e$B7ne(B6e$BF|e(B15:50 Takahiro K. [email protected]:

e$B$5$i$K9%4q?4$J$N$G$9$,!"e(Bclose(fd)e$B$,e(BECONNRESETe$B$K$J$k>u67$r3NG’$G$-$ke(B
e$B4JC1$J%W%m%0%i%`$O$J$$$G$7$g$&$+e(B?

e$B$o$?$7$Oe(B make TESTS=‘-v drb/test_drbssl.rb -n test_03’ test-all e$B$G3NG’$7$F$$$^$9!#e(B
Ruby e$BB&$K<j$r$$$l$D$D2?EY$+Av$i$;$l$P3NG’$O$G$-$k$+$H;W$$$^$9!#e(B
e$B$&!<$s!"C1BN$Ne(BCe$B$N%W%m%0%i%`$G;W$C$F$^$7$?!#e(B;-(