From owner-freebsd-hackers@FreeBSD.ORG Thu Nov 17 20:49:35 2011 Return-Path: Delivered-To: freebsd-hackers@FreeBSD.org Received: by hub.freebsd.org (Postfix, from userid 1233) id 27E1A106567A; Thu, 17 Nov 2011 20:49:35 +0000 (UTC) Date: Thu, 17 Nov 2011 20:49:35 +0000 From: Alexander Best To: freebsd-hackers@FreeBSD.org Message-ID: <20111117204935.GA68820@freebsd.org> References: <20111117175514.274040@gmx.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20111117175514.274040@gmx.com> Cc: 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: Thu, 17 Nov 2011 20:49:35 -0000 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. i took a look at the bsdtar sources and before the lseek() a function called test_for_append() is run. apart from other things it will do the following: if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode)) lafe_errc(1, 0, "Cannot append to %s: not a regular file.", bsdtar->filename); but again this is too restrictive. take a look at /dev/zero e.g.: otaku% ./mode /dev/zero Block special file: 0 Character special file: 1 Directory: 0 Pipe or FIFO special file: 0 Symbolic link: 0 Regular file: 0 Socket: 0 Whiteout: 0 Seekable: 1 it is not regular file and no block special file, so bsdtar will bail out for no reason! i think there are two possibilities: 1) add code to lseek() that will return -1 for all tape drives. 2) deal with those tape drives that don't support seeking individually. identifying a tape drive is easy. here's dd's code snippet: if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) { if (ioctl(io->fd, FIODTYPE, &type) == -1) err(1, "%s", io->name); if (type & D_TAPE) io->flags |= ISTAPE; } this could be added to lseek() and when "type & D_TAPE" == TRUE, then we could return -1. this would be method 1). no idea how to fix this issue using method 2) though. probably driving into the driver code of the according tape drives. cheers. alex ps: thanks to nox@ for pointing me to the initial thread, where this issue was discussed [1]. however the purpose of that thread was mainly fixing libarchive/bsdtar and not so much really fixing the issue at hand. also i'll consider re-opening problem report [2], wince this was never really fixed. [1] http://markmail.org/message/n6tp5dbv7sbzzujc [2] http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/60313 > > It might be that FreeBSD doesn't currently support seeking > on a tape, but we shouldn't paint ourselves into a corner > by assuming that it is fundimentally impossible.