chiark / gitweb /
shared: add touch_file() and let touch() always update timestamp
authorKay Sievers <kay@vrfy.org>
Thu, 22 May 2014 12:10:50 +0000 (21:10 +0900)
committerKay Sievers <kay@vrfy.org>
Fri, 23 May 2014 23:21:11 +0000 (07:21 +0800)
src/shared/util.c
src/shared/util.h

index c18d31dfcf96fd10439a6d838ba321589f36f843..83a674aa8b16ba5e141f1d5aa97cdc145d497c6d 100644 (file)
@@ -73,6 +73,7 @@
 #include "log.h"
 #include "strv.h"
 #include "label.h"
 #include "log.h"
 #include "strv.h"
 #include "label.h"
+#include "mkdir.h"
 #include "path-util.h"
 #include "exit-status.h"
 #include "hashmap.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);
 }
 
         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;
         _cleanup_close_ int fd;
+        int r;
 
         assert(path);
 
 
         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 (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;
 }
 
         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);
 char *unquote(const char *s, const char* quotes) {
         size_t l;
         assert(s);
index 7a7d15c82c39638c5925ea910cce19377d80d165..62eb60402d507a8260b6dcb69741cc44b820830f 100644 (file)
@@ -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);
 
                                    /* 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);
 int touch(const char *path);
 
 char *unquote(const char *s, const char *quotes);