* poll() incompatability with POSIX.1-2001 @ 2002-10-14 14:58 Jogchem de Groot 2002-10-14 15:14 ` Richard B. Johnson 0 siblings, 1 reply; 6+ messages in thread From: Jogchem de Groot @ 2002-10-14 14:58 UTC (permalink / raw) To: linux-kernel Hello, There's an incompatability with the poll() implementation in the linux-2.4 kernel. (Tried 2.4.18). According to the POSIX.1-2001 standard select() and poll() should return writability (POLLOUT) when connect() initated on a non-blocking socket asynchronously completes. http://www.opengroup.org/onlinepubs/007904975/functions/connect.html "If the connection cannot be established immediately and O_NONBLOCK is set for the file descriptor for the socket, connect() shall fail and set errno to [EINPROGRESS], but the connection request shall not be aborted, and the connection shall be established asynchronously. Subsequent calls to connect() for the same socket, before the connection is established, shall fail and set errno to [EALREADY]. When the connection has been established asynchronously, select() and poll() shall indicate that the file descriptor for the socket is ready for writing." On linux-2.4 i noticed the following behaviour: On connect() success select() returns writability for the socket. On connect() failure select() returns readability and writability for the socket. This behaviour is according to the specification. However with poll() (with events=POLLIN|POLLOUT) i get the following behaviour: On connect() success poll() returns POLLOUT in revents. On connect() failure poll() returns POLLIN|POLLHUP|POLLERR in revents. It does not set the POLLOUT bit here.. I hope somebody will take a closer look at this. It doesnt seem to require a big fix at all.. Thank you, bighawk ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: poll() incompatability with POSIX.1-2001 2002-10-14 14:58 poll() incompatability with POSIX.1-2001 Jogchem de Groot @ 2002-10-14 15:14 ` Richard B. Johnson 2002-10-14 17:13 ` Jogchem de Groot 2002-10-15 3:36 ` Geoffrey Lee 0 siblings, 2 replies; 6+ messages in thread From: Richard B. Johnson @ 2002-10-14 15:14 UTC (permalink / raw) To: Jogchem de Groot; +Cc: linux-kernel On Mon, 14 Oct 2002, Jogchem de Groot wrote: > Hello, > > There's an incompatability with the poll() implementation in the > linux-2.4 kernel. (Tried 2.4.18). > > According to the POSIX.1-2001 standard select() and poll() should > return writability (POLLOUT) when connect() initated on a non-blocking > socket asynchronously completes. > > http://www.opengroup.org/onlinepubs/007904975/functions/connect.html > > "If the connection cannot be established immediately and O_NONBLOCK is set > for the file descriptor for the socket, connect() shall fail and set errno to > [EINPROGRESS], but the connection request shall not be aborted, and the > connection shall be established asynchronously. Subsequent calls to connect() > for the same socket, before the connection is established, shall fail and set > errno to [EALREADY]. > > When the connection has been established asynchronously, select() and poll() > shall indicate that the file descriptor for the socket is ready for writing." > > On linux-2.4 i noticed the following behaviour: > > On connect() success select() returns writability for the socket. > On connect() failure select() returns readability and writability for the > socket. > > This behaviour is according to the specification. > > However with poll() (with events=POLLIN|POLLOUT) i get the following > behaviour: > > On connect() success poll() returns POLLOUT in revents. > On connect() failure poll() returns POLLIN|POLLHUP|POLLERR in revents. > > It does not set the POLLOUT bit here.. This is a failure to connect! The socket is therefore not ready for writing or reading -ever. This behavior may not be correct, not because of a failure to set the POLLOUT bit, but because the POLLIN bit is set. Check if this is really true. I can't duplicate this on 2.4.18 here because it's hard to get a deferred connect with my setup. Cheers, Dick Johnson Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips). The US military has given us many words, FUBAR, SNAFU, now ENRON. Yes, top management were graduates of West Point and Annapolis. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: poll() incompatability with POSIX.1-2001 2002-10-14 15:14 ` Richard B. Johnson @ 2002-10-14 17:13 ` Jogchem de Groot 2002-10-15 3:36 ` Geoffrey Lee 1 sibling, 0 replies; 6+ messages in thread From: Jogchem de Groot @ 2002-10-14 17:13 UTC (permalink / raw) To: linux-kernel; +Cc: root Hello, This is a failure to connect! The socket is therefore not ready for writing or reading -ever. This behavior may not be correct, not because of a failure to set the POLLOUT bit, but because the POLLIN bit is set. Check if this is really true. I can't duplicate this on 2.4.18 here because it's hard to get a deferred connect with my setup. It's really true:.. Here is some strace output: Case where connect() succeeds: connect(3, {sin_family=AF_INET, sin_port=htons(111), sin_addr=inet_addr("127.0.0.1")}}, 16) = -1 EINPROGRESS (Operation now in progress) poll([{fd=3, events=POLLIN|POLLOUT, revents=POLLOUT}], 1, -1) = 1 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 As you can see SO_ERROR returns '0', connection succeeded. Case where connect() fails: connect(3, {sin_family=AF_INET, sin_port=htons(110), sin_addr=inet_addr("127.0.0.1")}}, 16) = -1 EINPROGRESS (Operation now in progress) poll([{fd=3, events=POLLIN|POLLOUT, revents=POLLIN|POLLERR|POLLHUP}], 1, -1) = 1 getsockopt(3, SOL_SOCKET, SO_ERROR, [111], [4]) = 0 As you can see SO_ERROR returns '111', connection failed. bighawk ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: poll() incompatability with POSIX.1-2001 2002-10-14 15:14 ` Richard B. Johnson 2002-10-14 17:13 ` Jogchem de Groot @ 2002-10-15 3:36 ` Geoffrey Lee 2002-10-15 7:47 ` Jogchem de Groot 1 sibling, 1 reply; 6+ messages in thread From: Geoffrey Lee @ 2002-10-15 3:36 UTC (permalink / raw) To: Richard B. Johnson; +Cc: Jogchem de Groot, linux-kernel > > > > When the connection has been established asynchronously, select() and poll() > > shall indicate that the file descriptor for the socket is ready for writing." > > > > On linux-2.4 i noticed the following behaviour: > > > > On connect() success select() returns writability for the socket. > > On connect() failure select() returns readability and writability for the > > socket. > > > > This behaviour is according to the specification. > > > > However with poll() (with events=POLLIN|POLLOUT) i get the following > > behaviour: > > > > On connect() success poll() returns POLLOUT in revents. > > On connect() failure poll() returns POLLIN|POLLHUP|POLLERR in revents. > > > > It does not set the POLLOUT bit here.. > > This is a failure to connect! The socket is therefore not ready for > writing or reading -ever. This behavior may not be correct, not > because of a failure to set the POLLOUT bit, but because the POLLIN > bit is set. Check if this is really true. I can't duplicate this > on 2.4.18 here because it's hard to get a deferred connect with my > setup. > Hello! I have done some experimentation. First I used telnet to verify that the host xx.xx.xx.xx on port 80 is up and listening. We verify that this is true. Then, we run a test program. The test program creates a TCP socket which will connect to a given host on a given port then use the fcntl() call to set the non-blocking bit. We then use connect() to connect to the host. We verify that the errno is indeed EINPROGRESS. We then use poll with an events member set to POLLIN | POLLOUT. This is the result on a return from poll(). glee@orion ~/tmp $ ./poll-new -h xx.xx.xx.xx -p 80 connect connect: INPROGRESS poll: POLLOUT is set terminating glee@orion ~/tmp $ So, POLLOUT is set. Now, we try to connect to an invalid port. n ~/tmp $ ./poll-new -h xx.xx.xx.xx -p 4 connect connect: INPROGRESS poll: POLLERR set poll: POLLHUP set poll: POLLOUT is set terminating glee@orion ~/tmp $ So, POLLOUT is set. By the way, what constants should be defined when you do a #include <poll.h>? A lot of them are not defined, those listed in the poll() document on the opengroup website, only POLLPRI and POLLIN, POLLOUT, POLLNVAL, POLLHUP and POLLERR are defined. POLLRDNORM, POLLRDBAND, POLLWRBAND, POLLWRNORM are not defined. -- G. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: poll() incompatability with POSIX.1-2001 2002-10-15 3:36 ` Geoffrey Lee @ 2002-10-15 7:47 ` Jogchem de Groot 2002-10-15 13:53 ` Geoffrey Lee 0 siblings, 1 reply; 6+ messages in thread From: Jogchem de Groot @ 2002-10-15 7:47 UTC (permalink / raw) To: Geoffrey Lee; +Cc: linux-kernel On Tuesday 15 October 2002 05:36, you wrote: > This is the result on a return from poll(). > > glee@orion ~/tmp $ ./poll-new -h xx.xx.xx.xx -p 80 > connect > connect: INPROGRESS > poll: POLLOUT is set > terminating > glee@orion ~/tmp $ > > > So, POLLOUT is set. > > > Now, we try to connect to an invalid port. > > n ~/tmp $ ./poll-new -h xx.xx.xx.xx -p 4 > connect > connect: INPROGRESS > poll: POLLERR set > poll: POLLHUP set > poll: POLLOUT is set > terminating > glee@orion ~/tmp $ > > > So, POLLOUT is set. Hello, on what version did you try this? I've tried this now on Linux-2.4.18 and Linux-2.4.19 and both give the behaviour i described previously (No POLLOUT set). The simple test program i used is as follows: #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/poll.h> #include <sys/select.h> #include <errno.h> main(int argc, char **argv) { int sd,flags,stat,len=sizeof(int); struct sockaddr_in sin; struct pollfd pfd; memset(&sin, 0, sizeof(sin)); sd = socket(AF_INET, SOCK_STREAM, 0); fcntl(sd, F_SETFL, fcntl(sd, F_GETFL, 0) | O_NONBLOCK); sin.sin_addr.s_addr = htonl(0x7f000001); sin.sin_port = htons(atoi(argv[1])); sin.sin_family = AF_INET; if(connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1 && errno == EINPROGRESS) printf("connect returned EINPROGRESS\n"); pfd.fd = sd; pfd.events = POLLIN | POLLOUT; pfd.revents = 0; poll(&pfd, 1, -1); getsockopt(sd, SOL_SOCKET, SO_ERROR, &stat, &len); printf("%s\n", stat ? "failed" : "succeeded"); printf("returned events: %hd\n", pfd.revents); } bighawk ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: poll() incompatability with POSIX.1-2001 2002-10-15 7:47 ` Jogchem de Groot @ 2002-10-15 13:53 ` Geoffrey Lee 0 siblings, 0 replies; 6+ messages in thread From: Geoffrey Lee @ 2002-10-15 13:53 UTC (permalink / raw) To: Jogchem de Groot; +Cc: linux-kernel > Hello, on what version did you try this? I've tried this now on > Linux-2.4.18 and Linux-2.4.19 and both give the behaviour i described > previously (No POLLOUT set). > Ah, you are indeed right. I had a typo in my test code (trailing semi colon). So POLLIN | POLLERR | POLLHUP flags are for the revents member. -- G. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2002-10-15 13:54 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-10-14 14:58 poll() incompatability with POSIX.1-2001 Jogchem de Groot 2002-10-14 15:14 ` Richard B. Johnson 2002-10-14 17:13 ` Jogchem de Groot 2002-10-15 3:36 ` Geoffrey Lee 2002-10-15 7:47 ` Jogchem de Groot 2002-10-15 13:53 ` Geoffrey Lee
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).