sysfs 文件上的同步 I/O

sysfs 文件上的同步 I/O

我想保证我写入 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_writedo_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()也不会失败。 (虽然目前还没有发生,但这是报告某些错误的唯一方法,因此我希望为报告这些错误的时间做好准备。如果它们发生的话。)

相关内容