From owner-freebsd-hackers@FreeBSD.ORG Fri Nov 18 20:53:26 2011 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 1233) id 1BFD51065672; Fri, 18 Nov 2011 20:53:25 +0000 (UTC) Date: Fri, 18 Nov 2011 20:53:25 +0000 From: Alexander Best To: Tim Kientzle Message-ID: <20111118205325.GA12245@freebsd.org> References: <20111117175514.274040@gmx.com> <20111117214805.GA96937@freebsd.org> <34A2877A-977A-4668-8E37-642C6062AAC1@kientzle.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <34A2877A-977A-4668-8E37-642C6062AAC1@kientzle.com> Cc: freebsd-hackers@freebsd.org Subject: Re: 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: Fri, 18 Nov 2011 20:53:26 -0000 On Fri Nov 18 11, Tim Kientzle wrote: > On Nov 17, 2011, at 1:48 PM, Alexander Best wrote: > > > On Thu Nov 17 11, Dieter BSD wrote: > >>> lseek() on a tape drive does not return an error, nor does it > >>> actually do anything. > >> > >> IIRC some tape drives can seek, while others cannot. > >> Vague memories that it is supposed to be possible to put a > >> filesystem on a DECtape and mount the filesystem. > > > > or how about the following: > > > > 1) if the file argument we're seeking on is a tape drive, just do a regular > > seek operation. > > 2) afterwards use ftell() to verify that the seek REALLY happend. if it didn't, > > return -1 and set errno = EBADF. > > ftell() can't tell whether the seek really happened or not. > All it can do is ask the kernel, and the kernel doesn't know. > > Here is my current understanding: > > When you call lseek(), the kernel just stores the requested > offset in the file descriptor. lseek() always succeeds because > storing the requested offset in the file descriptor always succeeds. > (Except that the kernel specially checks if the file descriptor > is a pipe.) > > ftell() just obtains the data from the file descriptor. > So it always succeeds and always returns the data from > the previous seek request, regardless of whether that seek > actually did anything. > > With the next read or write request, the device driver may inspect the > offset information in the file descriptor. Or it can ignore > it. Almost all tape device drivers ignore it. Filesystems > uniformly support it. Disk drivers uniformly support it. > Other drivers vary considerably. > > In short: No, there is no "easy way" to determine if an > arbitrary stream or fd is seekable. If you try to create > a function that determines this, be certain to include > "Don't Know" as a possible return value. well it really depends what the goal is. it appears fixing fseek() for all cases is impossible then. however from a pragmatic point of view: why does a user have to wait for a command such as hd(1) or dd(1) working on files such as /dev/zero, /dev/null, /dev/(u)random or even /dev/ada* (only hd(1) -- dd(1) supports seeking here) for ages, although it could suceed in less than a second? the fact is: users care for speed and freebsd is slower than linux and openbsd in these cases. users aren't interested in the fact that lseek() won't work with tapes. most of them have probably never seen one (me included). if we return an error from within lseek() whenever lseek() was fired at a tape drive, wouldn't that cover 99% of all the possible cases? cheers. alex > > Tim