From 89a5a90cb0935cdad84a0b98d41789ad879d0d83 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 26 Oct 2015 20:26:23 +0100 Subject: util-lib: split xattr-related calls into xattr-util.[ch] --- Makefile.am | 2 + src/basic/copy.c | 1 + src/basic/smack-util.c | 7 +- src/basic/util.c | 167 ------------------------------------- src/basic/util.h | 10 --- src/basic/xattr-util.c | 193 +++++++++++++++++++++++++++++++++++++++++++ src/basic/xattr-util.h | 38 +++++++++ src/import/pull-job.c | 3 +- src/journal/journal-file.c | 1 + src/journal/journal-vacuum.c | 1 + src/shared/machine-image.c | 1 + src/test/test-util.c | 3 +- 12 files changed, 245 insertions(+), 182 deletions(-) create mode 100644 src/basic/xattr-util.c create mode 100644 src/basic/xattr-util.h diff --git a/Makefile.am b/Makefile.am index 563e2cc4ea..33d66d4dd0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -795,6 +795,8 @@ libbasic_la_SOURCES = \ src/basic/rlimit-util.h \ src/basic/dirent-util.c \ src/basic/dirent-util.h \ + src/basic/xattr-util.c \ + src/basic/xattr-util.h \ src/basic/mount-util.c \ src/basic/mount-util.h \ src/basic/hexdecoct.c \ diff --git a/src/basic/copy.c b/src/basic/copy.c index 2d2d7ade34..60a4bee0fe 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -31,6 +31,7 @@ #include "string-util.h" #include "strv.h" #include "util.h" +#include "xattr-util.h" #define COPY_BUFFER_SIZE (16*1024) diff --git a/src/basic/smack-util.c b/src/basic/smack-util.c index 5f570ff02a..5ada621ca3 100644 --- a/src/basic/smack-util.c +++ b/src/basic/smack-util.c @@ -23,11 +23,12 @@ #include -#include "util.h" -#include "process-util.h" -#include "path-util.h" #include "fileio.h" +#include "path-util.h" +#include "process-util.h" #include "smack-util.h" +#include "util.h" +#include "xattr-util.h" #ifdef HAVE_SMACK bool mac_smack_use(void) { diff --git a/src/basic/util.c b/src/basic/util.c index e214c6f3dc..dfebff7ec1 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include @@ -1963,102 +1962,6 @@ int is_device_node(const char *path) { return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode)); } -ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) { - char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; - _cleanup_close_ int fd = -1; - ssize_t l; - - /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */ - - fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0)); - if (fd < 0) - return -errno; - - xsprintf(fn, "/proc/self/fd/%i", fd); - - l = getxattr(fn, attribute, value, size); - if (l < 0) - return -errno; - - return l; -} - -static int parse_crtime(le64_t le, usec_t *usec) { - uint64_t u; - - assert(usec); - - u = le64toh(le); - if (u == 0 || u == (uint64_t) -1) - return -EIO; - - *usec = (usec_t) u; - return 0; -} - -int fd_getcrtime(int fd, usec_t *usec) { - le64_t le; - ssize_t n; - - assert(fd >= 0); - assert(usec); - - /* Until Linux gets a real concept of birthtime/creation time, - * let's fake one with xattrs */ - - n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le)); - if (n < 0) - return -errno; - if (n != sizeof(le)) - return -EIO; - - return parse_crtime(le, usec); -} - -int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) { - le64_t le; - ssize_t n; - - n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags); - if (n < 0) - return -errno; - if (n != sizeof(le)) - return -EIO; - - return parse_crtime(le, usec); -} - -int path_getcrtime(const char *p, usec_t *usec) { - le64_t le; - ssize_t n; - - assert(p); - assert(usec); - - n = getxattr(p, "user.crtime_usec", &le, sizeof(le)); - if (n < 0) - return -errno; - if (n != sizeof(le)) - return -EIO; - - return parse_crtime(le, usec); -} - -int fd_setcrtime(int fd, usec_t usec) { - le64_t le; - - assert(fd >= 0); - - if (usec <= 0) - usec = now(CLOCK_REALTIME); - - le = htole64((uint64_t) usec); - if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0) - return -errno; - - return 0; -} - int chattr_fd(int fd, unsigned value, unsigned mask) { unsigned old_attr, new_attr; struct stat st; @@ -2233,76 +2136,6 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char return 0; } -int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) { - char *v; - size_t l; - ssize_t n; - - assert(path); - assert(name); - assert(value); - - for (l = 100; ; l = (size_t) n + 1) { - v = new0(char, l); - if (!v) - return -ENOMEM; - - if (allow_symlink) - n = lgetxattr(path, name, v, l); - else - n = getxattr(path, name, v, l); - - if (n >= 0 && (size_t) n < l) { - *value = v; - return n; - } - - free(v); - - if (n < 0 && errno != ERANGE) - return -errno; - - if (allow_symlink) - n = lgetxattr(path, name, NULL, 0); - else - n = getxattr(path, name, NULL, 0); - if (n < 0) - return -errno; - } -} - -int fgetxattr_malloc(int fd, const char *name, char **value) { - char *v; - size_t l; - ssize_t n; - - assert(fd >= 0); - assert(name); - assert(value); - - for (l = 100; ; l = (size_t) n + 1) { - v = new0(char, l); - if (!v) - return -ENOMEM; - - n = fgetxattr(fd, name, v, l); - - if (n >= 0 && (size_t) n < l) { - *value = v; - return n; - } - - free(v); - - if (n < 0 && errno != ERANGE) - return -errno; - - n = fgetxattr(fd, name, NULL, 0); - if (n < 0) - return -errno; - } -} - int version(void) { puts(PACKAGE_STRING "\n" SYSTEMD_FEATURES); diff --git a/src/basic/util.h b/src/basic/util.h index 190d4f5edb..8f9f3f8fe6 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -500,13 +500,6 @@ union inotify_event_buffer { #define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW) -ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags); - -int fd_setcrtime(int fd, usec_t usec); -int fd_getcrtime(int fd, usec_t *usec); -int path_getcrtime(const char *p, usec_t *usec); -int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags); - int chattr_fd(int fd, unsigned value, unsigned mask); int chattr_path(const char *p, unsigned value, unsigned mask); @@ -517,9 +510,6 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility); int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); -int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink); -int fgetxattr_malloc(int fd, const char *name, char **value); - int version(void); bool fdname_is_valid(const char *s); diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c new file mode 100644 index 0000000000..35fd1c1616 --- /dev/null +++ b/src/basic/xattr-util.c @@ -0,0 +1,193 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + 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 . +***/ + +#include + +#include "fd-util.h" +#include "sparse-endian.h" +#include "util.h" +#include "xattr-util.h" + +int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) { + char *v; + size_t l; + ssize_t n; + + assert(path); + assert(name); + assert(value); + + for (l = 100; ; l = (size_t) n + 1) { + v = new0(char, l); + if (!v) + return -ENOMEM; + + if (allow_symlink) + n = lgetxattr(path, name, v, l); + else + n = getxattr(path, name, v, l); + + if (n >= 0 && (size_t) n < l) { + *value = v; + return n; + } + + free(v); + + if (n < 0 && errno != ERANGE) + return -errno; + + if (allow_symlink) + n = lgetxattr(path, name, NULL, 0); + else + n = getxattr(path, name, NULL, 0); + if (n < 0) + return -errno; + } +} + +int fgetxattr_malloc(int fd, const char *name, char **value) { + char *v; + size_t l; + ssize_t n; + + assert(fd >= 0); + assert(name); + assert(value); + + for (l = 100; ; l = (size_t) n + 1) { + v = new0(char, l); + if (!v) + return -ENOMEM; + + n = fgetxattr(fd, name, v, l); + + if (n >= 0 && (size_t) n < l) { + *value = v; + return n; + } + + free(v); + + if (n < 0 && errno != ERANGE) + return -errno; + + n = fgetxattr(fd, name, NULL, 0); + if (n < 0) + return -errno; + } +} + +ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) { + char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; + _cleanup_close_ int fd = -1; + ssize_t l; + + /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */ + + fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0)); + if (fd < 0) + return -errno; + + xsprintf(fn, "/proc/self/fd/%i", fd); + + l = getxattr(fn, attribute, value, size); + if (l < 0) + return -errno; + + return l; +} + +static int parse_crtime(le64_t le, usec_t *usec) { + uint64_t u; + + assert(usec); + + u = le64toh(le); + if (u == 0 || u == (uint64_t) -1) + return -EIO; + + *usec = (usec_t) u; + return 0; +} + +int fd_getcrtime(int fd, usec_t *usec) { + le64_t le; + ssize_t n; + + assert(fd >= 0); + assert(usec); + + /* Until Linux gets a real concept of birthtime/creation time, + * let's fake one with xattrs */ + + n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le)); + if (n < 0) + return -errno; + if (n != sizeof(le)) + return -EIO; + + return parse_crtime(le, usec); +} + +int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) { + le64_t le; + ssize_t n; + + n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags); + if (n < 0) + return -errno; + if (n != sizeof(le)) + return -EIO; + + return parse_crtime(le, usec); +} + +int path_getcrtime(const char *p, usec_t *usec) { + le64_t le; + ssize_t n; + + assert(p); + assert(usec); + + n = getxattr(p, "user.crtime_usec", &le, sizeof(le)); + if (n < 0) + return -errno; + if (n != sizeof(le)) + return -EIO; + + return parse_crtime(le, usec); +} + +int fd_setcrtime(int fd, usec_t usec) { + le64_t le; + + assert(fd >= 0); + + if (usec <= 0) + usec = now(CLOCK_REALTIME); + + le = htole64((uint64_t) usec); + if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0) + return -errno; + + return 0; +} diff --git a/src/basic/xattr-util.h b/src/basic/xattr-util.h new file mode 100644 index 0000000000..cf4cb12a25 --- /dev/null +++ b/src/basic/xattr-util.h @@ -0,0 +1,38 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + 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 . +***/ + +#include +#include + +#include "time-util.h" + +int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink); +int fgetxattr_malloc(int fd, const char *name, char **value); + +ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags); + +int fd_setcrtime(int fd, usec_t usec); + +int fd_getcrtime(int fd, usec_t *usec); +int path_getcrtime(const char *p, usec_t *usec); +int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags); diff --git a/src/import/pull-job.c b/src/import/pull-job.c index 0910901375..3cc7ea10b7 100644 --- a/src/import/pull-job.c +++ b/src/import/pull-job.c @@ -22,13 +22,14 @@ #include #include "fd-util.h" +#include "hexdecoct.h" #include "io-util.h" #include "machine-pool.h" -#include "hexdecoct.h" #include "parse-util.h" #include "pull-job.h" #include "string-util.h" #include "strv.h" +#include "xattr-util.h" PullJob* pull_job_unref(PullJob *j) { if (!j) diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index c33e278cbe..a3b09dddff 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -38,6 +38,7 @@ #include "parse-util.h" #include "random-util.h" #include "string-util.h" +#include "xattr-util.h" #define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem)) #define DEFAULT_FIELD_HASH_TABLE_SIZE (333ULL*sizeof(HashItem)) diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index d3add065d2..87646922fb 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -33,6 +33,7 @@ #include "parse-util.h" #include "string-util.h" #include "util.h" +#include "xattr-util.h" struct vacuum_info { uint64_t usage; diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c index 485793ed5d..ca85e26095 100644 --- a/src/shared/machine-image.c +++ b/src/shared/machine-image.c @@ -34,6 +34,7 @@ #include "string-util.h" #include "strv.h" #include "utf8.h" +#include "xattr-util.h" static const char image_search_path[] = "/var/lib/machines\0" diff --git a/src/test/test-util.c b/src/test/test-util.c index 109791163f..2e266bb047 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -42,6 +42,7 @@ #include "io-util.h" #include "mkdir.h" #include "parse-util.h" +#include "path-util.h" #include "process-util.h" #include "rm-rf.h" #include "signal-util.h" @@ -50,7 +51,7 @@ #include "user-util.h" #include "util.h" #include "virt.h" -#include "path-util.h" +#include "xattr-util.h" static void test_streq_ptr(void) { assert_se(streq_ptr(NULL, NULL)); -- cgit v1.2.3-54-g00ecf