X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ftmpfiles%2Ftmpfiles.c;h=6e0c093a82c58174ccfeb44efad79e69e32d96e2;hb=e7aee75932e8a5bee54eefcc77f4702a3ea79db2;hp=235617853b592e1a8b99c8343df2a993b203d674;hpb=9eb977db5b89b44f254ab40c1876a76b7d7ea2d0;p=elogind.git diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 235617853..6e0c093a8 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -100,6 +100,14 @@ static bool arg_remove = false; static const char *arg_prefix = NULL; +static const char *conf_file_dirs[] = { + "/etc/tmpfiles.d", + "/run/tmpfiles.d", + "/usr/local/lib/tmpfiles.d", + "/usr/lib/tmpfiles.d", + NULL +}; + #define MAX_DEPTH 256 static bool needs_glob(ItemType t) { @@ -617,8 +625,13 @@ static int create_item(Item *i) { iovec[1].iov_len = 1; n = writev(fd, iovec, 2); - if (n < 0 || (size_t) n != l+1) { - log_error("Failed to write file %s: %s", i->path, n < 0 ? strerror(-n) : "Short"); + + /* It's OK if we don't write the trailing + * newline, hence we check for l, instead of + * l+1 here. Files in /sys often refuse + * writing of the trailing newline. */ + if (n < 0 || (size_t) n < l) { + log_error("Failed to write file %s: %s", i->path, n < 0 ? strerror(-n) : "Short write"); close_nointr_nofail(fd); return n < 0 ? n : -EIO; } @@ -647,7 +660,7 @@ static int create_item(Item *i) { case CREATE_DIRECTORY: u = umask(0); - mkdir_parents(i->path, 0755); + mkdir_parents_label(i->path, 0755); r = mkdir(i->path, i->mode); umask(u); @@ -731,10 +744,11 @@ static int create_item(Item *i) { case CREATE_BLOCK_DEVICE: case CREATE_CHAR_DEVICE: { + mode_t file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR); u = umask(0); - label_context_set(i->path, CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR); - r = mknod(i->path, i->mode | (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR), i->major_minor); + 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); @@ -750,7 +764,7 @@ static int create_item(Item *i) { return -errno; } - if (i->type == CREATE_BLOCK_DEVICE ? !S_ISBLK(st.st_mode) : !S_ISCHR(st.st_mode)) { + if ((st.st_mode & S_IFMT) != file_type) { log_error("%s is not a device node.", i->path); return -EEXIST; } @@ -1248,6 +1262,30 @@ static int read_config_file(const char *fn, bool ignore_enoent) { return r; } +static char *resolve_fragment(const char *fragment, const char **search_paths) { + const char **p; + char *resolved_path; + + if (is_path(fragment)) + return strdup(fragment); + + STRV_FOREACH(p, search_paths) { + resolved_path = join(*p, "/", fragment, NULL); + if (resolved_path == NULL) { + log_error("Out of memory"); + return NULL; + } + + if (access(resolved_path, F_OK) == 0) + return resolved_path; + + free(resolved_path); + } + + errno = ENOENT; + return NULL; +} + int main(int argc, char *argv[]) { int r; Item *i; @@ -1279,19 +1317,25 @@ int main(int argc, char *argv[]) { if (optind < argc) { int j; - for (j = optind; j < argc; j++) - if (read_config_file(argv[j], false) < 0) + for (j = optind; j < argc; j++) { + char *fragment; + + fragment = resolve_fragment(argv[j], conf_file_dirs); + if (!fragment) { + log_error("Failed to find a %s file: %m", argv[j]); + r = EXIT_FAILURE; + goto finish; + } + if (read_config_file(fragment, false) < 0) r = EXIT_FAILURE; + free(fragment); + } } else { char **files, **f; - r = conf_files_list(&files, ".conf", - "/etc/tmpfiles.d", - "/run/tmpfiles.d", - "/usr/local/lib/tmpfiles.d", - "/usr/lib/tmpfiles.d", - NULL); + r = conf_files_list_strv(&files, ".conf", + (const char **)conf_file_dirs); if (r < 0) { log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r)); r = EXIT_FAILURE;