Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 写入(fd,…)之前是否需要任何操作,。。。?_C_File Descriptor_Write - Fatal编程技术网

C 写入(fd,…)之前是否需要任何操作,。。。?

C 写入(fd,…)之前是否需要任何操作,。。。?,c,file-descriptor,write,C,File Descriptor,Write,我在下面写了代码 #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_3.txt包含测试。 我

我在下面写了代码

#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_3.txt
包含
测试
。 我想这都是意料之中的行为

即使在我的测试中它产生了预期的输出, 我不确定,为了避免潜在问题、未定义的行为等,我是否应该在第一次
写入之前做任何事情,比如检查
fd=3
是否在使用中(以及在这种情况下,如何应用),它是否适当打开,等等

出于同样的原因,我不确定我是否应该在最后一次写
之后执行某些操作

也许我这样做的方式是“无风险的”,唯一的潜在问题是什么都没有写,我可以通过检查
nbytes
的值来检测到……我不知道


欢迎任何澄清。

如果您编写这样的程序,在没有打开fd 3的情况下执行它是一个使用错误。通常,只有0(标准输入)、1(标准输出)和2(标准输出)才应该按数字使用,而不必自己打开它们。如果程序需要使用其他预打开的文件描述符作为输入,标准习惯用法是在命令行或环境变量上传递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;
}
int main(int argc,char**argv){

如果(argcYou必须传递一个打开的文件描述符。因此,通常您会使用
open
socket
,或任何其他有效的文件描述符。在这种情况下,您需要依靠shell解释器在执行程序之前为您执行一些魔术。这是不可移植的。没有带有未打开的filedescriptor参数的UB.Syscalls返回
EBADF
。检查错误(负返回值和错误号)将fd 3重定向到一个文件是可以的。但是如果fd没有打开进行写入,errno设置为@PSkocik-Right!!即使文本实际写入重定向目标,nbytes设置为-1,errno设置为EBADF.Great。据我所知,您的扩展代码从argv获取fd编号,但在其他情况下仍然写入fd which不一定是开放的,因此可能存在与您描述的相同的问题。这是否正确?是的,这是正确的。您可以进行探测(例如,使用
fcntl(fd,F_GETFD)
)在执行任何其他操作之前,fd是否很早就坏了,并在错误输入时出错。但对于一个非平凡的程序来说,这变得更难做到,因为该程序可能会让构造函数执行导致文件描述符打开的操作。通常情况下,除非它是安全边界(例如suid程序)我相信打电话的人会遵守合同。
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;
}