shell file descriptor programming (was: Unlinked temp files)

Ubben Greg bink at aplcen.apl.jhu.edu
Sat May 6 18:55:43 AEST 1989


In article <4763 at ihlpe.ATT.COM> 452is-Kim writes:
>In article <10944 at 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<inputfile
	     read <&3 a b c
	     read <&3 a b c
	     ...
	     seek <&3        # rewind to start over
	     read <&3 a b c
	     exec 3<&-
	
	SEE ALSO
	     lseek(2), sh(1).

Both examples work on System V.2 Bourne shell, but only the first does on
this here Ultrix system under ksh.  Is this a good idea?  Problems?
Portability?

					-- Greg Ubben
					   bink at aplcen.apl.jhu.edu



More information about the Comp.unix.wizards mailing list