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