Subject: bin/774: compress interacts in unexpected way with fdesc filesystem
To: None <gnats-admin@NetBSD.ORG>
From: Brad Spencer <brad@anduin.eldar.org>
List: netbsd-bugs
Date: 02/01/1995 20:20:05
>Number: 774
>Category: bin
>Synopsis: compress interacts in unexpected way with fdesc filesystem
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Feb 1 20:20:03 1995
>Originator: Brad Spencer
>Organization:
" At home one day"
>Release: NetBSD-current around 1/30 or so
>Environment:
P90, NetBSD-current i386, standard stuff
System: NetBSD anduin.eldar.org 1.0A NetBSD 1.0A (ANDUIN) #0: Wed Feb 1 21:03:50 EST 1995 brad@anduin.eldar.org:/usr/src/sys/arch/i386/compile/ANDUIN i386
>Description:
The compress utility acts in an unexpected way with a fdesc
filesystem is union mounted with /dev and compress has had its
standard in and standard out redirected.
>How-To-Repeat:
Following the instructions in the mount_fdesc man page and union
mount said filesystem on /dev. Do the following:
cd /tmp
cp /etc/hosts hosts
compress < hosts > h.Z
At this point a message will me printed on stderr asking whether or
not '/dev/stdin' should be overwritten. Of course, one can not
answer this question, as stdin is currently the input file. And
nothing shows up in h.Z.
>Fix:
One might debate where the bug is actually located at, but the
reason for the interaction is because the fdesc filesystem symlinks
/dev/std* to /dev/fd/* which are files of the same type as the file
which is stdin, etc, be that a regular file, a pipe or tty. So, when
one redirects a regular file into compress, /dev/stdin suddenly
becomes a symlink to a regular file type. This effect causes a couple
of the checks in compress to pass, when they should not have.
Following is a diff which seems to cause compress to work correctly
when a fdesc is mounted as /dev.
*** compress.c.ORIG Sun Dec 25 06:26:26 1994
--- compress.c Wed Feb 1 10:16:32 1995
***************
*** 201,207 ****
exists = !stat(out, &sb);
if (!force && exists && S_ISREG(sb.st_mode) && !permission(out))
return;
! isreg = oreg = !exists || S_ISREG(sb.st_mode);
ifp = ofp = NULL;
if ((ifp = fopen(in, "r")) == NULL) {
--- 201,207 ----
exists = !stat(out, &sb);
if (!force && exists && S_ISREG(sb.st_mode) && !permission(out))
return;
! isreg = oreg = !exists || S_ISREG(sb.st_mode) && (strcasecmp(out,"/dev/stdout") != 0);
ifp = ofp = NULL;
if ((ifp = fopen(in, "r")) == NULL) {
***************
*** 212,218 ****
cwarn("%s", in);
goto err;
}
! if (!S_ISREG(isb.st_mode))
isreg = 0;
if ((ofp = zopen(out, "w", bits)) == NULL) {
--- 212,218 ----
cwarn("%s", in);
goto err;
}
! if ((!S_ISREG(isb.st_mode)) || (strcasecmp(in,"/dev/stdin") == 0))
isreg = 0;
if ((ofp = zopen(out, "w", bits)) == NULL) {
***************
*** 291,297 ****
exists = !stat(out, &sb);
if (!force && exists && S_ISREG(sb.st_mode) && !permission(out))
return;
! isreg = oreg = !exists || S_ISREG(sb.st_mode);
ifp = ofp = NULL;
if ((ofp = fopen(out, "w")) == NULL) {
--- 291,297 ----
exists = !stat(out, &sb);
if (!force && exists && S_ISREG(sb.st_mode) && !permission(out))
return;
! isreg = oreg = !exists || S_ISREG(sb.st_mode) && (strcasecmp(out,"/dev/stdout") != 0);
ifp = ofp = NULL;
if ((ofp = fopen(out, "w")) == NULL) {
***************
*** 307,313 ****
cwarn("%s", in);
goto err;
}
! if (!S_ISREG(sb.st_mode))
isreg = 0;
while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0)
--- 307,313 ----
cwarn("%s", in);
goto err;
}
! if ((!S_ISREG(sb.st_mode)) || (strcasecmp(in,"/dev/stdin") == 0))
isreg = 0;
while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0)
***************
*** 384,389 ****
--- 384,391 ----
if (!isatty(fileno(stderr)))
return (0);
+ if (!isatty(fileno(stdin)))
+ return (1);
(void)fprintf(stderr, "overwrite %s? ", fname);
first = ch = getchar();
while (ch != '\n' && ch != EOF)
>Audit-Trail:
>Unformatted: