Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!ames!pacbell!att!mcdchg!mcdphx!estinc!fnf From: fnf@estinc.UUCP (Fred Fish) Newsgroups: comp.unix.questions Subject: Re: sparse files Message-ID: <249@estinc.UUCP> Date: 18 Dec 89 04:08:57 GMT References: <21581@adm.BRL.MIL> <235@dg.dg.com> <2700@auspex.auspex.com> <244@estinc.UUCP> <21261@mimsy.umd.edu> Reply-To: fnf@estinc.UUCP (Fred Fish) Organization: Enhanced Software Technologies, Inc. Lines: 35 In article <21261@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes: >This code is not sufficient. In particular, a file that ends in >an `allnulls' block will come out too short. In older Unix systems, >the following is required: > ... >Note, however, that the 4.2BSD and 4.3BSD `restore' programs have the >very same bug that this article is about: if a file ends in a hole, >the restored version of the file will have the trailing hole omitted. >For this reason, the first version---write(fd,"",1)---may be preferable. Chris (along with the dozen or so people that emailed me about my example) is of course 100% correct. My example was misleading because I edited it quite heavy, and in the course of such, broke it with respect to the trailing hole bug. The actual code (unedited) is: if (bytes > DATASIZE && flags.Sflag && allnulls (blkp -> FD, (int) wbytes)) { if (s_lseek (fildes, (S32BIT) wbytes, 1) == SYS_ERROR) { bru_message (MSG_SEEK, fname); iobytes = s_write (fildes, blkp -> FD, wbytes); } else { iobytes = wbytes; } } else { iobytes = s_write (fildes, blkp -> FD, wbytes); } where of course the seek is only done when there is at least one more buffer full of data (besides the current one) to be written to the file and the -S flag was given. -Fred -- # Fred Fish, 1835 E. Belmont Drive, Tempe, AZ 85284, USA # 1-602-491-0048 asuvax!{nud,mcdphx}!estinc!fnf