On my machine stat returns size 22, but only 20 bytes are read:
openat(AT_FDCWD, "/sys/firmware/efi/efivars/LoaderTimeInitUSec-
4a67b082-0a4c-41cf-b6c7-
440b29bb8c4f", O_RDONLY|O_NOCTTY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=22, ...}) = 0
read(3, "\6\0\0\0", 4) = 4
read(3, "7\0001\0001\0003\0005\0002\0007\0\0\0", 18) = 16
Failed to read LoaderTimeInitUSec: Input/output error
Let's just accept that the kernel is returning inconsistent results.
It seems to happen two only two variables on my machine:
/sys/firmware/efi/efivars/LoaderTimeInitUSec-
4a67b082-0a4c-41cf-b6c7-
440b29bb8c4f
/sys/firmware/efi/efivars/LoaderTimeMenuUSec-
4a67b082-0a4c-41cf-b6c7-
440b29bb8c4f
so it might be related to the way we write them.
n = read(fd, buf, (size_t) st.st_size - 4);
if (n < 0)
return -errno;
- if (n != st.st_size - 4)
- return -EIO;
+ assert(n <= st.st_size - 4);
/* Always NUL terminate (2 bytes, to protect UTF-16) */
- ((char*) buf)[st.st_size - 4] = 0;
- ((char*) buf)[st.st_size - 4 + 1] = 0;
- }
+ ((char*) buf)[n - 4] = 0;
+ ((char*) buf)[n - 4 + 1] = 0;
+ } else
+ /* Assume that the reported size is accurate */
+ n = st.st_size - 4;
/* Note that efivarfs interestingly doesn't require ftruncate() to update an existing EFI variable
* with a smaller value. */
*ret_value = TAKE_PTR(buf);
if (ret_size)
- *ret_size = (size_t) st.st_size - 4;
+ *ret_size = n;
return 0;
}