X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=52e5df44a9994e759f1061a1eb715543e85d8350;hp=98b3465d4a58002fa00e767de90c83bf68429664;hb=10f9c75519671e7c7ab8993b54fe22da7c2d0c38;hpb=4a4d89b682d2a8d32e899c4b47950f64df74fb7c diff --git a/src/shared/util.c b/src/shared/util.c index 98b3465d4..52e5df44a 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -7561,8 +7561,37 @@ int openpt_in_namespace(pid_t pid, int flags) { return -EIO; } -int fd_getcrtime(int fd, usec_t *usec) { +ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) { + _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_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0)); + if (fd < 0) + return -errno; + + l = fgetxattr(fd, 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; @@ -7578,16 +7607,23 @@ int fd_getcrtime(int fd, usec_t *usec) { if (n != sizeof(le)) return -EIO; - u = le64toh(le); - if (u == 0 || u == (uint64_t) -1) + 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; - *usec = (usec_t) u; - return 0; + return parse_crtime(le, usec); } int path_getcrtime(const char *p, usec_t *usec) { - uint64_t u; le64_t le; ssize_t n; @@ -7600,12 +7636,7 @@ int path_getcrtime(const char *p, usec_t *usec) { if (n != sizeof(le)) return -EIO; - u = le64toh(le); - if (u == 0 || u == (uint64_t) -1) - return -EIO; - - *usec = (usec_t) u; - return 0; + return parse_crtime(le, usec); } int fd_setcrtime(int fd, usec_t usec) {