[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