-1

我在下面写了代码

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main() {

    int fd = 3;
    char c[100] = "Testing\n";
    ssize_t nbytes = write(fd, (void *) c, strlen(c));
    return 0;
}

编译/链接,并执行

$ ./io
$ ./io 3> io_3.txt

第一行没有输出。第二行给了我io_3.txt包含Testing. 这都是预期的行为(我猜)。

即使在我的测试中它产生了预期的输出,我也不确定是否为了避免潜在的问题、未定义的行为等,我应该在第一个之前做任何事情write,比如检查是否fd=3正在使用(在这种情况下,如何...可能适用),如果它是适当的开放等。

write出于同样的原因,我不确定是否应该在 last 之后执行一些操作。

也许我所做的方式是“无风险的”,唯一的潜在问题是没有写入任何内容,我可以通过检查nbytes... 我不知道的值来检测。

欢迎任何澄清。

4

1 回答 1

4

如果您编写这样的程序,在没有 fd 3 open 的情况下执行它是一个使用错误。通常,在没有自己打开它们的情况下,唯一应该按数字使用的文件描述符是 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] = "Testing\n";
    ssize_t nbytes = write(fd, (void *) c, strlen(c));
    return 0;
}

在实践中,如果 fd 3 没有打开,像你这样的简单程序可能是安全的,写入失败。但是,一旦您执行任何可能打开文件描述符的操作(可能是实现内部的,例如syslog打开时区数据的日期/时间函数或消息翻译目录等),fd 3 现在可能会引用这样的打开文件,并且您错误地尝试对其进行写入。像这样使用文件描述符是一个严重的错误。

于 2020-05-18T20:48:32.980 回答