diff options
author | Florian Weimer <fweimer@redhat.com> | 2018-07-10 16:14:45 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2018-07-10 16:14:45 +0200 |
commit | fd70af45528d59a00eb3190ef6706cb299488fcd (patch) | |
tree | 9782185e343e716c4af641cc16ece3ffd5c38ebf /io/statx_generic.c | |
parent | b444e8f7cc40265c9a20ce5de5f3f6795b7f5028 (diff) | |
download | glibc-fd70af45528d59a00eb3190ef6706cb299488fcd.tar.gz glibc-fd70af45528d59a00eb3190ef6706cb299488fcd.tar.xz glibc-fd70af45528d59a00eb3190ef6706cb299488fcd.zip |
Add the statx function
Diffstat (limited to 'io/statx_generic.c')
-rw-r--r-- | io/statx_generic.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/io/statx_generic.c b/io/statx_generic.c new file mode 100644 index 0000000000..df327f8c52 --- /dev/null +++ b/io/statx_generic.c @@ -0,0 +1,81 @@ +/* Generic implementation of statx based on fstatat64. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library 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. + + The GNU C Library 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 the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> + +static inline struct statx_timestamp +statx_convert_timestamp (struct timespec tv) +{ + return (struct statx_timestamp) { tv.tv_sec, tv.tv_nsec }; +} + +/* Approximate emulation of statx. This will always fill in + POSIX-mandated attributes even if the underlying file system does + not actually support it (for example, GID and UID on file systems + without UNIX-style permissions). */ +static __attribute__ ((unused)) int +statx_generic (int fd, const char *path, int flags, + unsigned int mask, struct statx *buf) +{ + /* Flags which need to be cleared before passing them to + fstatat64. */ + static const int clear_flags = AT_STATX_SYNC_AS_STAT; + + /* Flags supported by our emulation. */ + static const int supported_flags + = AT_EMPTY_PATH | AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW | clear_flags; + + if (__glibc_unlikely ((flags & ~supported_flags) != 0)) + { + __set_errno (EINVAL); + return -1; + } + + struct stat64 st; + int ret = __fstatat64 (fd, path, &st, flags & ~clear_flags); + if (ret != 0) + return ret; + + /* The interface is defined in such a way that unused (padding) + fields have to be cleared. STATX_BASIC_STATS corresponds to the + data which is available via fstatat64. */ + *buf = (struct statx) + { + .stx_mask = STATX_BASIC_STATS, + .stx_blksize = st.st_blksize, + .stx_nlink = st.st_nlink, + .stx_uid = st.st_uid, + .stx_gid = st.st_gid, + .stx_mode = st.st_mode, + .stx_ino = st.st_ino, + .stx_size = st.st_size, + .stx_blocks = st.st_blocks, + .stx_atime = statx_convert_timestamp (st.st_atim), + .stx_ctime = statx_convert_timestamp (st.st_ctim), + .stx_mtime = statx_convert_timestamp (st.st_mtim), + .stx_rdev_major = major (st.st_rdev), + .stx_rdev_minor = minor (st.st_rdev), + .stx_dev_major = major (st.st_dev), + .stx_dev_minor = minor (st.st_dev), + }; + + return 0; +} |