抄的书上的代码。
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/syscall.h>
#include <sys/times.h>
#include <unistd.h>
extern int errno;
void
perror_and_exit (const char *msg)
{
perror (msg);
exit (errno);
}
int
main (int argc, char **argv)
{
int val;
if (argc != 2)
{
fputs ("usage: a.out <descriptor#>\n", stderr);
exit (1);
}
if ((val = fcntl (atoi (argv[1]), F_GETFL, 0)) < 0)
{
int ec = errno;
fprintf (stderr, "fcntl error for fd %d: %s", atoi (argv[1]),
strerror (ec));
exit (ec);
}
switch (val & O_ACCMODE)
{
case O_RDONLY:
printf ("read only");
break;
case O_WRONLY:
printf ("write only");
break;
case O_RDWR:
printf ("read write");
break;
default:
perror_and_exit ("unknown access mode");
}
if (val & O_APPEND)
printf (", append");
if (val & O_NONBLOCK)
printf (", nonblocking");
if (val & O_SYNC)
printf (", synchronous writes");
#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC)
if (val & O_FSYNC)
printf (", synchronous writes");
#endif
putchar ('\n');
exit (0);
}
非常惊讶的是,Linux 上 Bash 给应用程序分配的标准输入、输出、错误流都是可读可写的。似乎 Bash 是把当前的打字机设备(tty)打开并分配给了应用程序的三个标准流,因为 /proc/<pid>/fd/0
(和其他两个)都是链接到了 /dev/pts/5
上,而这个设备是我当前的终端。
$ /data/apue/build/apue 0
read write
$ /data/apue/build/apue 1
read write
$ /data/apue/build/apue 2
read write
$ /data/apue/build/apue 0 <A.txt
read only
$ /data/apue/build/apue 0 <>A.txt
read write
$ /data/apue/build/apue 5 5<>B.txt
read write
注意 Bash 中 /data/apue/build/apue 5 5<>B.txt
这种重定向,它把 5 号文件描述符分配给了 B.txt 文件,而且是用可写的方式打开。因为这里有写方式打开,所以 B.txt 不存在时会自动创建,如果是只读方式打开,那么 B.txt 不存在就会报错。