我想保证我写入 sysfs 文件(特别是文件/sys/class/gpio
)的内容同步到实际寄存器。我最初使用该标志打开文件的代码O_SYNC
,我认为是这样做的。然而,在另一段代码中,我尝试使用fsync()
,但它因 EINVAL 失败,并man fsync
告诉我:
EROFS, EINVAL
fd is bound to a special file which does not support synchronization
我已经检查了 sysfs 文件上可能的操作的代码,但没有找到任何类型的do_sync_write
或do_fsync
函数。
那么,该O_SYNC
标志在打开 sysfs 文件时有什么作用吗?open
尝试打开不支持同步读/写的文件时不应返回错误代码O_SYNC
?
问候,
吉列尔梅
答案1
/系统是一个完全基于 RAM 的文件系统,用于访问内核数据结构。这包括通用输入输出接口接口。
您所需要做的就是正常打开伪文件,并使用单次写入来写入数据。如果成功,并且所有数据(可能除了任何尾随空格(如换行符))都已写入,则内核向您保证它已接受所有数据。换句话说:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define GPIO_EXPORT_PATH "/sys/class/gpio/export"
static int gpio_export(int pin)
{
char buffer[32];
ssize_t written;
int fd;
char *const q = buffer + sizeof buffer;
char *p = buffer + sizeof buffer;
if (pin < 0)
return errno = EINVAL;
*(--p) = '\n';
do {
*(--p) = '0' + (pin % 10);
pin /= 10;
} while (pin > 0);
do {
fd = open(GPIO_EXPORT_PATH, O_WRONLY);
} while (fd == -1 && errno == EINTR);
if (fd == -1)
return errno;
do {
written = write(fd, p, (size_t)(q - p));
} while (written == -1 && errno == EINTR);
if (written == -1) {
const int saved_errno = errno;
close(fd);
return errno = saved_errno;
}
if (close(fd))
return errno;
/* Not all written?
* It is okay if the last char, '\n' was not written. */
if (written != (ssize_t)(q - p) &&
written != (ssize_t)(q - 1 - p))
return errno = EIO; /* Partial write, data not accepted! */
return errno = 0;
}
请注意,当我们执行 时write()
,我们会验证是否已写入所有字符(尾随换行符除外)。这就是您需要的原子性要求。我也喜欢小心,并验证是否close()
也不会失败。 (虽然目前还没有发生,但这是报告某些错误的唯一方法,因此我希望为报告这些错误的时间做好准备。如果它们发生的话。)