我在下面写了代码
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
int fd = 3;
char c[100] = "Testingn";
ssize_t nbytes = write(fd, (void *) c, strlen(c));
return 0;
}
编译/链接和执行
$ ./io
$ ./io 3> io_3.txt
第一行没有产生任何输出。第二行给了我包含Testing
的文件io_3.txt
。 这都是预期的行为(我猜(。
即使在我的测试中它产生了预期的输出, 我不确定为了避免潜在的问题、未定义的行为等,我是否应该在第一次write
之前做任何事情,比如检查fd=3
是否正在使用中(在这种情况下,如何......这可能适用(,如果它适当开放等。
出于同样的原因,我不确定我是否应该在最后一次write
之后执行一些操作。
也许我这样做的方式是"无风险的",唯一的潜在问题是没有写入任何内容,我可以通过检查nbytes
的值来检测......我不知道。
欢迎任何澄清。
如果你写这样的程序,在没有打开 fd 3 的情况下执行它是一个使用错误。通常,唯一应该按数字使用而不自己打开的文件描述符是 0(stdin(、1(stdout(和 2(stderr(。如果程序需要将其他预打开的文件描述符作为输入,则标准习惯用法是在命令行或环境变量上传递 fd 编号,而不是对它们进行硬编码。例如:
int main(int argc, char **argv) {
if (argc<2 || !isdigit(argv[1][0])) return 1;
int fd = strtol(argv[1], 0, 0);
char c[100] = "Testingn";
ssize_t nbytes = write(fd, (void *) c, strlen(c));
return 0;
}
在实践中,像您这样的琐碎程序可能是安全的,如果 fd 3 未打开,写入就会失败。但是,一旦您执行任何可能打开文件描述符的操作(可能是实现的内部描述符,例如syslog
,或打开时区数据的日期/时间函数,或消息翻译目录等(,fd 3 现在可能会引用这样一个打开的文件,并且您错误地尝试写入它。像这样使用文件描述符是一个严重的错误。