This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Toward a satisfactory showmanyc
- From: Nathan Myers <ncm-nospam at cantrip dot org>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Date: Thu, 20 Mar 2003 15:21:23 -0800
- Subject: Re: Toward a satisfactory showmanyc
- References: <3E7A1BFE.8000408@unitus.it>
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