This ref-counted struct holds a path and a descriptor to a directory. The descriptor should be used for "real" work (openat, renameat and others) and the path should be used for logging/debugging. --- Makefile.am | 2 + src/journal/journal-dir.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++ src/journal/journal-dir.h | 37 ++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 src/journal/journal-dir.c create mode 100644 src/journal/journal-dir.h
diff --git a/Makefile.am b/Makefile.am index 43b819b..32e7ca3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4644,6 +4644,8 @@ libsystemd_journal_internal_la_SOURCES = \ src/systemd/_sd-common.h \ src/journal/journal-file.c \ src/journal/journal-file.h \ + src/journal/journal-dir.c \ + src/journal/journal-dir.h \ src/journal/journal-vacuum.c \ src/journal/journal-vacuum.h \ src/journal/journal-verify.c \ diff --git a/src/journal/journal-dir.c b/src/journal/journal-dir.c new file mode 100644 index 0000000..689e1f0 --- /dev/null +++ b/src/journal/journal-dir.c @@ -0,0 +1,141 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2015 Endocode AG + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "journal-dir.h" +#include "macro.h" +#include "util.h" + +static int journal_directory_new_steal(char *path, int fd, JournalDirectory **dir) { + JournalDirectory *d; + + assert(path); + assert(fd >= 0); + assert(dir); + + d = new0(JournalDirectory, 1); + if (!d) + return -ENOMEM; + d->path = path; + d->fd = fd; + d->n_ref = 1; + *dir = d; + return 0; +} + +int journal_directory_open(const char *path, JournalDirectory **dir) +{ + _cleanup_free_ char *p = NULL; + _cleanup_close_ int fd = -1; + int r; + + assert(path); + assert(dir); + + fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (fd < 0) + return -errno; + + p = strdup(path); + if (!p) + return -ENOMEM; + + r = journal_directory_new_steal(p, fd, dir); + if (r < 0) + return r; + p = NULL; + fd = -1; + return 0; +} + +int journal_directory_new(const char *path, int fd, JournalDirectory **dir) +{ + _cleanup_free_ char *p = NULL; + _cleanup_close_ int dfd = -1; + int r; + + assert(path); + assert(fd >= 0); + assert(dir); + + dfd = fcntl(fd, F_DUPFD_CLOEXEC, 3); + if (dfd < 0) + return -errno; + + p = strdup(path); + if (!p) + return -ENOMEM; + + r = journal_directory_new_steal(p, dfd, dir); + if (r < 0) + return r; + p = NULL; + dfd = -1; + return 0; +} + +JournalDirectory *journal_directory_ref(JournalDirectory *dir) +{ + assert(dir); + assert(dir->n_ref > 0); + + dir->n_ref ++; + return dir; +} + +JournalDirectory *journal_directory_unref(JournalDirectory *dir) +{ + if (dir) { + PROTECT_ERRNO; + + assert(dir->n_ref > 0); + + dir->n_ref --; + if (!dir->n_ref) { + safe_close(dir->fd); + free(dir->path); + free(dir); + } + } + + return NULL; +} + +int journal_directory_opendir(JournalDirectory *dir, DIR **de) +{ + int fd; + DIR* d; + + assert(dir); + assert(de); + + fd = fcntl(dir->fd, F_DUPFD_CLOEXEC, 3); + if (fd < 0) + return -errno; + + d = fdopendir(fd); + if (!d) { + safe_close(fd); + return -errno; + } + + *de = d; + return 0; +} diff --git a/src/journal/journal-dir.h b/src/journal/journal-dir.h new file mode 100644 index 0000000..65ae229 --- /dev/null +++ b/src/journal/journal-dir.h @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2015 Endocode AG + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/types.h> +#include <dirent.h> + +typedef struct JournalDirectory { + char *path; + int fd; + int n_ref; +} JournalDirectory; + +int journal_directory_open(const char *path, JournalDirectory **dir); +int journal_directory_new(const char *path, int fd, JournalDirectory **dir); +JournalDirectory *journal_directory_ref(JournalDirectory *dir); +JournalDirectory *journal_directory_unref(JournalDirectory *dir); +int journal_directory_opendir(JournalDirectory *dir, DIR **de); -- 2.1.0 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel