This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Toward a satisfactory showmanyc


On Thu, Mar 20, 2003 at 08:52:30PM +0100, Paolo Carlini wrote:
> > #include <sys/ioctl.h>
> >
> > int i = 0;
> > ::ioctl(fd, FIONREAD, &i)
> >
> > on any file descriptor (pipe, socket, file, character device) to see
> > how much is available to read.
> >
> > Note that ioctl is not part of POSIX, and that it is often found at
> > <ioctl.h> instead. Also, for files bigger than 2G it reports silly
> > results.
> 
> and then:
> 
> >On many targets it doesn't work on regular files at all.  On some
> >targets (apparently including FreeBSD and Solarix 9) FIONREAD is 
> >defined in <sys/filio.h>.  See also 
> 
> Therefore, what about this updated strategy for showmanyc (easily
> extensible to large file support, it seems to me):
> 
> 1- fstat on files.
> 2- If fstat fails, ioctl for everything else.
> 
> Of course this implies autoconf machinery for <sys/ioctl.h>
> vs <ioctl.h> and also for FIONREAD in <sys/filio.h>
> (I had hoped for fewer different possibilites :(

Certainly the overwhelming bulk of the implementation work will be in 
the autoconf machinery.  (Fortunately, "#ifdef FIONREAD" works, which 
might reduce complexity a little bit.)  

I am sensitive about the performance implications of calling fstat() 
first.  On any given platform ioctl() or FIONREAD might not exist.
I'm thinking it should try, in order:

  ioctl
    If the test is #ifdef'ed out, fine.  If it fails, fine.
    If it reports a positive number, return it.  If it reports
    a negative number, it's probably a file bigger than 2G, so
    skip to the next test.  Otherwise...
  poll
    A cheap test -- if it reports "not ready", return 0.
    Note that it reports "ready" if the next read will say EOF,
    so "ready" just tells us it's worth looking more closely.
  fstat
    If it says the fd is a file, then use st_size as in your 
    existing patch.  If it says the fd is a pipe or stream, the
    ioctl above must have been #ifdef'd out; but, if it reports 
    a non-zero st_size (which works on some targets), use it.  
    If it fails, report 0.  Probably we should be using fstat64
    where it exists.

For the case of a socket, we could use a funny search after all the 
above has failed:  set the SO_RCVLOWAT socket option to increasing 
values until poll() reports "not ready", and then restore 
SO_RECVLOWAT and report the last "ready" value.  The problem is 
that since it reports "ready" at EOF, you can't trust it if it 
never reports "not ready".  So, if you get tired of quadrupling 
(e.g. you've hit 64K, seven calls) and still get "ready", try 
a really large value, e.g. 1<<24, -- and if it still reports ready 
you know it's at EOF, and you report -1; otherwise, just report the 
64K.

Note that setsockopt SO_RCVLOWAT (like ioctl) is not required by POSIX.

Of course it's up to you to decide how much work you want to put into 
supporting this; at whatever point you think you and library have
tried hard enough, return 0.

Nathan Myers
ncm-nospam at cantrip dot org


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]