diff --git a/src/basic/efivars.c b/src/basic/efivars.c index 43f498de0f..8470d085c7 100644 --- a/src/basic/efivars.c +++ b/src/basic/efivars.c @@ -239,10 +239,7 @@ int efi_set_variable(const char *variable, const void *value, size_t size) { /* For some reason efivarfs doesn't update mtime automatically. Let's do it manually then. This is * useful for processes that cache EFI variables to detect when changes occurred. */ - if (futimens(fd, (const struct timespec[2]) { - { .tv_nsec = UTIME_NOW }, - { .tv_nsec = UTIME_NOW } - }) < 0) + if (futimens(fd, /* times = */ NULL) < 0) log_debug_errno(errno, "Failed to update mtime/atime on %s, ignoring: %m", p); r = 0; diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 7f0b5814be..b3d5e8a07d 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -325,12 +325,22 @@ int fchmod_opath(int fd, mode_t m) { int futimens_opath(int fd, const struct timespec ts[2]) { /* Similar to fchmod_opath() but for futimens() */ - if (utimensat(AT_FDCWD, FORMAT_PROC_FD_PATH(fd), ts, 0) < 0) { + assert(fd >= 0); + + if (utimensat(fd, "", ts, AT_EMPTY_PATH) >= 0) + return 0; + if (errno != EINVAL) + return -errno; + + /* Support for AT_EMPTY_PATH is added rather late (kernel 5.8), so fall back to going through /proc/ + * if unavailable. */ + + if (utimensat(AT_FDCWD, FORMAT_PROC_FD_PATH(fd), ts, /* flags = */ 0) < 0) { if (errno != ENOENT) return -errno; if (proc_mounted() == 0) - return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ + return -ENOSYS; return -ENOENT; } @@ -405,17 +415,14 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi ret = fchmod_and_chown(fd, mode, uid, gid); if (stamp != USEC_INFINITY) { - struct timespec ts[2]; + struct timespec ts; + timespec_store(&ts, stamp); - timespec_store(&ts[0], stamp); - ts[1] = ts[0]; - r = futimens_opath(fd, ts); + r = futimens_opath(fd, (const struct timespec[2]) { ts, ts }); } else - r = futimens_opath(fd, NULL); - if (r < 0 && ret >= 0) - return r; + r = futimens_opath(fd, /* ts = */ NULL); - return ret; + return RET_GATHER(ret, r); } int symlink_idempotent(const char *from, const char *to, bool make_relative) { diff --git a/src/login/pam_systemd_loadkey.c b/src/login/pam_systemd_loadkey.c index 2e65d60608..3b11d76453 100644 --- a/src/login/pam_systemd_loadkey.c +++ b/src/login/pam_systemd_loadkey.c @@ -18,7 +18,7 @@ * This can be overridden by the keyname= parameter. */ static const char DEFAULT_KEYNAME[] = "cryptsetup"; -_public_ int pam_sm_authenticate( +_public_ PAM_EXTERN int pam_sm_authenticate( pam_handle_t *handle, int flags, int argc, const char **argv) { @@ -91,7 +91,7 @@ _public_ int pam_sm_authenticate( return PAM_SUCCESS; } -_public_ int pam_sm_setcred( +_public_ PAM_EXTERN int pam_sm_setcred( pam_handle_t *handle, int flags, int argc, const char **argv) {