Jari Aalto dixit:
>That is an incorrect reasoning. The POSIX standard mandates:
[…]
>The shell scripts are executed in context of <file>. The POSIX standard
>specifically requires the context to be a readabale in order to run the
>instructions.
Yes, but SUSv4 doesn’t say (or I could not find it) explicitly what
to do with directories.
>It would be helpful to report this cat(1) bug to the OS you had used for
>testing.
mksh is part of MirBSD.
In UNIX®, everything is a file. This is a mantra. Directories
are files. See also the attached source code, which outputs
this on MirBSD:
t...@bleu:~ $ ./a.out
open successful: 3
close: 0
There are even operating systems where you can read from directories:
mirabi...@stargazer:~ $ ./a.out
open successful: 3
read 512 bytes
close: 0
mirabi...@stargazer:~ $ uname -a
MidnightBSD stargazer.midnightbsd.org 0.3-CURRENT MidnightBSD 0.3-CURRENT #4:
Wed Jun 10 16:14:19 EDT 2009
r...@stargazer.midnightbsd.org:/usr/obj/usr/src/sys/GENERIC i386
Of course, this leads to interesting things:
mirabi...@stargazer:~ $ mksh /
/[1]: syntax error: '^B^L^D^Cvar$D^B^P^D^Dhome�$X�^T^A^L^D^Cetc' unexpected
But this is not an error, since:
OPEN(2) BSD Programmer's Manual OPEN(2)
NAME
open - open or create a file for reading or writing
Apparently, the open(2) syscall operates in the very same file context
as the shell does, but it succeeds to open directories. Thus, directo-
ries *are* files even for the shell context, *unless* this gets chan-
ged in open(2), which is most unlikely.
Please provide a better reasoning if you want this behaviour changed ☺
bye,
//mirabilos
--
[...] if maybe ext3fs wasn't a better pick, or jfs, or maybe reiserfs, oh but
what about xfs, and if only i had waited until reiser4 was ready... in the be-
ginning, there was ffs, and in the middle, there was ffs, and at the end, there
was still ffs, and the sys admins knew it was good. :) -- Ted Unangst über *fs
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
char buf[4096];
int
main(void)
{
int fd;
ssize_t n;
if ((fd = open("/", O_RDONLY)) < 0)
err(1, "open");
printf("open successful: %d\n", fd);
while ((n = read(fd, buf, sizeof(buf)))) {
if (n == -1) {
if (errno == EAGAIN)
continue;
err(1, "read");
}
printf("read %zd bytes\n", n);
}
fd = close(fd);
printf("close: %d\n", fd);
return (fd == 0 ? 0 : 1);
}