Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!iuvax!cica!ctrsol!lll-winken!uunet!auspex!guy From: guy@auspex.auspex.com (Guy Harris) Newsgroups: comp.bugs.sys5 Subject: Re: Bug in pg - doesn't close directories Keywords: pg open files directory Message-ID: <2221@auspex.auspex.com> Date: 12 Jul 89 17:35:28 GMT References: <5941@wolfen.cc.uow.oz> Reply-To: guy@auspex.auspex.com (Guy Harris) Organization: Auspex Systems, Santa Clara Lines: 89 > 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); }