From owner-freebsd-hackers@FreeBSD.ORG Tue Nov 15 20:24:50 2011 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 1233) id 54046106566C; Tue, 15 Nov 2011 20:24:50 +0000 (UTC) Date: Tue, 15 Nov 2011 20:24:50 +0000 From: Alexander Best To: freebsd-hackers@freebsd.org Message-ID: <20111115202450.GA73512@freebsd.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: easy way to determine if a stream or fd is seekable X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Nov 2011 20:24:50 -0000 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