Synchronization

sysfs 文件上的同步 I/O

  • April 1, 2016

我想保證我寫入 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

問候,

威廉

/sys是一個完全基於 RAM 的文件系統,用於訪問核心資料結構。這包括GPIO介面。

您需要做的就是正常打開偽文件,並使用一次寫入來寫入數據。如果它成功了,並且所有的數據(除了可能的任何尾隨空格,比如換行符)都被寫入,核心向你保證它已經接受了所有的數據。換句話說:

#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()也不會失敗。(雖然它目前沒有發生,但它是報告某些錯誤的唯一方法,所以我希望為報告這些錯誤的時間做好準備。如果它們發生了。)

引用自:https://unix.stackexchange.com/questions/273634