Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ncar!ames!indri!aplcen!bink From: bink@aplcen.apl.jhu.edu (Ubben Greg) Newsgroups: comp.unix.wizards Subject: Re: shell file descriptor programming (was: Unlinked temp files) Summary: seek.[c1] Keywords: seek rewind Message-ID: <1202@aplcen.apl.jhu.edu> Date: 6 May 89 08:55:43 GMT References: <871@marvin.Solbourne.COM> <1015@philmds.UUCP> <296@tree.UUCP> <4763@ihlpe.ATT.COM> Reply-To: bink@aplcen.apl.jhu.edu (Greg Ubben) Organization: The Johns Hopkins University, Baltimore MD Lines: 90 In article <4763@ihlpe.ATT.COM> 452is-Kim writes: >In article <10944@bloom-beacon.MIT.EDU> Steve Summit writes: >: extern long int atol(); >: main(argc, argv) int argc; char *argv[]; >: {lseek(atoi(argv[1]), atol(argv[2]), atoi(argv[3]);} >[...] >To use this program to rewind file descriptor 4, for example, you say: > > rewind <&4 > >I know it's not clean, but it works. I suppose you could have a shell script >front end that takes an actual argument instead of a redirection. On the contrary, I feel the UNIXy way of doing it IS to operate on stdin, and let the shell redirect if necessary. Here is the generalized seek program I put on our system after reading the previous postings: /* * seek.c * Performs an lseek on the standard input. * Greg Ubben, XXX, 2May89 */ static char what[] = "@(#) 2May89 seek.c gsubben"; static char usage[] = "Usage: seek [offset [whence]]\n"; extern long strtol(), lseek(); main (argc,argv) int argc; char *argv[]; { long offset = (argc>1 ? strtol(argv[1],&argv[1],0) : 0L); int whence = (argc>2 ? strtol(argv[2],&argv[2],10) : 0); if (argc>1 && *argv[1] || argc>2 && *argv[2] || argc>3) { write (2, usage, sizeof(usage)-1); exit (2); } if (lseek(0,offset,whence) < 0) { perror (argv[0]); exit (1); } exit (0); } It's already been used in a shell that needed to write to a dir-like data file. I'm sure there's problems with this, but I leave it as an exercise to find them. :-) It fails on bad whence values, as this isn't worth checking -- 0, 1, or 2 will always be hardcoded in the shells that use it. Here's a tenative man entry that gives some nifty examples: SEEK(1) NAME seek - exercise lseek system call SYNOPSIS seek [offset [whence]] DESCRIPTION Seek performs an lseek(2) to adjust the file pointer of standard input. Offset must be a decimal, octal (if it begins with 0), or hexadecimal (if it begins with 0x or 0X) integer. Whence must be 0, 1, or 2 to set the offset base at the beginning of the file, current location, or end of the file. Both arguments default to 0, causing no arguments to "rewind" the file. EXAMPLES (seek 25 && echo "OFFSET25\c") >>datafile <&1 exec 3