easy way to determine if a stream or fd is seekable

Alexander Best arundel at freebsd.org
Thu Nov 17 09:59:51 UTC 2011


On Wed Nov 16 11, Tim Kientzle wrote:
> 
> On Nov 16, 2011, at 4:24 PM, Alexander Best wrote:
> 
> > On Thu Nov 17 11, Joerg Sonnenberger wrote:
> >> On Wed, Nov 16, 2011 at 01:14:28PM +0000, Alexander Best wrote:
> >>> On Wed Nov 16 11, Joerg Sonnenberger wrote:
> >>>> On Tue, Nov 15, 2011 at 08:24:50PM +0000, Alexander Best wrote:
> >>>>> one of the things i'm missing is an easy way to determine, whether a stream or
> >>>>> fd is seekable. i checked the dd(1) and hd(1) sources and those tools are
> >>>>> performing so much stuff just to find out if this is the case, and they still
> >>>>> are doing a very poor job.
> >>>> 
> >>>> Isn't the primary issue that FreeBSD doesn't properly report errors for
> >>>> lseek(2)? I think you should start from that and not hack around the
> >>>> fallout...
> >>> 
> >>> what do you mean? lseek(2) returns -1, when the file descriptor is not
> >>> seekable. i fired lseek(2) at all sorts of file types (dir, sockets, ...)
> >>> and it always returned the correct result.
> >> 
> >> If that were the case, you wouldn't need your flag to detect seek
> >> support. But e.g. some devices silently ignore seek requests without
> >> reporting errors. At least that is what I remember from the last time
> >> this has brought up.
> > 
> > this is the first time i hear about problems with seek requests. would be nice
> > to see some examples cases. was this discussed on the mailinglists? or
> > submitted as a problem report?
> 
> There was a version of bsdtar that made the mistake of assuming
> lseek() would return an error.
> 
> lseek() on a tape drive does not return an error, nor does it
> actually do anything.
> 
> After a few experiments, bsdtar stopped using lseek() on
> FreeBSD for anything other than regular files and block
> devices.   I believe there are other things that do support
> seeking, but I don't believe there is an accurate mechanism
> for determining whether lseek() is correctly supported.

dealing with tape drives wouldn't be that difficult. there's code in dd(1) e.g.
that identifies a file argument as D_TAPE or !D_TAPE via an ioctl() call.

if tapes are the only devices types that have issues with lseek(), this could
easily be dealt with.

i'll take a look at the bsdtar commit logs to find out where the exact problems
were. however i vote that the lseek(2) and also fseek(3) should have their
"BUGS" section extended with a description for the issue(s) that exist.

might the problem with lseek() be related to this bug report?

http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/60313

cheers.
alex

ps: since i've never worked with tape: what file type does it identify as?
character special file, or block special file, or ...?

> 
> Tim


More information about the freebsd-hackers mailing list