# Write to broken pipe on Linux

**URL:** <https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404>\
**Category:** Development\
**Created:** [May 1, 2008, 7:02pm UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404 "2008-05-01T19:02:57Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 1, 2008, 7:02pm UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404/1 "2008-05-01T19:02:57Z")

</div>

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

[http://rryu.sakura.ne.jp/nisenise-fuhito/2008/04/22/950.html](http://rryu.sakura.ne.jp/nisenise-fuhito/2008/04/22/950.html) e$B$He(B  
e$B$+e(B(e$B8+Mn$H$7$F$^$7$?$,e(B)[ruby-list:43356]e$B$K$“$k!”@\B3$,@Z$l$?%=%1%Ce(B  
e$B%H$K=q$-9~$b$&$H$9$k$H!"FsEYL\0J9\_e(Bselecte$B$NBT$A\>uBV$+$iH4$1$J$/$Je(B  
e$B$kLdBj$N%Q%C%A$G$9!#e(Brb\_io\_wait\_{read,writ}able()e$B$N8\_49@-$,$J$/$J$Ce(B  
e$B$F$7$^$&$N$,5$$K$J$k$N$G!"L\>A0$rJQ$($?$[$&$,$$$$$+$b$7$l$^$;$s$,!"e(B  
e$B$I$&$$$&$N$,$$$$$G$9$+$M$'!#e(B

# Index: include/ruby/io.h

— include/ruby/io.h (revision 16258)  
+++ include/ruby/io.h (working copy)  
@@ -61,4 +61,5 @@ typedef struct rb\_io\_t {  
#define FMODE\_TTY 16  
#define FMODE\_DUPLEX 32  
+#define FMODE\_BROKENPIPE 256  
#define FMODE\_WSPLIT 0x200  
#define FMODE\_WSPLIT\_INITIALIZED 0x400  
@@ -107,6 +108,6 @@ void rb\_io\_synchronized(rb\_io\_t\*);  
void rb\_io\_check\_initialized(rb\_io\_t\*);  
void rb\_io\_check\_closed(rb\_io\_t\*);  
-int rb\_io\_wait\_readable(int);  
-int rb\_io\_wait\_writable(int);  
+int rb\_io\_wait\_readable(rb\_io\_t\*);  
+int rb\_io\_wait\_writable(rb\_io\_t\*);  
void rb\_io\_set\_nonblock(rb\_io\_t \*fptr);

# Index: io.c

— io.c (revision 16258)  
+++ io.c (working copy)  
@@ -419,4 +419,10 @@ rb\_io\_check\_writable(rb\_io\_t \*fptr)  
rb\_raise(rb\_eIOError, “not opened for writing”);  
}  
+#ifdef **linux**

- if (fptr-\>mode & FMODE\_BROKENPIPE) {
- errno = EPIPE;
- rb\_sys\_fail(0);
- }  
+#endif  
if (fptr-\>rbuf\_len) {  
io\_unread(fptr);  
@@ -590,5 +596,5 @@ io\_fflush(rb\_io\_t \*fptr)  
errno = EAGAIN;  
}

- if (rb\_io\_wait\_writable(fptr-\>fd)) {

- if (rb\_io\_wait\_writable(fptr)) {  
rb\_io\_check\_closed(fptr);  
goto retry;  
@@ -608,7 +614,8 @@ wait\_readable(VALUE p)

int  
-rb\_io\_wait\_readable(int f)  
+rb\_io\_wait\_readable(rb\_io\_t \*fptr)  
{  
rb\_fdset\_t rfds;

- int f = fptr-\>fd;

int  
-rb\_io\_wait\_writable(int f)  
+rb\_io\_wait\_writable(rb\_io\_t \*fptr)  
{  
rb\_fdset\_t wfds;

- int f = fptr-\>fd;

- 

```
 case EPIPE:

```

- fptr-\>mode |= FMODE\_BROKENPIPE;

- 

```
 default:

```

return Qfalse;  
@@ -752,5 +763,5 @@ io\_fwrite(VALUE str, rb\_io\_t \*fptr)  
errno = EAGAIN;  
}

- 

```
   if (rb_io_wait_writable(fptr->fd)) {

```

- 

```
   if (rb_io_wait_writable(fptr)) {
       rb_io_check_closed(fptr);
 if (offset < RSTRING_LEN(str))

```

@@ -1038,5 +1049,5 @@ io\_fillbuf(rb\_io\_t \*fptr)  
}  
if (r \< 0) {

- 

```
       if (rb_io_wait_readable(fptr->fd))

```

- 

```
       if (rb_io_wait_readable(fptr))
           goto retry;
       rb_sys_fail(fptr->path);

```

@@ -1480,5 +1491,5 @@ io\_getpartial(int argc, VALUE \*argv, VAL  
}  
if (n \< 0) {

- 

```
       if (!nonblock && rb_io_wait_readable(fptr->fd))

```

- 

```
       if (!nonblock && rb_io_wait_readable(fptr))
           goto again;
       rb_sys_fail(fptr->path);

```

# Index: ext/socket/socket.c

— ext/socket/socket.c (revision 16258)  
+++ ext/socket/socket.c (working copy)  
@@ -525,5 +525,5 @@ bsock\_send(int argc, VALUE \*argv, VALUE  
}  
if (n \< 0) {

- if (rb\_io\_wait\_writable(fd)) {

- if (rb\_io\_wait\_writable(fptr)) {  
goto retry;  
}  
@@ -1809,5 +1809,5 @@ udp\_send(int argc, VALUE \*argv, VALUE so  
return INT2FIX(n);  
}

- if (rb\_io\_wait\_writable(fptr-\>fd)) {

- if (rb\_io\_wait\_writable(fptr)) {  
goto retry;  
}  
Index: ext/openssl/ossl\_ssl.c  
===================================================================  
— ext/openssl/ossl\_ssl.c (revision 16258)  
+++ ext/openssl/ossl\_ssl.c (working copy)  
@@ -951,8 +951,8 @@ ossl\_start\_ssl(VALUE self, int (\*func)()  
switch((ret2 = ssl\_get\_error(ssl, ret))){  
case SSL\_ERROR\_WANT\_WRITE:

- 

```
       rb_io_wait_writable(FPTR_TO_FD(fptr));

```

- 

```
       rb_io_wait_writable(fptr);
       continue;

```

case SSL\_ERROR\_WANT\_READ:

- 

```
       rb_io_wait_readable(FPTR_TO_FD(fptr));

```

- 

```
       rb_io_wait_readable(fptr);
       continue;

```

case SSL\_ERROR\_SYSCALL:  
@@ -1033,8 +1033,8 @@ ossl\_ssl\_read(int argc, VALUE \*argv, VAL  
rb\_eof\_error();  
case SSL\_ERROR\_WANT\_WRITE:

- 

```
           rb_io_wait_writable(FPTR_TO_FD(fptr));

```

- 

```
           rb_io_wait_writable(fptr);
           continue;
 case SSL_ERROR_WANT_READ:

```

- 

```
           rb_io_wait_readable(FPTR_TO_FD(fptr));

```

- 

```
           rb_io_wait_readable(fptr);

```

continue;  
case SSL\_ERROR\_SYSCALL:  
@@ -1081,8 +1081,8 @@ ossl\_ssl\_write(VALUE self, VALUE str)  
goto end;  
case SSL\_ERROR\_WANT\_WRITE:

- 

```
           rb_io_wait_writable(FPTR_TO_FD(fptr));

```

- 

```
           rb_io_wait_writable(fptr);
           continue;
 case SSL_ERROR_WANT_READ:

```

- 

```
           rb_io_wait_readable(FPTR_TO_FD(fptr));

```

- 

```
           rb_io_wait_readable(fptr);
           continue;
 case SSL_ERROR_SYSCALL:

```

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 1, 2008, 9:36pm UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404/2 "2008-05-01T21:36:57Z")

</div>

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

In message “Re: [ruby-dev:34567] write to broken pipe on Linux”  
on Fri, 2 May 2008 02:01:59 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|[http://rryu.sakura.ne.jp/nisenise-fuhito/2008/04/22/950.html](http://rryu.sakura.ne.jp/nisenise-fuhito/2008/04/22/950.html) e$B$He(B  
|e$B$+e(B(e$B8+Mn$H$7$F$^$7$?$,e(B)[ruby-list:43356]e$B$K$“$k!”@\B3$,@Z$l$?%=%1%Ce(B  
|e$B%H$K=q$-9~$b$&$H$9$k$H!"FsEYL\0J9\_e(Bselecte$B$NBT$A\>uBV$+$iH4$1$J$/$Je(B  
|e$B$kLdBj$N%Q%C%A$G$9!#e(Brb\_io\_wait\_{read,writ}able()e$B$N8\_49@-$,$J$/$J$Ce(B  
|e$B$F$7$^$&$N$,5$$K$J$k$N$G!"L\>A0$rJQ$($?$[$&$,$$$$$+$b$7$l$^$;$s$,!"e(B  
|e$B$I$&$$$&$N$,$$$$$G$9$+$M$'!#e(B

e$BL\>A0$b5$$K$J$k$N$G$9$,!"$3$N8=\>]$,e(Blinuxe$BFCM-$N$b$N$+$I$&$+$b5$e(B  
e$B$K$J$j$^$9!#$$$C$=!"e(BEPIPEe$B$r\<u$1$?$ie(Bclosee$B$H$+e(Bshutdowne$B$H$+8F$se(B  
e$B$8$c$($P$$$$$s$8$c$J$$$G$9$+$M!#$=$l$@$He(Blinuxe$B8GM-$+$I$&$+9M$(e(B  
e$B$J$/$F$b$$$$$7!"0z?tJQ$($J$/$F$$$$$7!#e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 2, 2008, 9:28am UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404/3 "2008-05-02T09:28:49Z")

</div>

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

In message “Re: [ruby-dev:34572] Re: write to broken pipe on Linux”  
on Fri, 2 May 2008 14:57:23 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|\> e$BL\>A0$b5$$K$J$k$N$G$9$,!"$3$N8=\>]$,e(Blinuxe$BFCM-$N$b$N$+$I$&$+$b5$e(B  
|\> e$B$K$J$j$^$9!#$$$C$=!"e(BEPIPEe$B$r\<u$1$?$ie(Bclosee$B$H$+e(Bshutdowne$B$H$+8F$se(B  
|\> e$B$8$c$($P$$$$$s$8$c$J$$$G$9$+$M!#$=$l$@$He(Blinuxe$B8GM-$+$I$&$+9M$(e(B  
|\> e$B$J$/$F$b$$$$$7!“0z?tJQ$($J$/$F$$$$$7!#e(B  
|  
|e$B\>e5-%j%s%/@h$N\>pJs$K$h$k$H!”\>/$J$/$H$be(BWindows Vistae$B$He(BMac OS X  
|10.5e$B$G$OH/@8$7$J$$$h$&$G$9!#e(B

e$B$^$"!"e(BWindowse$B$O$H$b$+$/!"e(BOS  
Xe$B0J30$Ne(BUNIXe$B7Oe(BOSe$B$GH/@8$7$J$$$+$Ie(B  
e$B$&$+$O$+$J$j5$$K$J$j$^$9!#e(BOS  
Xe$B$,Bg\>fIW$J$ie(BBSDe$B7O$OBg\>fIW$G$"e(B  
e$B$k2DG=@-$O9b$$$G$7$g$&$,!"e(BAIXe$B$H$+e(BHP-UXe$B$H$+M=A[$7$,$?$$$N$b$"e(B  
e$B$k$7!#e(B

EPIPEe$B$de(BENOTCONNe$B$,H/@8$7$?e(Bfde$B$re(Bselecte$B$KEO$9$H$U$?$?$S$=$l$i$,H/e(B  
e$B@8$9$k$Y$-$G$“$k$He(B(e$B$?$H$($Pe(B)POSIXe$BE\*$KL@\<($5$l$F$$$k$N$G$”$l$P!“e(B  
linuxe$B8GM-$N%P%0$HG’Dj$7$F!“EvLL!”\>lEv$?$jE\*$JBP1~$r$9$k$H$+$be(B  
e$B$”$j$($k$H$O;W$&$N$G$9$,!#e(B

|shutdowne$B$G$O!"e(BEPIPEe$B$NBe$o$j$Ke(BENOTCONNe$B$,H/@8$9$k$h$&$K$J$k$@$1$Ge(B  
|e$B$=$N\<!$N=q$-9~$\_$G$d$O$j%V%m%C%/$7$F$7$^$&$h$&$G$9!#e(Bclosee$B$K$9$ke(B  
|e$B$He(BEBADFe$B$K$O$J$k$N$G$9$,!"e(Beof?e$B$de(Bclosee$B$G$bF1$8$/e(BEBADFe$B$,H/@8$7$F$7e(B  
|e$B$^$&$h$&$K$J$j$^$9!#B\>$N%9%l%C%I$NM-L5$K$h$C$FF0:n$,JQ$o$C$F$7$^e(B  
|e$B$&$N$b$I$&$+$H$$$&5$$b$7$^$9$,!#e(B

e$B$O$8$a$KN)$AJV$C$F9M$($k$H!“FI$\_=P$=$&$H$7$?;~$Ke(BEPIPEe$B$,JV$Ce(B  
e$B$F$-$F$7$^$C$?e(BIOe$B$KBP$7$F$I$N$h$&$KBP=h$9$Y$-$J$s$G$7$g$&$M!#e(B  
BROKENPIPEe$B%U%i%0$rN)$F$k!”$H$$$&$N$b$“$s$^$j@5$7$$BP=h$N$h$&e(B  
e$B$K$O;W$($J$$$s$G$9$,!#$d$O$j6/@)E\*$Ke(Bclosee$B$7$FNc30$+$J$”!#e(B

|e$B$H$$$&$+!"e(B1.9e$B$G$O$9$G$Ke(Bblocking regione$B$r;H$($Pe(Bselecte$B$OI,MW$J$$$Oe(B  
|e$B$:$G$9!#e(B

1.9e$B$G$O$=$NJ}8~$GBP1~$7$^$7$g$&$+!#e(B

```
                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

```

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 3, 2008, 2:25am UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404/4 "2008-05-03T02:25:42Z")

</div>

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

At Fri, 2 May 2008 16:27:45 +0900,  
Yukihiro M. wrote in [ruby-dev:34574]:

> EPIPEe$B$de(BENOTCONNe$B$,H/@8$7$?e(Bfde$B$re(Bselecte$B$KEO$9$H$U$?$?$S$=$l$i$,H/e(B  
> e$B@8$9$k$Y$-$G$"$k$He(B(e$B$?$H$($Pe(B)POSIXe$BE\*$KL@\<($5$l$F$$$k$N$G$"$l$P!“e(B  
> linuxe$B8GM-$N%P%0$HG’Dj$7$F!“EvLL!”\>lEv$?$jE\*$JBP1~$r$9$k$H$+$be(B  
> e$B$”$j$($k$H$O;W$&$N$G$9$,!#e(B

e$B$=$3$^$G$O5,Dj$5$l$F$$$J$$$h$&$J5$$,$7$^$9!#e(B

> |shutdowne$B$G$O!"e(BEPIPEe$B$NBe$o$j$Ke(BENOTCONNe$B$,H/@8$9$k$h$&$K$J$k$@$1$Ge(B  
> |e$B$=$N\<!$N=q$-9~$\_$G$d$O$j%V%m%C%/$7$F$7$^$&$h$&$G$9!#e(Bclosee$B$K$9$ke(B  
> |e$B$He(BEBADFe$B$K$O$J$k$N$G$9$,!"e(Beof?e$B$de(Bclosee$B$G$bF1$8$/e(BEBADFe$B$,H/@8$7$F$7e(B  
> |e$B$^$&$h$&$K$J$j$^$9!#B\>$N%9%l%C%I$NM-L5$K$h$C$FF0:n$,JQ$o$C$F$7$^e(B  
> |e$B$&$N$b$I$&$+$H$$$&5$$b$7$^$9$,!#e(B
> 
> e$B$O$8$a$KN)$AJV$C$F9M$($k$H!“FI$\_=P$=$&$H$7$?;~$Ke(BEPIPEe$B$,JV$Ce(B  
> e$B$F$-$F$7$^$C$?e(BIOe$B$KBP$7$F$I$N$h$&$KBP=h$9$Y$-$J$s$G$7$g$&$M!#e(B  
> BROKENPIPEe$B%U%i%0$rN)$F$k!”$H$$$&$N$b$"$s$^$j@5$7$$BP=h$N$h$&e(B  
> e$B$K$O;W$($J$$$s$G$9$,!#$d$O$j6/@)E\*$Ke(Bclosee$B$7$FNc30$+$J$"!#e(B

e$B$G$9$+$M$’!#e(B

> |e$B$H$$$&$+!"e(B1.9e$B$G$O$9$G$Ke(Bblocking regione$B$r;H$($Pe(Bselecte$B$OI,MW$J$$$Oe(B  
> |e$B$:$G$9!#e(B
> 
> 1.9e$B$G$O$=$NJ}8~$GBP1~$7$^$7$g$&$+!#e(B

1.8e$B$,LdBj$G$9$M!#$H$j$"$($:;n$7$F$\_$?$s$G$9$,!"e(Bdeadlocke$B$K$J$C$Fe(B  
e$B$7$^$$$^$7$?!#e(B

# e$BK!;v$GIT:\_$N$?$a!"e(B5/5e$B$^$Ge(BIP unreachablee$B!#e(B

# Index: eval.c

— eval.c (revision 16276)  
+++ eval.c (working copy)  
@@ -10930,4 +10930,11 @@ rb\_thread\_schedule()  
#endif  
FOREACH\_THREAD\_FROM(curr, th) {

- if ((th-\>wait\_for&WAIT\_FD) && FD\_ISSET(th-\>fd, &readfds)) {
- 

```
   FD_CLR(th->fd, &readfds);

```

- 

```
    th->status = THREAD_RUNNABLE;

```

- 

```
   th->select_value = n;

```

- 

```
   n = max;

```

- 

```
   found = 1;

```

- }  
if (th-\>wait\_for & WAIT\_SELECT) {  
int v = 0;  
@@ -10937,6 +10944,8 @@ rb\_thread\_schedule()  
v |= find\_bad\_fds(&exceptfds, &th-\>exceptfds, th-\>fd);  
if (v) {
- 

```
 th->status = THREAD_RUNNABLE;
 th->select_value = n;
 n = max;

```

- 

```
 found = 1;
   }

```

}  
@@ -11019,5 +11028,5 @@ rb\_thread\_schedule()  
th-\>thread, thread\_status\_name(th-\>status));  
if (th-\>wait\_for & WAIT\_FD) warn\_printf(“F(%d)”, th-\>fd);

- 

```
 if (th->wait_for & WAIT_SELECT) warn_printf("S");

```

- 

```
 if (th->wait_for & WAIT_SELECT) warn_printf("S(%d)", th->fd);
 if (th->wait_for & WAIT_TIME) warn_printf("T(%f)", th->delay);
 if (th->wait_for & WAIT_JOIN)

```

# Index: io.c

— io.c (revision 16276)  
+++ io.c (working copy)  
@@ -351,4 +351,5 @@ io\_fflush(f, fptr)  
int n;

- rb\_io\_check\_closed(fptr);  
if (!rb\_thread\_fd\_writable(fileno(f))) {  
rb\_io\_check\_closed(fptr);  
@@ -388,4 +389,8 @@ rb\_io\_wait\_readable(f)  
return Qtrue;

- 

```
 case EPIPE:

```

- close(f);

- return Qfalse;

- 

```
 default:

```

return Qfalse;  
@@ -416,4 +421,8 @@ rb\_io\_wait\_writable(f)  
return Qtrue;

- 

```
 case EPIPE:

```

- close(f);

- return Qfalse;

- 

```
 default:

```

return Qfalse;  
@@ -1724,5 +1733,5 @@ rb\_io\_getline(rs, io)  
while ((c = appendline(fptr, newline, &str)) != EOF &&  
(c != newline || RSTRING(str)-\>len \< rslen ||

- (rspara || rscheck(rsptr,rslen,rs), 0) ||

- ((rspara || rscheck(rsptr,rslen,rs)) && 0) ||  
memcmp(RSTRING(str)-\>ptr+RSTRING(str)-\>len-rslen,rsptr,rslen)));

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 8, 2008, 6:02pm UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404/5 "2008-05-08T18:02:47Z")

</div>

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

In message “Re: [ruby-dev:34578] Re: write to broken pipe on Linux”  
on Sat, 3 May 2008 09:24:58 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|\> e$B$O$8$a$KN)$AJV$C$F9M$($k$H!“FI$\_=P$=$&$H$7$?;~$Ke(BEPIPEe$B$,JV$Ce(B  
|\> e$B$F$-$F$7$^$C$?e(BIOe$B$KBP$7$F$I$N$h$&$KBP=h$9$Y$-$J$s$G$7$g$&$M!#e(B  
|\> BROKENPIPEe$B%U%i%0$rN)$F$k!”$H$$$&$N$b$“$s$^$j@5$7$$BP=h$N$h$&e(B  
|\> e$B$K$O;W$($J$$$s$G$9$,!#$d$O$j6/@)E\*$Ke(Bclosee$B$7$FNc30$+$J$”!#e(B

|1.8e$B$,LdBj$G$9$M!#$H$j$"$($:;n$7$F$\_$?$s$G$9$,!"e(Bdeadlocke$B$K$J$C$Fe(B  
|e$B$7$^$$$^$7$?!#e(B

e$B%Q%C%A$Oe(Bdeadlocke$B$K$J$C$?$b$N$G$7$g$&$+!#J}8~@-$H$7$F$Oe(BEPIPE  
e$B$G6/@)e(Bclose+e$BNc30$G$$$$$H;W$&$s$G$9$,!#e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 2, 2008, 7:57am UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404/6 "2008-05-02T07:57:58Z")

</div>

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

At Fri, 2 May 2008 04:35:52 +0900,  
Yukihiro M. wrote in [ruby-dev:34568]:

> e$B$J$/$F$b$$$$$7!“0z?tJQ$($J$/$F$$$$$7!#e(B  
> e$B\>e5-%j%s%/@h$N\>pJs$K$h$k$H!”\>/$J$/$H$be(BWindows Vistae$B$He(BMac OS  
> X  
> 10.5e$B$G$OH/@8$7$J$$$h$&$G$9!#e(B

shutdowne$B$G$O!"e(BEPIPEe$B$NBe$o$j$Ke(BENOTCONNe$B$,H/@8$9$k$h$&$K$J$k$@$1$Ge(B  
e$B$=$N\<!$N=q$-9~$\_$G$d$O$j%V%m%C%/$7$F$7$^$&$h$&$G$9!#e(Bclosee$B$K$9$ke(B  
e$B$He(BEBADFe$B$K$O$J$k$N$G$9$,!"e(Beof?e$B$de(Bclosee$B$G$bF1$8$/e(BEBADFe$B$,H/@8$7$F$7e(B  
e$B$^$&$h$&$K$J$j$^$9!#B\>$N%9%l%C%I$NM-L5$K$h$C$FF0:n$,JQ$o$C$F$7$^e(B  
e$B$&$N$b$I$&$+$H$$$&5$$b$7$^$9$,!#e(B

e$B$H$$$&$+!"e(B1.9e$B$G$O$9$G$Ke(Bblocking  
regione$B$r;H$($Pe(Bselecte$B$OI,MW$J$$$Oe(B  
e$B$:$G$9!#e(B

# Index: io.c

— io.c (revision 16261)  
+++ io.c (working copy)  
@@ -187,5 +187,4 @@ static int max\_file\_descriptor = NOFILE;  
#define READ\_CHECK(fptr) do {  
if (!READ\_DATA\_PENDING(fptr)) {\

- rb\_thread\_wait\_fd((fptr)-\>fd);  
rb\_io\_check\_closed(fptr);  
}  
@@ -513,18 +512,19 @@ struct io\_internal\_struct {  
void \*buf;  
size\_t capa;
- int is\_read;  
};

static VALUE  
-internal\_io\_func(void \*ptr)  
+internal\_read\_func(void \*ptr)  
{  
struct io\_internal\_struct _iis = (struct io\_internal\_struct_)ptr;

- if (iis-\>is\_read) {  
return read(iis-\>fd, iis-\>buf, iis-\>capa);  
}
- else {

- 

+static VALUE  
+internal\_write\_func(void \*ptr)  
+{

- struct io\_internal\_struct _iis = (struct io\_internal\_struct_)ptr;  
return write(iis-\>fd, iis-\>buf, iis-\>capa);  
}  
-}

static int  
@@ -535,7 +535,6 @@ rb\_read\_internal(int fd, void \*buf, size  
iis.buf = buf;  
iis.capa = count;

- iis.is\_read = 1;

- return rb\_thread\_blocking\_region(internal\_io\_func, &iis,  
RB\_UBF\_DFL, 0);

- return rb\_thread\_blocking\_region(internal\_read\_func, &iis,  
RB\_UBF\_DFL, 0);  
}

@@ -547,7 +546,6 @@ rb\_write\_internal(int fd, void \*buf, siz  
iis.buf = buf;  
iis.capa = count;

- iis.is\_read = 0;

- return rb\_thread\_blocking\_region(internal\_io\_func, &iis,  
RB\_UBF\_DFL, 0);

- return rb\_thread\_blocking\_region(internal\_write\_func, &iis,  
RB\_UBF\_DFL, 0);  
}

@@ -617,5 +615,4 @@ rb\_io\_wait\_readable(int f)  
case ERESTART:  
#endif

- rb\_thread\_wait\_fd(f);  
return Qtrue;

@@ -659,5 +656,4 @@ rb\_io\_wait\_writable(int f)  
case ERESTART:  
#endif

- rb\_thread\_fd\_writable(f);  
return Qtrue;

@@ -731,9 +727,5 @@ io\_fwrite(VALUE str, rb\_io\_t \*fptr)  
if (n == 0)  
return len;

- 

```
   /* avoid context switch between "a" and "\n" in STDERR.puts 

```

“a”.

- 

```
      [ruby-dev:25080] */

```

- if (fptr-\>stdio\_file != stderr && !rb\_thread\_fd\_writable(fptr-\>fd)) {  
rb\_io\_check\_closed(fptr);
- }  
retry:  
l = n;  
@@ -1303,5 +1295,4 @@ io\_fread(VALUE str, long offset, rb\_io\_t  
if ((n -= c) \<= 0) break;  
}
- rb\_thread\_wait\_fd(fptr-\>fd);  
rb\_io\_check\_closed(fptr);  
if (io\_fillbuf(fptr) \< 0) {  
@@ -1474,9 +1465,6 @@ io\_getpartial(int argc, VALUE \*argv, VAL  
if (nonblock) {  
rb\_io\_set\_nonblock(fptr);
- 

```
 n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
   }

```

- 

```
   else {
       n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);

```

- }  
if (n \< 0) {  
if (!nonblock && rb\_io\_wait\_readable(fptr-\>fd))  
@@ -1776,5 +1764,4 @@ appendline(rb\_io\_t \*fptr, int delim, VAL  
}  
}
- rb\_thread\_wait\_fd(fptr-\>fd);  
rb\_io\_check\_closed(fptr);  
if (io\_fillbuf(fptr) \< 0) {  
@@ -1813,5 +1800,4 @@ swallow(rb\_io\_t \*fptr, int term)  
rb\_sys\_fail(fptr-\>path);  
}
- rb\_thread\_wait\_fd(fptr-\>fd);  
rb\_io\_check\_closed(fptr);  
} while (io\_fillbuf(fptr) == 0);  
@@ -1853,5 +1839,4 @@ rb\_io\_getline\_fast(rb\_io\_t \*fptr)  
if (e) break;  
}
- rb\_thread\_wait\_fd(fptr-\>fd);  
rb\_io\_check\_closed(fptr);  
if (io\_fillbuf(fptr) \< 0) {  
@@ -2419,17 +2404,9 @@ rb\_io\_getc(VALUE io)  
return io\_getc(fptr, enc);  
}

- 

int  
rb\_getc(FILE \*f)  
{

- int c;
- 
- if (!STDIO\_READ\_DATA\_PENDING(f)) {
- rb\_thread\_wait\_fd(fileno(f));
- }
- TRAP\_BEG;
- c = getc(f);
- TRAP\_END;
- 
- return c;

- return rb\_thread\_blocking\_region((rb\_blocking\_function\_t\*)fgetc, f,  
RB\_UBF\_DFL, 0);  
}

@@ -3024,10 +3001,6 @@ rb\_io\_syswrite(VALUE io, VALUE str)  
rb\_warn(“syswrite for buffered IO”);  
}

- if (!rb\_thread\_fd\_writable(fptr-\>fd)) {  
rb\_io\_check\_closed(fptr);
- }
- TRAP\_BEG;
- n = write(fptr-\>fd, RSTRING\_PTR(str), RSTRING\_LEN(str));
- TRAP\_END;

- n = rb\_write\_internal(fptr-\>fd, RSTRING\_PTR(str),  
RSTRING\_LEN(str));

- rb\_thread\_wait\_fd(fptr-\>fd);  
rb\_io\_check\_closed(fptr);  
if (RSTRING\_LEN(str) != ilen) {  
@@ -6632,5 +6604,4 @@ copy\_stream\_fallback\_body(VALUE arg)  
else {  
ssize\_t ss;
- 

```
       rb_thread_wait_fd(stp->src_fd);
       rb_str_resize(buf, buflen);
       ss = copy_stream_read(stp, RSTRING_PTR(buf), l, off);

```

# Index: ext/socket/socket.c

— ext/socket/socket.c (revision 16261)  
+++ ext/socket/socket.c (working copy)  
@@ -103,4 +103,6 @@ int Rconnect();  
#endif

+#define BLOCKING\_REGION(func, arg)  
(long)rb\_thread\_blocking\_region((func), (arg), RB\_UBF\_DFL, 0)  
+  
#define INET\_CLIENT 0  
#define INET\_SERVER 1  
@@ -496,35 +498,58 @@ bsock\_getpeername(VALUE sock)  
}

+struct send\_arg {

- int fd, flags;
- VALUE mesg;
- struct sockaddr \*to;
- socklen\_t tolen;  
+};
- 

+static VALUE  
+sendto\_blocking(void \*data)  
+{

- struct send\_arg \*arg = data;
- VALUE mesg = arg-\>mesg;
- return (VALUE)sendto(arg-\>fd, RSTRING\_PTR(mesg), RSTRING\_LEN(mesg),
- 

```
  arg->flags, arg->to, arg->tolen);

```

+}  
+  
+static VALUE  
+send\_blocking(void \*data)  
+{

- struct send\_arg \*arg = data;
- VALUE mesg = arg-\>mesg;
- return (VALUE)send(arg-\>fd, RSTRING\_PTR(mesg), RSTRING\_LEN(mesg),
- 

```
      arg->flags);

```

+}  
+  
static VALUE  
bsock\_send(int argc, VALUE \*argv, VALUE sock)  
{

- VALUE mesg, to;
- VALUE flags;

- struct send\_arg arg;
- VALUE flags, to;  
rb\_io\_t \*fptr;

- int fd, n;

- int n;

- rb\_blocking\_function\_t \*func;

- rb\_scan\_args(argc, argv, “21”, &mesg, &flags, &to);

- rb\_scan\_args(argc, argv, “21”, &arg.mesg, &flags, &to);

- StringValue(mesg);
- if (!NIL\_P(to)) StringValue(to);
- GetOpenFile(sock, fptr);
- fd = fptr-\>fd;
- rb\_thread\_fd\_writable(fd);
- retry:

- StringValue(arg.mesg);  
if (!NIL\_P(to)) {

- 

```
   TRAP_BEG;

```

- n = sendto(fd, RSTRING\_PTR(mesg), RSTRING\_LEN(mesg), NUM2INT(flags),
- 

```
  (struct sockaddr*)RSTRING_PTR(to), RSTRING_LEN(to));

```

- 

```
   TRAP_END;

```

- StringValue(to);
- to = rb\_str\_new4(to);
- arg.to = (struct sockaddr \*)RSTRING\_PTR(to);
- arg.tolen = RSTRING\_LEN(to);
- func = sendto\_blocking;  
}  
else {

- 

```
   TRAP_BEG;

```

- n = send(fd, RSTRING\_PTR(mesg), RSTRING\_LEN(mesg), NUM2INT(flags));
- 

```
   TRAP_END;

```

- func = send\_blocking;  
}

- if (n \< 0) {
- if (rb\_io\_wait\_writable(fd)) {
- 

```
 goto retry;

```

- GetOpenFile(sock, fptr);
- arg.fd = fptr-\>fd;
- arg.flags = NUM2INT(flags);
- while ((n = (int)BLOCKING\_REGION(func, &arg)) \< 0) {
- if (rb\_io\_wait\_writable(arg.fd)) {
- 

```
 continue;

```

}  
rb\_sys\_fail(“send(2)”);  
@@ -570,20 +595,33 @@ enum sock\_recv\_type {  
};

+struct recvfrom\_arg {

- int fd, flags;
- VALUE str;
- socklen\_t alen;
- char buf[1024];  
+};
- 

+static VALUE  
+recvfrom\_blocking(void \*data)  
+{

- struct recvfrom\_arg \*arg = data;
- return (VALUE)recvfrom(arg-\>fd, RSTRING\_PTR(arg-\>str),  
RSTRING\_LEN(arg-\>str),
- 

```
    arg->flags, (struct sockaddr*)arg->buf, &arg->alen);

```

+}  
+  
static VALUE  
s\_recvfrom(VALUE sock, int argc, VALUE \*argv, enum sock\_recv\_type from)  
{  
rb\_io\_t \*fptr;

- VALUE str;
- char buf[1024];
- socklen\_t alen = sizeof buf;

- VALUE str, klass;
- struct recvfrom\_arg arg;  
VALUE len, flg;  
long buflen;  
long slen;

- int fd, flags;

- if (flg == Qnil) flags = 0;

- else flags = NUM2INT(flg);

- if (flg == Qnil) arg.flags = 0;
- else arg.flags = NUM2INT(flg);  
buflen = NUM2INT(len);

@@ -592,24 +630,19 @@ s\_recvfrom(VALUE sock, int argc, VALUE \*  
rb\_raise(rb\_eIOError, “recv for buffered IO”);  
}

- fd = fptr-\>fd;
- 
- str = rb\_tainted\_str\_new(0, buflen);

- arg.fd = fptr-\>fd;
- arg.alen = sizeof(arg.buf);

- retry:
- rb\_thread\_wait\_fd(fd);
- rb\_io\_check\_closed(fptr);
- if (RSTRING\_LEN(str) != buflen) {

- arg.str = str = rb\_tainted\_str\_new(0, buflen);
- klass = RBASIC(str)-\>klass;
- RBASIC(str)-\>klass = 0;
- 
- while (rb\_io\_check\_closed(fptr),
- 

```
(slen = BLOCKING_REGION(recvfrom_blocking, &arg)) < 0) {

```

- if (RBASIC(str)-\>klass || RSTRING\_LEN(str) != buflen) {  
rb\_raise(rb\_eRuntimeError, “buffer string modified”);  
}

- TRAP\_BEG;
- slen = recvfrom(fd, RSTRING\_PTR(str), buflen, flags, (struct  
sockaddr\*)buf, &alen);
- TRAP\_END;
- 
- if (slen \< 0) {
- if (rb\_io\_wait\_readable(fd)) {
- 

```
 goto retry;

```

- }
- rb\_sys\_fail(“recvfrom(2)”);  
}

- 
- RBASIC(str)-\>klass = klass;  
if (slen \< RSTRING\_LEN(str)) {  
rb\_str\_set\_len(str, slen);  
@@ -618,13 +651,13 @@ s\_recvfrom(VALUE sock, int argc, VALUE \*  
switch (from) {  
case RECV\_RECV:

- return (VALUE)str;

- return str;  
case RECV\_IP:  
#if 0

- if (alen != sizeof(struct sockaddr\_in)) {

- if (arg.alen != sizeof(struct sockaddr\_in)) {  
rb\_raise(rb\_eTypeError, “sockaddr size differs - should not  
happen”);  
}  
#endif

- if (alen && alen != sizeof(buf)) /\* OSX doesn’t return a from result  
for connection-oriented sockets \*/
- 

```
 return rb_assoc_new(str, ipaddr((struct sockaddr*)buf, fptr->mode 

```

& FMODE\_NOREVLOOKUP));

- if (arg.alen && arg.alen != sizeof(arg.buf)) /\* OSX doesn’t return a  
from result for connection-oriented sockets \*/
- 

```
 return rb_assoc_new(str, ipaddr((struct sockaddr*)arg.buf, 

```

fptr-\>mode & FMODE\_NOREVLOOKUP));  
else  
return rb\_assoc\_new(str, Qnil);  
@@ -632,8 +665,8 @@ s\_recvfrom(VALUE sock, int argc, VALUE \*  
#ifdef HAVE\_SYS\_UN\_H  
case RECV\_UNIX:

- 

```
   return rb_assoc_new(str, unixaddr((struct sockaddr_un*)buf, 

```

alen));

- 

```
   return rb_assoc_new(str, unixaddr((struct sockaddr_un*)arg.buf, 

```

arg.alen));  
#endif  
case RECV\_SOCKET:

- return rb\_assoc\_new(str, rb\_str\_new(buf, alen));

- return rb\_assoc\_new(str, rb\_str\_new(arg.buf, arg.alen));  
default:  
rb\_bug(“s\_recvfrom called with bad value”);  
@@ -924,5 +957,6 @@ sock\_addrinfo(VALUE host, VALUE port, in  
if (r-\>ai\_socktype == SOCK\_DGRAM) {  
r-\>ai\_protocol = IPPROTO\_UDP;

- 

```
           } else if (r->ai_socktype == SOCK_STREAM) {

```

- }
- else if (r-\>ai\_socktype == SOCK\_STREAM) {  
r-\>ai\_protocol = IPPROTO\_TCP;  
}  
@@ -1096,9 +1130,32 @@ wait\_connectable(int fd)  
#endif

+struct connect\_arg {

- int fd;
- const struct sockaddr \*sockaddr;
- socklen\_t len;  
+};
- 

+static VALUE  
+connect\_blocking(void \*data)  
+{

- struct connect\_arg \*arg = data;
- return (VALUE)connect(arg-\>fd, arg-\>sockaddr, arg-\>len);  
+}
- 

+#if defined(SOCKS) && !defined(SOCKS5)  
+static VALUE  
+socks\_connect\_blocking(void \*data)  
+{

- struct connect\_arg \*arg = data;
- return (VALUE)Rconnect(arg-\>fd, arg-\>sockaddr, arg-\>len);  
+}  
+#endif
- 

static int  
-ruby\_connect(int fd, struct sockaddr \*sockaddr, int len, int socks)  
+ruby\_connect(int fd, const struct sockaddr \*sockaddr, int len, int  
socks)  
{  
int status;

- int mode;

- rb\_blocking\_function\_t \*func = connect\_blocking;
- struct connect\_arg arg;  
#if WAIT\_IN\_PROGRESS \> 0  
int wait\_in\_progress = -1;  
@@ -1107,36 +1164,12 @@ ruby\_connect(int fd, struct sockaddr \*so  
#endif

-#if defined(HAVE\_FCNTL)  
-# if defined(F\_GETFL)

- mode = fcntl(fd, F\_GETFL, 0);  
-# else
- mode = 0;  
-# endif
- 

-#ifdef O\_NDELAY  
-# define NONBLOCKING O\_NDELAY  
-#else  
-#ifdef O\_NBIO  
-# define NONBLOCKING O\_NBIO  
-#else  
-# define NONBLOCKING O\_NONBLOCK  
-#endif  
-#endif  
-#ifdef SOCKS5

- if (!socks)  
-#endif
- fcntl(fd, F\_SETFL, mode|NONBLOCKING);  
-#endif /\* HAVE\_FCNTL \*/
- 
- for (;😉 {

- arg.fd = fd;
- arg.sockaddr = sockaddr;
- arg.len = len;  
#if defined(SOCKS) && !defined(SOCKS5)

- if (socks) {
- 

```
 status = Rconnect(fd, sockaddr, len);

```

- }
- else

- if (socks) func = socks\_connect\_blocking;  
#endif

- {
- 

```
 status = connect(fd, sockaddr, len);

```

- }

- for (;😉 {
- status = (int)BLOCKING\_REGION(func, &arg);  
if (status \< 0) {  
switch (errno) {  
@@ -1199,7 +1232,4 @@ ruby\_connect(int fd, struct sockaddr \*so  
}  
}  
-#ifdef HAVE\_FCNTL

- fcntl(fd, F\_SETFL, mode);  
-#endif  
return status;  
}  
@@ -1240,5 +1270,5 @@ init\_inetsock\_internal(struct inetsock\_a  
struct addrinfo \*res;  
int fd, status = 0;
- char \*syscall;

- char \*syscall = 0;

- if (type == INET\_SERVER)
- listen(fd, 5);
- /\* create new instance \*/  
return init\_sock(arg-\>sock, fd);  
@@ -1450,10 +1477,17 @@ static VALUE  
tcp\_svr\_init(int argc, VALUE \*argv, VALUE sock)  
{
- VALUE arg1, arg2;

- VALUE arg1, arg2, blog;
- rb\_io\_t \*fptr;
- int backlog = 5;

- if (rb\_scan\_args(argc, argv, “11”, &arg1, &arg2) == 2)
- return init\_inetsock(sock, arg1, arg2, Qnil, Qnil, INET\_SERVER);
- else
- return init\_inetsock(sock, Qnil, arg1, Qnil, Qnil, INET\_SERVER);

- if (rb\_scan\_args(argc, argv, “11:backlog”, &arg1, &arg2, &blog) !=

1. 

- arg2 = arg1, arg1 = Qnil;
- if (!NIL\_P(blog)) backlog = NUM2INT(blog);
- sock = init\_inetsock(sock, arg1, arg2, Qnil, Qnil, INET\_SERVER);
- GetOpenFile(sock, fptr);
- if (listen(fptr-\>fd, backlog)) {
- rb\_sys\_fail(“listen”);
- }
- return sock;  
}

@@ -1491,4 +1525,17 @@ s\_accept\_nonblock(VALUE klass, rb\_io\_t \*  
}

+struct accept\_arg {

- int fd;
- struct sockaddr \*sockaddr;
- socklen\_t \*len;  
+};
- 

+static VALUE  
+accept\_blocking(void \*data)  
+{

- struct accept\_arg \*arg = data;
- return (VALUE)accept(arg-\>fd, arg-\>sockaddr, arg-\>len);  
+}
- 

static VALUE  
s\_accept(VALUE klass, int fd, struct sockaddr \*sockaddr, socklen\_t  
\*len)  
@@ -1496,15 +1543,12 @@ s\_accept(VALUE klass, int fd, struct soc  
int fd2;  
int retry = 0;

- struct accept\_arg arg;

- arg.fd = fd;

- arg.sockaddr = sockaddr;

- arg.len = len;  
retry:

- rb\_thread\_wait\_fd(fd);  
-#if defined(\_nec\_ews)
- fd2 = accept(fd, sockaddr, len);  
-#else
- TRAP\_BEG;
- fd2 = accept(fd, sockaddr, len);
- TRAP\_END;  
-#endif

- fd2 = (int)BLOCKING\_REGION(accept\_blocking, &arg);  
if (fd2 \< 0) {  
switch (errno) {  
@@ -1787,8 +1831,9 @@ static VALUE  
udp\_send(int argc, VALUE \*argv, VALUE sock)  
{

- VALUE mesg, flags, host, port;

- VALUE flags, host, port;  
rb\_io\_t \*fptr;  
int n;  
struct addrinfo \*res0, \*res;

- struct send\_arg arg;

- rb\_scan\_args(argc, argv, “4”, &mesg, &flags, &host, &port);

- rb\_scan\_args(argc, argv, “4”, &arg.mesg, &flags, &host, &port);

- StringValue(mesg);

- StringValue(arg.mesg);  
res0 = sock\_addrinfo(host, port, SOCK\_DGRAM, 0);  
GetOpenFile(sock, fptr);
- arg.fd = fptr-\>fd;
- arg.flags = NUM2INT(flags);  
for (res = res0; res; res = res-\>ai\_next) {  
retry:

- n = sendto(fptr-\>fd, RSTRING\_PTR(mesg), RSTRING\_LEN(mesg),  
NUM2INT(flags),
- 

```
  res->ai_addr, res->ai_addrlen);

```

- arg.to = res-\>ai\_addr;
- arg.tolen = res-\>ai\_addrlen;
- n = (int)BLOCKING\_REGION(sendto\_blocking, &arg);  
if (n \>= 0) {  
freeaddrinfo(res0);  
@@ -1920,4 +1968,16 @@ unix\_recvfrom(int argc, VALUE \*argv, VAL  
#endif

+struct iomsg\_arg {

- int fd;
- struct msghdr msg;  
+};
- 

+static VALUE  
+sendmsg\_blocking(void \*data)  
+{

- struct iomsg\_arg \*arg = data;
- return sendmsg(arg-\>fd, &arg-\>msg, 0);  
+}
- 

static VALUE  
unix\_send\_io(VALUE sock, VALUE val)  
@@ -1926,5 +1986,5 @@ unix\_send\_io(VALUE sock, VALUE val)  
int fd;  
rb\_io\_t \*fptr;

- struct msghdr msg;

- struct iomsg\_arg arg;  
struct iovec vec[1];  
char buf[1];  
@@ -1951,6 +2011,6 @@ unix\_send\_io(VALUE sock, VALUE val)  
GetOpenFile(sock, fptr);

- msg.msg\_name = NULL;
- msg.msg\_namelen = 0;

- arg.msg.msg\_name = NULL;

- arg.msg.msg\_namelen = 0;

- msg.msg\_iov = vec;
- msg.msg\_iovlen = 1;

- arg.msg.msg\_iov = vec;
- arg.msg.msg\_iovlen = 1;

#if FD\_PASSING\_BY\_MSG\_CONTROL

- msg.msg\_control = (caddr\_t)&cmsg;
- msg.msg\_controllen = CMSG\_LEN(sizeof(int));
- msg.msg\_flags = 0;

- arg.msg.msg\_control = (caddr\_t)&cmsg;
- arg.msg.msg\_controllen = CMSG\_LEN(sizeof(int));
- arg.msg.msg\_flags = 0;  
MEMZERO((char\*)&cmsg, char, sizeof(cmsg));  
cmsg.hdr.cmsg\_len = CMSG\_LEN(sizeof(int));  
@@ -1971,9 +2031,10 @@ unix\_send\_io(VALUE sock, VALUE val)  
\*(int \*)CMSG\_DATA(&cmsg.hdr) = fd;  
#else

- msg.msg\_accrights = (caddr\_t)&fd;
- msg.msg\_accrightslen = sizeof(fd);

- arg.msg.msg\_accrights = (caddr\_t)&fd;
- arg.msg.msg\_accrightslen = sizeof(fd);  
#endif

- if (sendmsg(fptr-\>fd, &msg, 0) == -1)

- arg.fd = fptr-\>fd;
- if ((int)BLOCKING\_REGION(sendmsg\_blocking, &arg) == -1)  
rb\_sys\_fail(“sendmsg(2)”);

@@ -1986,4 +2047,11 @@ unix\_send\_io(VALUE sock, VALUE val)

static VALUE  
+recvmsg\_blocking(void \*data)  
+{

- struct iomsg\_arg \*arg = data;
- return recvmsg(arg-\>fd, &arg-\>msg, 0);  
+}
- 

+static VALUE  
unix\_recv\_io(int argc, VALUE \*argv, VALUE sock)  
{  
@@ -1991,5 +2059,5 @@ unix\_recv\_io(int argc, VALUE \*argv, VALU  
VALUE klass, mode;  
rb\_io\_t \*fptr;

- struct msghdr msg;

- struct iomsg\_arg arg;  
struct iovec vec[2];  
char buf[1];  
@@ -2011,18 +2079,16 @@ unix\_recv\_io(int argc, VALUE \*argv, VALU  
GetOpenFile(sock, fptr);

- rb\_io\_wait\_readable(fptr-\>fd);
- 
- msg.msg\_name = NULL;
- msg.msg\_namelen = 0;

- arg.msg.msg\_name = NULL;

- arg.msg.msg\_namelen = 0;

- msg.msg\_iov = vec;
- msg.msg\_iovlen = 1;

- arg.msg.msg\_iov = vec;
- arg.msg.msg\_iovlen = 1;

#if FD\_PASSING\_BY\_MSG\_CONTROL

- msg.msg\_control = (caddr\_t)&cmsg;
- msg.msg\_controllen = CMSG\_SPACE(sizeof(int));
- msg.msg\_flags = 0;

- arg.msg.msg\_control = (caddr\_t)&cmsg;
- arg.msg.msg\_controllen = CMSG\_SPACE(sizeof(int));
- arg.msg.msg\_flags = 0;  
cmsg.hdr.cmsg\_len = CMSG\_LEN(sizeof(int));  
cmsg.hdr.cmsg\_level = SOL\_SOCKET;  
@@ -2030,17 +2096,18 @@ unix\_recv\_io(int argc, VALUE \*argv, VALU  
\*(int \*)CMSG\_DATA(&cmsg.hdr) = -1;  
#else

- msg.msg\_accrights = (caddr\_t)&fd;
- msg.msg\_accrightslen = sizeof(fd);

- arg.msg.msg\_accrights = (caddr\_t)&fd;
- arg.msg.msg\_accrightslen = sizeof(fd);  
fd = -1;  
#endif

- if (recvmsg(fptr-\>fd, &msg, 0) == -1)

- arg.fd = fptr-\>fd;
- if ((int)BLOCKING\_REGION(recvmsg\_blocking, &arg) == -1)  
rb\_sys\_fail(“recvmsg(2)”);

#if FD\_PASSING\_BY\_MSG\_CONTROL

- if (msg.msg\_controllen != CMSG\_SPACE(sizeof(int))) {

- if (arg.msg.msg\_controllen != CMSG\_SPACE(sizeof(int))) {  
rb\_raise(rb\_eSocket,  
“file descriptor was not passed (msg\_controllen=%d, %d  
expected)”,

- 

```
     msg.msg_controllen, CMSG_SPACE(sizeof(int)));

```

- 

```
arg.msg.msg_controllen, CMSG_SPACE(sizeof(int)));

```

}  
if (cmsg.hdr.cmsg\_len != CMSG\_LEN(sizeof(int))) {  
@@ -2060,8 +2127,8 @@ unix\_recv\_io(int argc, VALUE \*argv, VALU  
}  
#else

- if (msg.msg\_accrightslen != sizeof(fd)) {

- if (arg.msg.msg\_accrightslen != sizeof(fd)) {  
rb\_raise(rb\_eSocket,  
“file descriptor was not passed (accrightslen) : %d != %d”,

- 

```
       msg.msg_accrightslen, sizeof(fd));

```

- 

```
arg.msg.msg_accrightslen, sizeof(fd));

```

}  
#endif

— e$BKM$NA0$Ke(BBuge$B$O$J$$!#e(B  
— e$BKM$N8e$m$Ke(BBuge$B$O$G$-$k!#e(B  
e$BCfEDe(B e$B?-1Ye(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 8, 2008, 6:15pm UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404/7 "2008-05-08T18:15:46Z")

</div>

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

In message “Re: [ruby-dev:34619] Re: write to broken pipe on Linux”  
on Fri, 9 May 2008 01:09:44 +0900, Tanaka A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|\> e$B%Q%C%A$Oe(Bdeadlocke$B$K$J$C$?$b$N$G$7$g$&$+!#J}8~@-$H$7$F$Oe(BEPIPE  
|\> e$B$G6/@)e(Bclose+e$BNc30$G$$$$$H;W$&$s$G$9$,!#e(B  
|  
|e$B%=%1%C%H$G$O$^$:$$$s$8$c$J$$$G$9$+!#e(B

|EPIPE e$B$N$"$H$G$b!"5UJ}8~$NDL?.$O2DG=$G!"e(Bclose e$B$5$l$F$7$^$&$He(B  
|e$BDL?.$,=PMh$J$/$J$j$^$9!#e(B

e$B$=$&$+$"!#$7$+$be(BEPIPEe$B$,5/$-$=$&$J$N$O\<g$K%=%1%C%H$@$C$?$j$7e(B  
e$B$^$9$7$M$(!#$d$O$j%U%i%0$G\>pJs$rJ];}$9$k$7$+$J$$$N$+$J!#e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 8, 2008, 6:12pm UTC](https://www.ruby-forum.com/t/write-to-broken-pipe-on-linux/136404/8 "2008-05-08T18:12:15Z")

</div>

In article [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid),  
Yukihiro M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> e$B%Q%C%A$Oe(Bdeadlocke$B$K$J$C$?$b$N$G$7$g$&$+!#J}8~@-$H$7$F$Oe(BEPIPE  
> e$B$G6/@)e(Bclose+e$BNc30$G$$$$$H;W$&$s$G$9$,!#e(B

e$B%=%1%C%H$G$O$^$:$$$s$8$c$J$$$G$9$+!#e(B

% ruby -rsocket -e ’  
s1, s2 = UNIXSocket.pair  
s1.shutdown(Socket::SHUT\_WR)  
begin  
s1.write “a”  
rescue  
p $!  
end  
s2.write “a”  
p s1.read(1)  
’  
#\<Errno::EPIPE: Broken pipe\>  
“a”

EPIPE e$B$N$"$H$G$b!"5UJ}8~$NDL?.$O2DG=$G!"e(Bclose e$B$5$l$F$7$^$&$He(B  
e$BDL?.$,=PMh$J$/$J$j$^$9!#e(B
