[ruby-trunk - Bug #5524][Assigned] IO.wait_for_single_fd(closed fd) sticks on other than Linux

Issue #5524 has been reported by Yui NARUSE.


Bug #5524: IO.wait_for_single_fd(closed fd) sticks on other than Linux
http://redmine.ruby-lang.org/issues/5524

Author: Yui NARUSE
Status: Assigned
Priority: Normal
Assignee: Motohiro KOSAKI
Category:
Target version:
ruby -v: ruby 2.0.0dev (2011-10-31 trunk 33582) [x86_64-freebsd9.0]

r31428 で、test_wait_for_invalid_fd ってテストを追加しており、
IO.wait_for_single_fd(close 済みの fd) が EBADF になることを確認しているのですが、
これ単体で動かすと FreeBSD で戻ってきません。

思うに、このテストって本来ポータブルに刺さる物なんじゃないでしょうか。
test-allだと何かの弾みで通ってしまうだけで。

% cat poll.c
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <errno.h>
int
main(void) {
int pipes[2];
int res = pipe(pipes);
if (res != 0) abort();
int r = pipes[0];
int w = pipes[1];
res = close(w);
if (res != 0) abort();

struct pollfd fds;
fds.fd = w;
fds.events = POLLOUT;
errno = 0;
res = poll(&fds, 1, 1000);
fprintf(stderr, "%d %d %d\n", res, errno, fds.revents);
return 0;

}

というプログラムではポータブルに POLLVAL が返り、

#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
int
main(void) {
int pipes[2];
int res = pipe(pipes);
if (res != 0) abort();
int r = pipes[0];
int w = pipes[1];
res = close(w);
if (res != 0) abort();
fd_set readfds; FD_ZERO(&readfds);
fd_set writefds; FD_ZERO(&writefds);
fd_set exceptfds; FD_ZERO(&exceptfds);
//struct timeval *timeout = NULL;
//FD_SET(r, &readfds);
FD_SET(w, &writefds);
res = select(1, &readfds, &writefds, &exceptfds, NULL);
return 0;
}

はポータブルにブロックされるあたり、このテストってLinux依存なんじゃ無いかという疑惑を持っているんですがどうでしょう。

$B>.:j$G$9(B

$B$($($H!"$J$k$;[email protected];]$,$$$^$$$A$^[email protected]$G$-$F$J$$5$$,$9$k$N$G$9$,!&!&!&!&(B

r31428 $B$G!"(Btest_wait_for_invalid_fd $B$C$F%F%9%H$rDI2C$7$F$*$j!"(B
IO.wait_for_single_fd(close $B:Q$_$N(B fd) $B$,(B EBADF
$B$K$J$k$3$H$r3NG’$7$F$$$k$N$G$9$,!"(B
$B$3$lC1BN$GF0$+$9$H(B FreeBSD $B$GLa$C$F$-$^$;$s!#(B

$B;W$&$K!"$3$N%F%9%H$C$FK\Mh%]!<%?%V%k$K;I$5$kJ*$J$s$8$c$J$$$G$7$g$&$+!#(B
[email protected]$H2?$+$NCF$_$GDL$C$F$7$^$&[email protected]$1$G!#(B

Mac$B$H$+$G$b;I$5$i$J$$$G$9!#(B

int r = pipes[0];
return 0;
}

$B$H$$$&%W%m%0%i%`$G$O%]!<%?%V%k$K(B POLLVAL $B$,JV$j!"(B

POLLVAL$B$,JV$k$H;W$$$^$9$,!"(Bpoll
$B$D$+$&$N$O([email protected]$1$J$s$G(B
$B:#2s$N7o$OL54X78$G$O$J$$$G$7$g$&$+!#(B

res = close(w);

$B$O%]!<%?%V%k$K%V%m%C%/$5$l$k$"$?$j!"$3$N%F%9%H$C$F(BLinux$B0MB8$J$s$8$cL5$$$+$H$$$&5?OG$r;}$C$F$$$k$s$G$9$,$I$&$G$7$g$&!#(B

SUS$B$O(BEBADF$B$rMW5a$7$F$$$k$N$G(BFreeBSD$B$N%P%0$G$O$J$$$G$7$g$&$+!)(B

http://pubs.opengroup.org/onlinepubs/7908799/xsh/select.html

[email protected]$1%F%9%H%9%-%C%[email protected]$a!)(B

Issue #5524 has been updated by Motohiro KOSAKI.

なるせさんのテストプロは
selectのmaxfds引数が間違っているので、動かないのは期待通りではないでしょうか。以下の修正をあててFreeBSDで
動かしてもらえませんか

~/projects/test/select_ebadf% diff -u select_badf.c.orig select_badf.c
diff -u select_badf.c.orig select_badf.c
— select_badf.c.orig 2011-11-08 11:33:44.000000000 -0500
+++ select_badf.c 2011-11-08 11:38:26.000000000 -0500
@@ -3,6 +3,8 @@
#include <sys/select.h>
#include <unistd.h>

+#define max(x,y) ((x > y) ? x : y)
+
int
main(void) {
int pipes[2];
@@ -18,7 +20,8 @@
//struct timeval *timeout = NULL;
//FD_SET(r, &readfds);
FD_SET(w, &writefds);

  • res = select(1, &readfds, &writefds, &exceptfds, NULL);
  • res = select(max(r,w)+1, &readfds, &writefds, &exceptfds, NULL);
  • return 0;
    }

Bug #5524: IO.wait_for_single_fd(closed fd) sticks on other than Linux
http://redmine.ruby-lang.org/issues/5524

Author: Yui NARUSE
Status: Assigned
Priority: Normal
Assignee: Motohiro KOSAKI
Category:
Target version:
ruby -v: -

r31428 で、test_wait_for_invalid_fd ってテストを追加しており、
IO.wait_for_single_fd(close 済みの fd) が EBADF になることを確認しているのですが、
これ単体で動かすと FreeBSD で戻ってきません。

思うに、このテストって本来ポータブルに刺さる物なんじゃないでしょうか。
test-allだと何かの弾みで通ってしまうだけで。

% cat poll.c
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <errno.h>
int
main(void) {
int pipes[2];
int res = pipe(pipes);
if (res != 0) abort();
int r = pipes[0];
int w = pipes[1];
res = close(w);
if (res != 0) abort();

struct pollfd fds;
fds.fd = w;
fds.events = POLLOUT;
errno = 0;
res = poll(&fds, 1, 1000);
fprintf(stderr, "%d %d %d\n", res, errno, fds.revents);
return 0;

}

というプログラムではポータブルに POLLVAL が返り、

#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
int
main(void) {
int pipes[2];
int res = pipe(pipes);
if (res != 0) abort();
int r = pipes[0];
int w = pipes[1];
res = close(w);
if (res != 0) abort();
fd_set readfds; FD_ZERO(&readfds);
fd_set writefds; FD_ZERO(&writefds);
fd_set exceptfds; FD_ZERO(&exceptfds);
//struct timeval *timeout = NULL;
//FD_SET(r, &readfds);
FD_SET(w, &writefds);
res = select(1, &readfds, &writefds, &exceptfds, NULL);
return 0;
}

はポータブルにブロックされるあたり、このテストってLinux依存なんじゃ無いかという疑惑を持っているんですがどうでしょう。

Issue #5524 has been updated by Yui NARUSE.

Motohiro KOSAKI wrote:

なるせさんのテストプロは selectのmaxfds引数が間違っているので、動かないのは期待通りではないでしょうか。以下の修正をあててFreeBSDで
動かしてもらえませんか

おぉ、なるほど、確かにそれだと FreeBSD だけ動きません。
FreeBSD 側のバグとして報告しました、当面 FreeBSD だけスキップするようにします。
http://www.freebsd.org/cgi/query-pr.cgi?pr=162379

Bug #5524: IO.wait_for_single_fd(closed fd) sticks on other than Linux
http://redmine.ruby-lang.org/issues/5524

Author: Yui NARUSE
Status: Feedback
Priority: Normal
Assignee: Yui NARUSE
Category:
Target version:
ruby -v: -

r31428 で、test_wait_for_invalid_fd ってテストを追加しており、
IO.wait_for_single_fd(close 済みの fd) が EBADF になることを確認しているのですが、
これ単体で動かすと FreeBSD で戻ってきません。

思うに、このテストって本来ポータブルに刺さる物なんじゃないでしょうか。
test-allだと何かの弾みで通ってしまうだけで。

% cat poll.c
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <errno.h>
int
main(void) {
int pipes[2];
int res = pipe(pipes);
if (res != 0) abort();
int r = pipes[0];
int w = pipes[1];
res = close(w);
if (res != 0) abort();

struct pollfd fds;
fds.fd = w;
fds.events = POLLOUT;
errno = 0;
res = poll(&fds, 1, 1000);
fprintf(stderr, "%d %d %d\n", res, errno, fds.revents);
return 0;

}

というプログラムではポータブルに POLLVAL が返り、

#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
int
main(void) {
int pipes[2];
int res = pipe(pipes);
if (res != 0) abort();
int r = pipes[0];
int w = pipes[1];
res = close(w);
if (res != 0) abort();
fd_set readfds; FD_ZERO(&readfds);
fd_set writefds; FD_ZERO(&writefds);
fd_set exceptfds; FD_ZERO(&exceptfds);
//struct timeval *timeout = NULL;
//FD_SET(r, &readfds);
FD_SET(w, &writefds);
res = select(1, &readfds, &writefds, &exceptfds, NULL);
return 0;
}

はポータブルにブロックされるあたり、このテストってLinux依存なんじゃ無いかという疑惑を持っているんですがどうでしょう。

Issue #5524 has been updated by Motohiro KOSAKI.

Status changed from Assigned to Feedback
Assignee changed from Motohiro KOSAKI to Yui NARUSE


Bug #5524: IO.wait_for_single_fd(closed fd) sticks on other than Linux
http://redmine.ruby-lang.org/issues/5524

Author: Yui NARUSE
Status: Feedback
Priority: Normal
Assignee: Yui NARUSE
Category:
Target version:
ruby -v: -

r31428 で、test_wait_for_invalid_fd ってテストを追加しており、
IO.wait_for_single_fd(close 済みの fd) が EBADF になることを確認しているのですが、
これ単体で動かすと FreeBSD で戻ってきません。

思うに、このテストって本来ポータブルに刺さる物なんじゃないでしょうか。
test-allだと何かの弾みで通ってしまうだけで。

% cat poll.c
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <errno.h>
int
main(void) {
int pipes[2];
int res = pipe(pipes);
if (res != 0) abort();
int r = pipes[0];
int w = pipes[1];
res = close(w);
if (res != 0) abort();

struct pollfd fds;
fds.fd = w;
fds.events = POLLOUT;
errno = 0;
res = poll(&fds, 1, 1000);
fprintf(stderr, "%d %d %d\n", res, errno, fds.revents);
return 0;

}

というプログラムではポータブルに POLLVAL が返り、

#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
int
main(void) {
int pipes[2];
int res = pipe(pipes);
if (res != 0) abort();
int r = pipes[0];
int w = pipes[1];
res = close(w);
if (res != 0) abort();
fd_set readfds; FD_ZERO(&readfds);
fd_set writefds; FD_ZERO(&writefds);
fd_set exceptfds; FD_ZERO(&exceptfds);
//struct timeval *timeout = NULL;
//FD_SET(r, &readfds);
FD_SET(w, &writefds);
res = select(1, &readfds, &writefds, &exceptfds, NULL);
return 0;
}

はポータブルにブロックされるあたり、このテストってLinux依存なんじゃ無いかという疑惑を持っているんですがどうでしょう。