Bug in pg - doesn't close directories

Guy Harris guy at auspex.auspex.com
Thu Jul 13 03:35:28 AEST 1989


>	When pg encounters a directory in its argument list it prints
>out a message to that effect and moves on to the next argument.
>Unfortunately it does not close the directory and eventually runs
>out of file descriptors.

It's even worse than that.  First of all, its check for "is this a
directory" is wrong - S_IFDIR is *NOT* a flag bit, it's a value for a
bit field, so the proper test is "(statb.st_mode & S_IFMT) == S_IFDIR",
not "(statb.st_mode & S_IFDIR)" - and second of all, it won't close the
descriptor if some other tests fail, either.

A fix to the S5R3.1 version:

*** pg.c.orig	Wed Jul 12 10:23:31 1989
--- pg.c	Wed Jul 12 10:33:37 1989
***************
*** 914,919 ****
--- 914,920 ----
  	struct stat stbuf;
  	register FILE *f;
  	int fd;
+ 	int f_was_opened;
  
  	pipe_in = 0;
  	if (strcmp(fs,"-") == 0) {
***************
*** 923,928 ****
--- 924,930 ----
  			rewind(tmp_fin);
  			f = tmp_fin;
  		}
+ 		f_was_opened = 0;
  	}
  	else {
  		if ((f=fopen(fs, "r")) == (FILE *)NULL) {
***************
*** 930,951 ****
  			perror(fs);
  			return ((FILE *)NULL);
  		}
  	}
  	if (fstat(fileno(f), &stbuf) == -1) {
  		(void) fflush(stdout);
  		perror(fs);
  		return ((FILE *)NULL);
  	}
! 	if (stbuf.st_mode & S_IFDIR) {
  		(void) fprintf(stderr,"pg: %s is a directory\n",fs);
  		return ((FILE *)NULL);
  	}
! 	if (stbuf.st_mode & S_IFREG) {
  		if (f == stdin)		/* It may have been read from */
  			rewind(f);	/* already, and not reopened  */
  	}
  	else {
  		if (f != stdin) {
  			(void) fprintf(stderr,"pg: special files only handled as standard input\n");
  			return((FILE *)NULL);
  		}
--- 932,960 ----
  			perror(fs);
  			return ((FILE *)NULL);
  		}
+ 		f_was_opened = 1;
  	}
  	if (fstat(fileno(f), &stbuf) == -1) {
+ 		if (f_was_opened)
+ 			(void) fclose(f);
  		(void) fflush(stdout);
  		perror(fs);
  		return ((FILE *)NULL);
  	}
! 	if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
! 		if (f_was_opened)
! 			(void) fclose(f);
  		(void) fprintf(stderr,"pg: %s is a directory\n",fs);
  		return ((FILE *)NULL);
  	}
! 	if ((stbuf.st_mode & S_IFMT) == S_IFREG) {
  		if (f == stdin)		/* It may have been read from */
  			rewind(f);	/* already, and not reopened  */
  	}
  	else {
  		if (f != stdin) {
+ 			if (f_was_opened)
+ 				(void) fclose(f);
  			(void) fprintf(stderr,"pg: special files only handled as standard input\n");
  			return((FILE *)NULL);
  		}



More information about the Comp.bugs.sys5 mailing list