[fpc-pascal] fpselect does not work on linux
Rainer Stratmann
RainerStratmann at t-online.de
Sat May 9 13:07:52 CEST 2009
>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 at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Rainer
More information about the fpc-pascal
mailing list