chiark / gitweb /
util: add a bit of syntactic sugar to run short code fragments with a different umask
[elogind.git] / src / tmpfiles / tmpfiles.c
index 4a76a2f778bbfbdcbab1bb8b7c9310dd1fdb086a..4e2519d1b543d2e5ff82e932c30c5441190ce97a 100644 (file)
@@ -43,6 +43,7 @@
 #include "log.h"
 #include "util.h"
 #include "macro.h"
+#include "missing.h"
 #include "mkdir.h"
 #include "path-util.h"
 #include "strv.h"
@@ -453,18 +454,17 @@ static int item_set_perms(Item *i, const char *path) {
 static int write_one_file(Item *i, const char *path) {
         int r, e, fd, flags;
         struct stat st;
-        mode_t u;
 
         flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
                 i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
 
-        u = umask(0);
-        label_context_set(path, S_IFREG);
-        fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
-        e = errno;
-        label_context_clear();
-        umask(u);
-        errno = e;
+        RUN_WITH_UMASK(0) {
+                label_context_set(path, S_IFREG);
+                fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
+                e = errno;
+                label_context_clear();
+                errno = e;
+        }
 
         if (fd < 0) {
                 if (i->type == WRITE_FILE && errno == ENOENT)
@@ -610,7 +610,7 @@ static int glob_item(Item *i, int (*action)(Item *, const char *)) {
         if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) {
 
                 if (k != GLOB_NOMATCH) {
-                        if (errno != 0)
+                        if (errno > 0)
                                 errno = EIO;
 
                         log_error("glob(%s) failed: %m", i->path);
@@ -628,7 +628,6 @@ static int glob_item(Item *i, int (*action)(Item *, const char *)) {
 
 static int create_item(Item *i) {
         int r, e;
-        mode_t u;
         struct stat st;
 
         assert(i);
@@ -657,10 +656,10 @@ static int create_item(Item *i) {
         case TRUNCATE_DIRECTORY:
         case CREATE_DIRECTORY:
 
-                u = umask(0);
-                mkdir_parents_label(i->path, 0755);
-                r = mkdir(i->path, i->mode);
-                umask(u);
+                RUN_WITH_UMASK(0000) {
+                        mkdir_parents_label(i->path, 0755);
+                        r = mkdir(i->path, i->mode);
+                }
 
                 if (r < 0 && errno != EEXIST) {
                         log_error("Failed to create directory %s: %m", i->path);
@@ -685,9 +684,9 @@ static int create_item(Item *i) {
 
         case CREATE_FIFO:
 
-                u = umask(0);
-                r = mkfifo(i->path, i->mode);
-                umask(u);
+                RUN_WITH_UMASK(0000) {
+                        r = mkfifo(i->path, i->mode);
+                }
 
                 if (r < 0 && errno != EEXIST) {
                         log_error("Failed to create fifo %s: %m", i->path);
@@ -756,13 +755,13 @@ static int create_item(Item *i) {
 
                 file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR);
 
-                u = umask(0);
-                label_context_set(i->path, file_type);
-                r = mknod(i->path, i->mode | file_type, i->major_minor);
-                e = errno;
-                label_context_clear();
-                umask(u);
-                errno = e;
+                RUN_WITH_UMASK(0000) {
+                        label_context_set(i->path, file_type);
+                        r = mknod(i->path, i->mode | file_type, i->major_minor);
+                        e = errno;
+                        label_context_clear();
+                        errno = e;
+                }
 
                 if (r < 0 && errno != EEXIST) {
                         log_error("Failed to create device node %s: %m", i->path);
@@ -1020,7 +1019,8 @@ static bool item_equal(Item *a, Item *b) {
 }
 
 static int parse_line(const char *fname, unsigned line, const char *buffer) {
-        Item *i, *existing;
+        Item _cleanup_free_ *i = NULL;
+        Item *existing;
         char _cleanup_free_
                 *mode = NULL, *user = NULL, *group = NULL, *age = NULL;
         char type;
@@ -1046,8 +1046,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                    &n);
         if (r < 2) {
                 log_error("[%s:%u] Syntax error.", fname, line);
-                r = -EIO;
-                goto finish;
+                return -EIO;
         }
 
         if (n >= 0)  {
@@ -1077,16 +1076,14 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         case CREATE_SYMLINK:
                 if (!i->argument) {
                         log_error("[%s:%u] Symlink file requires argument.", fname, line);
-                        r = -EBADMSG;
-                        goto finish;
+                        return -EBADMSG;
                 }
                 break;
 
         case WRITE_FILE:
                 if (!i->argument) {
                         log_error("[%s:%u] Write file requires argument.", fname, line);
-                        r = -EBADMSG;
-                        goto finish;
+                        return -EBADMSG;
                 }
                 break;
 
@@ -1096,14 +1093,12 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
                 if (!i->argument) {
                         log_error("[%s:%u] Device file requires argument.", fname, line);
-                        r = -EBADMSG;
-                        goto finish;
+                        return -EBADMSG;
                 }
 
                 if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) {
                         log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument);
-                        r = -EBADMSG;
-                        goto finish;
+                        return -EBADMSG;
                 }
 
                 i->major_minor = makedev(major, minor);
@@ -1112,24 +1107,20 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
         default:
                 log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
-                r = -EBADMSG;
-                goto finish;
+                return -EBADMSG;
         }
 
         i->type = type;
 
         if (!path_is_absolute(i->path)) {
                 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
-                r = -EBADMSG;
-                goto finish;
+                return -EBADMSG;
         }
 
         path_kill_slashes(i->path);
 
-        if (arg_prefix && !path_startswith(i->path, arg_prefix)) {
-                r = 0;
-                goto finish;
-        }
+        if (arg_prefix && !path_startswith(i->path, arg_prefix))
+                return 0;
 
         if (user && !streq(user, "-")) {
                 const char *u = user;
@@ -1137,7 +1128,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
                 if (r < 0) {
                         log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
-                        goto finish;
+                        return r;
                 }
 
                 i->uid_set = true;
@@ -1149,7 +1140,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 r = get_group_creds(&g, &i->gid);
                 if (r < 0) {
                         log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
-                        goto finish;
+                        return r;
                 }
 
                 i->gid_set = true;
@@ -1160,8 +1151,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
                 if (sscanf(mode, "%o", &m) != 1) {
                         log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
-                        r = -ENOENT;
-                        goto finish;
+                        return -ENOENT;
                 }
 
                 i->mode = m;
@@ -1179,10 +1169,9 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                         a++;
                 }
 
-                if (parse_usec(a, &i->age) < 0) {
+                if (parse_sec(a, &i->age) < 0) {
                         log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
-                        r = -EBADMSG;
-                        goto finish;
+                        return -EBADMSG;
                 }
 
                 i->age_set = true;
@@ -1197,24 +1186,18 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 if (!item_equal(existing, i))
                         log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
 
-                r = 0;
-                goto finish;
+                return 0;
         }
 
         r = hashmap_put(h, i->path, i);
         if (r < 0) {
                 log_error("Failed to insert item %s: %s", i->path, strerror(-r));
-                goto finish;
+                return r;
         }
 
-        i = NULL;
-        r = 0;
+        i = NULL; /* avoid cleanup */
 
-finish:
-        if (i)
-                item_free(i);
-
-        return r;
+        return 0;
 }
 
 static int help(void) {