>Select does *not* tell you if a file descriptor is writeable or readable. >It tells you if the read/write operation will block. >This is something subtly different. This is interesting for blocking mode. But since you can switch to nonblocking mode every operation will return immediately.
Here are some descriptions I found about select: http://publib.boulder.ibm.com/infocenter/tpfhelp/current/index.jsp?topic=/com.ibm.ztpf-ztpfdf.doc_put.cur/gtpc2/cpp_select.html http://docs.sun.com/app/docs/doc/816-5168/select-3c?a=view http://www.developerweb.net/forum/showthread.php?p=13486 "...The select socket function monitors a list of file descriptors for readability, readiness for writing, and exception pending conditions." Of course if you are in a blocking mode then a call does not block. ...if the select call returns that what we expect. >For instance, it reports file descriptor 0 as writable, which is rather >strange, since it >is read-only, but correct, because the write call will not block. Indeed the >write call >will return at once with an error condition. > >This is what the kernel sees (I used strace to test your code with descriptor >0): > >select(1, NULL, [0], NULL, {0, 0}) = 1 (out [0], left {0, 0}) May be it is better to test it with sockets descriptors. If I get a result that the call will not block (as you say) and then I write data to the descriptor then the program crashes with exitcode 13... >Which is exactly what I sent. > >In short, is_writable_socket should be implemented differently, not using >select. How can I find out if a socket connection in a nonblocking mode is established? >Michael. Am Samstag, 9. Mai 2009 12:55 schrieb dmitry boyarintsev: > hello Rainer, > > do you check the socket's writability by fpFD_ISSET(sck, fds) ? Yes, before I did it this way, but it was the same behaviour. Windows ok. Linux failed. function is_writable_socket2( s : integer ; var error : longint ) : boolean; var fds : tfdset; tv : timeval; valopt : longint = 1; vallen : {$ifdef linux} longword {$else} longint {$endif}; begin result := false; {$ifdef linux} fpfd_zero( fds ); fpfd_set( s , fds ); {$endif} {$ifdef windows} fd_zero( fds ); fd_set( s , fds ); {$endif} tv.tv_sec := 0; tv.tv_usec := 0; // socket+1 , read , write , except , timeout {$ifdef linux} if fpselect( s + 1 , nil , @fds , nil , @tv ) > 0 then begin if fpfd_isset( s , fds ) = 1 then begin vallen := sizeof( valopt ); if fpgetsockopt( s , sol_socket , so_error , @valopt , @vallen ) = 0 then begin error := valopt; result := valopt = 0; end; end; end; {$else} if select( s + 1 , nil , @fds , nil , @tv ) > 0 then begin if fd_isset( s , fds ) then begin vallen := sizeof( valopt ); if getsockopt( s , sol_socket , so_error , valopt , vallen ) = 0 then begin error := valopt; result := valopt = 0; end; end; end; {$endif} end; > thanks, > dmitry > _______________________________________________ > fpc-pascal maillist - fpc-pascal@lists.freepascal.org > http://lists.freepascal.org/mailman/listinfo/fpc-pascal Rainer _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal