From c38dfac9ed6c1c3beb3dd88ebf82a13d1e561ff8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 22 May 2014 21:10:50 +0900 Subject: [PATCH] shared: add touch_file() and let touch() always update timestamp --- src/shared/util.c | 38 +++++++++++++++++++++++++++++++++----- src/shared/util.h | 1 + 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index c18d31dfc..83a674aa8 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -73,6 +73,7 @@ #include "log.h" #include "strv.h" #include "label.h" +#include "mkdir.h" #include "path-util.h" #include "exit-status.h" #include "hashmap.h" @@ -3344,22 +3345,49 @@ char *ellipsize(const char *s, size_t length, unsigned percent) { return ellipsize_mem(s, strlen(s), length, percent); } -int touch(const char *path) { +int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) { _cleanup_close_ int fd; + int r; assert(path); - /* This just opens the file for writing, ensuring it - * exists. It doesn't call utimensat() the way /usr/bin/touch - * does it. */ + if (parents) + mkdir_parents(path, 0755); - fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644); + fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644); if (fd < 0) return -errno; + if (mode > 0) { + r = fchmod(fd, mode); + if (r < 0) + return -errno; + } + + if (uid != (uid_t)-1 || gid != (gid_t)-1) { + r = fchown(fd, uid, gid); + if (r < 0) + return -errno; + } + + if (stamp != (usec_t)-1) { + struct timespec ts[2]; + + timespec_store(&ts[0], stamp); + timespec_store(&ts[1], stamp); + r = futimens(fd, ts); + } else + r = futimens(fd, NULL); + if (r < 0) + return -errno; + return 0; } +int touch(const char *path) { + return touch_file(path, false, -1, -1, -1, 0); +} + char *unquote(const char *s, const char* quotes) { size_t l; assert(s); diff --git a/src/shared/util.h b/src/shared/util.h index 7a7d15c82..62eb60402 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -478,6 +478,7 @@ char *ellipsize(const char *s, size_t length, unsigned percent); /* bytes columns */ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent); +int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode); int touch(const char *path); char *unquote(const char *s, const char *quotes); -- 2.30.2