【发布时间】:2021-01-28 15:56:11
【问题描述】:
我正在尝试了解直接 I/O。为此,我编写了这个小玩具代码,它只是应该打开一个文件并向其中写入一个文本字符串:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv) {
char thefile[64];
int fd;
char message[64]="jsfreowivanlsaskajght";
sprintf(thefile, "diotestfile.dat");
if ((fd = open(thefile,O_DIRECT | O_RDWR | O_CREAT, S_IRWXU)) == -1) {
printf("error opening file\n");
exit(1);
}
write(fd, message, 64);
close(fd);
}
我的 Cray 和 GNU 编译命令是
cc -D'_GNU_SOURCE' diotest.c
对于英特尔来说是
cc -D'_GNU_SOURCE' -xAVX diotest.c
在所有三个编译器下,文件 diotestfile.dat 都是以正确的权限创建的,但从未向其中写入任何数据。可执行文件完成后,输出文件为空白。 O_DIRECT 是罪魁祸首(或者,更准确地说,我猜是我对O_DIRECT 的错误处理)。如果我把它拿出来,代码就可以正常工作。我在尝试使用的更复杂的代码中看到了同样的问题。我需要做些什么不同的事情?
【问题讨论】:
-
使用
O_DIRECT时,文件偏移量和读写长度通常会有对齐限制。您系统上的open函数的手册页有望描述详细信息,这些详细信息可能因操作系统和文件系统类型而异。 -
最有可能 write 返回 -1 但您没有检查错误。
-
那么什么是errno?
-
@bob.sacamento 问题是,在
write返回-1 之后,errno是什么?也就是说,perror()或strerror(errno)返回了什么?这些是需要了解的重要功能:它们确实试图告诉你失败的原因,而不仅仅是那个无意义的 -1。 -
@bob.sacamento 系统调用的返回值是not errno。
errno是一个特殊的其他变量;它曾经是一个预定义的全局变量。你想#include <errno.h>,然后,从字面上看,打电话给strerror(errno)。