On Sep 11, 2019, at 7:51 AM, Jeff Layton <jlay...@kernel.org> wrote: > > * add wrapper functions for stat, lstat and stat_for_mode so that we > can conditionally plug in statx-enabled variants > * add statx-enabled functions and set the request mask based on the > output format and what values are needed > --- > src/ls.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 69 insertions(+), 4 deletions(-) > > diff --git a/src/ls.c b/src/ls.c > index 8e5015e5ac12..3c12f63e595b 100644 > --- a/src/ls.c > +++ b/src/ls.c > @@ -3166,6 +3166,71 @@ needs_quoting (char const* name) > return *name != *test || strlen (name) != len; > } > > +#if USE_STATX > +static unsigned int > +calc_request_mask(void) > +{ > + unsigned int mask = STATX_MODE; > + > + if (print_inode) > + mask |= STATX_INO; > + if (format == long_format) { > + mask |= STATX_NLINK | STATX_SIZE; > + if (print_owner || print_author) > + mask |= STATX_UID; > + if (print_group) > + mask |= STATX_GID; > + } > + return mask; > +} > + > +static int > +do_statx (const char *name, struct stat *st, int flags, unsigned int mask) > +{ > + struct statx stx; > + int ret = statx(AT_FDCWD, name, flags, mask, &stx); > + if (ret >= 0) > + statx_to_stat(&stx, st);
Should this also get a stat() fallback if statx() is not supported? Cheers, Andreas > + return ret; > +} > + > +static inline int > +do_stat(const char *name, struct stat *st) > +{ > + return do_statx(name, st, 0, calc_request_mask()); > +} > + > +static int > +do_lstat (const char *name, struct stat *st) > +{ > + return do_statx(name, st, AT_SYMLINK_NOFOLLOW, calc_request_mask()); > +} > + > +static int > +stat_for_mode(const char *name, struct stat *st) > +{ > + return do_statx(name, st, 0, STATX_MODE); > +} > +#else > +static inline int > +do_stat (const char *name, struct stat *st) > +{ > + return stat(name, st); > +} > + > +static inline int > +do_lstat (const char *name, struct stat *st) > +{ > + return lstat(name, st); > +} > + > +static int > +stat_for_mode(const char *name, struct stat *st) > +{ > + return do_stat(name, st); > +} > +#endif > + > /* Add a file to the current table of files. > Verify that the file exists, and print an error message if it does not. > Return the number of blocks that the file occupies. */ > @@ -3264,7 +3329,7 @@ gobble_file (char const *name, enum filetype type, > ino_t inode, > switch (dereference) > { > case DEREF_ALWAYS: > - err = stat (full_name, &f->stat); > + err = do_stat (full_name, &f->stat); > do_deref = true; > break; > > @@ -3273,7 +3338,7 @@ gobble_file (char const *name, enum filetype type, > ino_t inode, > if (command_line_arg) > { > bool need_lstat; > - err = stat (full_name, &f->stat); > + err = do_stat (full_name, &f->stat); > do_deref = true; > > if (dereference == DEREF_COMMAND_LINE_ARGUMENTS) > @@ -3293,7 +3358,7 @@ gobble_file (char const *name, enum filetype type, > ino_t inode, > FALLTHROUGH; > > default: /* DEREF_NEVER */ > - err = lstat (full_name, &f->stat); > + err = do_lstat (full_name, &f->stat); > do_deref = false; > break; > } > @@ -3382,7 +3447,7 @@ gobble_file (char const *name, enum filetype type, > ino_t inode, > they won't be traced and when no indicator is needed. */ > if (linkname > && (file_type <= indicator_style || check_symlink_mode) > - && stat (linkname, &linkstats) == 0) > + && stat_for_mode(linkname, &linkstats) == 0) > { > f->linkok = true; > f->linkmode = linkstats.st_mode; > -- > 2.21.0 > Cheers, Andreas
signature.asc
Description: Message signed with OpenPGP