nsec_t now_nsec(clockid_t clock_id) { struct timespec ts; assert_se(clock_gettime(clock_id, &ts) == 0); return timespec_load_nsec(&ts); }
static int apply_timestamp(const char *path, struct timespec *ts) { struct timespec twice[2] = { *ts, *ts }; int fd = -1; _cleanup_fclose_ FILE *f = NULL; int r; assert(path); assert(ts); /* * We store the timestamp both as mtime of the file and in the file itself, * to support filesystems which cannot store nanosecond-precision timestamps. * Hence, don't bother updating the file, let's just rewrite it. */ r = mac_selinux_create_file_prepare(path, S_IFREG); if (r < 0) return log_error_errno(r, "Failed to set SELinux context for %s: %m", path); fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); mac_selinux_create_file_clear(); if (fd < 0) { if (errno == EROFS) return log_debug("Can't create timestamp file %s, file system is read-only.", path); return log_error_errno(errno, "Failed to create/open timestamp file %s: %m", path); } f = fdopen(fd, "w"); if (!f) { safe_close(fd); return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", path); } (void) fprintf(f, "%s" "TimestampNSec=" NSEC_FMT "\n", MESSAGE, timespec_load_nsec(ts)); fflush(f); if (futimens(fd, twice) < 0) return log_error_errno(errno, "Failed to update timestamp on %s: %m", path); return 0; }