util/nvmutil: proper /dev/fd search in fchmod

some systems may not even have it

works with /dev/fd (bsd/mac etc)

works with linux (/proc/self/fd)

and falls back on super old systems
that have neither

Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
Leah Rowe
2026-03-16 17:11:08 +00:00
parent 120241f1cf
commit 96dde65d16
+48 -25
View File
@@ -492,6 +492,10 @@ static void *x_v_memcpy(void *dst,
static int x_i_memcmp(const void *a, static int x_i_memcmp(const void *a,
const void *b, unsigned long n); const void *b, unsigned long n);
static int x_i_fchmod(int fd, mode_t mode); static int x_i_fchmod(int fd, mode_t mode);
static int x_try_fdpath(const char *prefix,
int fd, mode_t mode);
static unsigned long x_conv_fd(char *buf,
unsigned long n);
/* /*
* Sizes in bytes: * Sizes in bytes:
@@ -3180,38 +3184,57 @@ x_i_memcmp(const void *a, const void *b, unsigned long n)
static int static int
x_i_fchmod(int fd, mode_t mode) x_i_fchmod(int fd, mode_t mode)
{ {
char path[32]; if (x_try_fdpath("/dev/fd/", fd, mode) == 0)
char tmp[16]; return 0;
int i = 0;
int j = 0;
int n;
/* build "/dev/fd/" */ if (x_try_fdpath("/proc/self/fd/", fd, mode) == 0)
path[i++] = '/'; return 0;
path[i++] = 'd';
path[i++] = 'e';
path[i++] = 'v';
path[i++] = '/';
path[i++] = 'f';
path[i++] = 'd';
path[i++] = '/';
/* convert fd to decimal */ errno = ENOSYS;
n = fd; return -1;
}
if (n == 0) { static int
path[i++] = '0'; x_try_fdpath(const char *prefix, int fd, mode_t mode)
} else { {
while (n > 0) { char path[PATH_LEN];
tmp[j++] = (char)('0' + (n % 10));
n /= 10;
}
while (j > 0) unsigned long i = 0;
path[i++] = tmp[--j]; unsigned long j;
while (prefix[i]) {
path[i] = prefix[i];
i++;
} }
j = x_conv_fd(path + i, (unsigned long)fd);
i += j;
path[i] = '\0'; path[i] = '\0';
return chmod(path, mode); return chmod(path, mode);
} }
static unsigned long
x_conv_fd(char *buf, unsigned long n)
{
char tmp[256];
unsigned long i = 0;
unsigned long j = 0;
if (n == 0) {
buf[0] = '0';
return 1;
}
while (n > 0) {
tmp[i++] = (char)('0' + (n % 10));
n /= 10;
}
while (i > 0)
buf[j++] = tmp[--i];
return j;
}