easy way to determine if a stream or fd is seekable

Alexander Best arundel at freebsd.org
Tue Nov 15 20:24:50 UTC 2011


hi there,

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.

dd(1) e.g. identifies /dev/zero as non-seekable, even though it is. the result:

`dd if=/dev/zero bs=1m count=1 skip=100000`:

on freebsd:
57,41 real         0,05 user        43,21 sys

on openbsd:
0,88 real         0,00 user         0,07 sys

on freebsd dd(1) is very easy fixable (1 line diff). the point however is:

there doesn't seem to exist a unified way of checking seekable == TRUE. so
every userspace application seems to do it differently and most of them (dd(1)
and hd(1) e.g) aren't doing it right. hd(1) e.g. believes that only regular
files are seekable. this means that hd(1) fired at /dev/ada* with a high skip
value takes ages! dd(1) is a bit smarter in this case, but still not correct.

idealy there would be something like stat.st_mode (see stat(2)) where one
could simply do a S_ISSEEK(m). so far the best and easiest solution i've seen
is:

fd = open(argv[1], O_RDONLY);
if (fd == -1)
   exit(1);
if (lseek(fd, 0, SEEK_CUR) != -1)
    printf ("%d is seekable.\n", fd);
else
    printf ("%d is not seekable.\n", fd);

seeing an application iterate through a stream or fd via getchar(), although
a simple seek() would work is very frustrating. i think what would be needed
is a simple function or macro that userspace applications can make use of.
maybe such a thing already exists in linux, openbsd, netbsd, dragonflybsd,
solaris or plan9?

cheers.
alex

references:
[1] http://www.mavetju.org/mail/view_thread.php?list=freebsd-hackers&id=3290708&thread=yes
[2] http://www.freebsd.org/cgi/query-pr.cgi?pr=152485
[3] http://www.freebsd.org/cgi/query-pr.cgi?pr=86485


More information about the freebsd-hackers mailing list