2004-06-30 22:31:43 +00:00
|
|
|
/* stat.c -- display file or file system status
|
2026-01-01 10:56:16 -08:00
|
|
|
Copyright (C) 2001-2026 Free Software Foundation, Inc.
|
2002-04-16 06:27:39 +00:00
|
|
|
|
2007-07-23 14:35:58 +02:00
|
|
|
This program is free software: you can redistribute it and/or modify
|
2002-04-16 06:27:39 +00:00
|
|
|
it under the terms of the GNU General Public License as published by
|
2007-07-23 14:35:58 +02:00
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
2002-04-16 06:27:39 +00:00
|
|
|
|
|
|
|
|
This program 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 General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2017-09-19 01:13:23 -07:00
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2002-04-16 06:27:39 +00:00
|
|
|
|
|
|
|
|
Written by Michael Meskes. */
|
|
|
|
|
|
2002-04-13 14:11:44 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
|
2006-08-29 21:53:29 +00:00
|
|
|
/* Keep this conditional in sync with the similar conditional in
|
|
|
|
|
../m4/stat-prog.m4. */
|
2011-09-08 11:52:55 +02:00
|
|
|
#if ((STAT_STATVFS || STAT_STATVFS64) \
|
2006-08-18 18:36:04 +00:00
|
|
|
&& (HAVE_STRUCT_STATVFS_F_BASETYPE || HAVE_STRUCT_STATVFS_F_FSTYPENAME \
|
2009-08-22 18:56:06 +02:00
|
|
|
|| (! HAVE_STRUCT_STATFS_F_FSTYPENAME && HAVE_STRUCT_STATVFS_F_TYPE)))
|
2006-04-12 20:14:42 +00:00
|
|
|
# define USE_STATVFS 1
|
|
|
|
|
#else
|
|
|
|
|
# define USE_STATVFS 0
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-04-13 13:47:14 +00:00
|
|
|
#include <stdio.h>
|
2002-04-13 14:11:44 +00:00
|
|
|
#include <sys/types.h>
|
2002-04-13 13:47:14 +00:00
|
|
|
#include <pwd.h>
|
|
|
|
|
#include <grp.h>
|
2006-04-12 20:14:42 +00:00
|
|
|
#if USE_STATVFS
|
2003-05-26 20:23:14 +00:00
|
|
|
# include <sys/statvfs.h>
|
2003-06-17 17:40:45 +00:00
|
|
|
#elif HAVE_SYS_VFS_H
|
|
|
|
|
# include <sys/vfs.h>
|
2003-05-26 20:23:14 +00:00
|
|
|
#elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H
|
|
|
|
|
/* NOTE: freebsd5.0 needs sys/param.h and sys/mount.h for statfs.
|
|
|
|
|
It does have statvfs.h, but shouldn't use it, since it doesn't
|
|
|
|
|
HAVE_STRUCT_STATVFS_F_BASETYPE. So find a clean way to fix it. */
|
2003-04-07 18:11:39 +00:00
|
|
|
/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */
|
2003-05-26 20:23:14 +00:00
|
|
|
# include <sys/param.h>
|
|
|
|
|
# include <sys/mount.h>
|
2010-04-24 17:38:13 +02:00
|
|
|
# if HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H
|
2003-04-07 18:11:39 +00:00
|
|
|
/* Ultrix 4.4 needs these for the declaration of struct statfs. */
|
2003-06-17 17:40:45 +00:00
|
|
|
# include <netinet/in.h>
|
|
|
|
|
# include <nfs/nfs_clnt.h>
|
|
|
|
|
# include <nfs/vfs.h>
|
|
|
|
|
# endif
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
#elif HAVE_OS_H /* BeOS */
|
|
|
|
|
# include <fs_info.h>
|
2002-06-21 12:34:36 +00:00
|
|
|
#endif
|
2007-01-07 09:15:42 +01:00
|
|
|
#include <selinux/selinux.h>
|
2024-02-18 12:23:07 -08:00
|
|
|
#include <getopt.h>
|
2002-06-21 12:34:36 +00:00
|
|
|
|
2002-04-13 14:11:44 +00:00
|
|
|
#include "system.h"
|
|
|
|
|
|
2010-05-01 11:29:39 +02:00
|
|
|
#include "areadlink.h"
|
2016-11-03 15:36:48 +00:00
|
|
|
#include "argmatch.h"
|
2023-10-27 08:45:50 -07:00
|
|
|
#include "c-ctype.h"
|
2004-04-09 12:03:02 +00:00
|
|
|
#include "file-type.h"
|
2010-05-01 11:29:39 +02:00
|
|
|
#include "filemode.h"
|
2002-04-13 14:11:44 +00:00
|
|
|
#include "fs.h"
|
2010-07-15 19:54:49 -06:00
|
|
|
#include "mountlist.h"
|
2024-05-05 12:54:59 +03:00
|
|
|
#include "octhexdigits.h"
|
2002-07-13 08:05:04 +00:00
|
|
|
#include "quote.h"
|
2011-06-11 16:28:34 +01:00
|
|
|
#include "stat-size.h"
|
2005-09-16 07:50:33 +00:00
|
|
|
#include "stat-time.h"
|
2002-12-15 20:45:36 +00:00
|
|
|
#include "strftime.h"
|
2010-07-15 19:54:49 -06:00
|
|
|
#include "find-mount-point.h"
|
2010-10-01 11:44:05 -06:00
|
|
|
#include "xvasprintf.h"
|
ls: use statx instead of stat when available
statx allows ls to indicate interest in only certain inode metadata.
This is potentially a win on networked/clustered/distributed
file systems. In cases where we'd have to do a full, heavyweight stat()
call we can now do a much lighter statx() call.
As a real-world example, consider a file system like CephFS where one
client is actively writing to a file and another client does an
ls --color in the same directory. --color means that we need to fetch
the mode of the file.
Doing that with a stat() call means that we have to fetch the size and
mtime in addition to the mode. The MDS in that situation will have to
revoke caps in order to ensure that it has up-to-date values to report,
which disrupts the writer.
This has a measurable affect on performance. I ran a fio sequential
write test on one cephfs client and had a second client do "ls --color"
in a tight loop on the directory that held the file:
Baseline -- no activity on the second client:
WRITE: bw=76.7MiB/s (80.4MB/s), 76.7MiB/s-76.7MiB/s (80.4MB/s-80.4MB/s),
io=4600MiB (4824MB), run=60016-60016msec
Without this patch series, we see a noticable performance hit:
WRITE: bw=70.4MiB/s (73.9MB/s), 70.4MiB/s-70.4MiB/s (73.9MB/s-73.9MB/s),
io=4228MiB (4433MB), run=60012-60012msec
With this patch series, we gain most of that ground back:
WRITE: bw=75.9MiB/s (79.6MB/s), 75.9MiB/s-75.9MiB/s (79.6MB/s-79.6MB/s),
io=4555MiB (4776MB), run=60019-60019msec
* src/stat.c: move statx to stat struct conversion to new header...
* src/statx.h: ...here.
* src/ls.c: Add wrapper functions for stat/lstat/fstat calls,
and add variants for when we are only interested in specific info.
Add statx-enabled functions and set the request mask based on the
output format and what values are needed.
* NEWS: Mention the Improvement.
2019-09-19 11:59:45 -04:00
|
|
|
#include "statx.h"
|
2006-09-01 19:40:46 +00:00
|
|
|
|
2019-06-14 14:37:43 -04:00
|
|
|
#if HAVE_STATX && defined STATX_INO
|
|
|
|
|
# define USE_STATX 1
|
|
|
|
|
#else
|
|
|
|
|
# define USE_STATX 0
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-04-12 20:14:42 +00:00
|
|
|
#if USE_STATVFS
|
2006-09-01 19:40:46 +00:00
|
|
|
# define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATVFS_F_FSID_IS_INTEGER
|
2004-09-03 21:58:36 +00:00
|
|
|
# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS_F_TYPE
|
2002-06-21 12:34:36 +00:00
|
|
|
# if HAVE_STRUCT_STATVFS_F_NAMEMAX
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
# define SB_F_NAMEMAX(S) ((S)->f_namemax)
|
2002-06-21 12:34:36 +00:00
|
|
|
# endif
|
2011-09-08 11:52:55 +02:00
|
|
|
# if ! STAT_STATVFS && STAT_STATVFS64
|
2015-06-05 17:33:54 -07:00
|
|
|
# define STRUCT_STATVFS struct statvfs64
|
2011-09-08 11:52:55 +02:00
|
|
|
# define STATFS statvfs64
|
|
|
|
|
# else
|
2015-06-05 17:33:54 -07:00
|
|
|
# define STRUCT_STATVFS struct statvfs
|
2011-09-08 11:52:55 +02:00
|
|
|
# define STATFS statvfs
|
|
|
|
|
# endif
|
2006-04-12 20:14:42 +00:00
|
|
|
# define STATFS_FRSIZE(S) ((S)->f_frsize)
|
2002-06-21 12:34:36 +00:00
|
|
|
#else
|
2004-09-03 21:58:36 +00:00
|
|
|
# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATFS_F_TYPE
|
2002-06-21 12:34:36 +00:00
|
|
|
# if HAVE_STRUCT_STATFS_F_NAMELEN
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
# define SB_F_NAMEMAX(S) ((S)->f_namelen)
|
2017-08-29 23:42:54 -07:00
|
|
|
# elif HAVE_STRUCT_STATFS_F_NAMEMAX
|
|
|
|
|
# define SB_F_NAMEMAX(S) ((S)->f_namemax)
|
2002-06-21 12:34:36 +00:00
|
|
|
# endif
|
2004-11-17 03:12:06 +00:00
|
|
|
# define STATFS statfs
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
# if HAVE_OS_H /* BeOS */
|
|
|
|
|
/* BeOS has a statvfs function, but it does not return sensible values
|
|
|
|
|
for f_files, f_ffree and f_favail, and lacks f_type, f_basetype and
|
|
|
|
|
f_fstypename. Use 'struct fs_info' instead. */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static int
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
statfs (char const *filename, struct fs_info *buf)
|
|
|
|
|
{
|
|
|
|
|
dev_t device = dev_for_path (filename);
|
|
|
|
|
if (device < 0)
|
|
|
|
|
{
|
|
|
|
|
errno = (device == B_ENTRY_NOT_FOUND ? ENOENT
|
2009-08-22 18:56:06 +02:00
|
|
|
: device == B_BAD_VALUE ? EINVAL
|
|
|
|
|
: device == B_NAME_TOO_LONG ? ENAMETOOLONG
|
|
|
|
|
: device == B_NO_MEMORY ? ENOMEM
|
|
|
|
|
: device == B_FILE_ERROR ? EIO
|
|
|
|
|
: 0);
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
/* If successful, buf->dev will be == device. */
|
|
|
|
|
return fs_stat_dev (device, buf);
|
|
|
|
|
}
|
|
|
|
|
# define f_fsid dev
|
|
|
|
|
# define f_blocks total_blocks
|
|
|
|
|
# define f_bfree free_blocks
|
|
|
|
|
# define f_bavail free_blocks
|
|
|
|
|
# define f_bsize io_size
|
|
|
|
|
# define f_files total_nodes
|
|
|
|
|
# define f_ffree free_nodes
|
|
|
|
|
# define STRUCT_STATVFS struct fs_info
|
2006-09-01 19:40:46 +00:00
|
|
|
# define STRUCT_STATXFS_F_FSID_IS_INTEGER true
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
# define STATFS_FRSIZE(S) ((S)->block_size)
|
|
|
|
|
# else
|
|
|
|
|
# define STRUCT_STATVFS struct statfs
|
2006-09-01 19:40:46 +00:00
|
|
|
# define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATFS_F_FSID_IS_INTEGER
|
2012-05-15 19:56:21 +01:00
|
|
|
# if HAVE_STRUCT_STATFS_F_FRSIZE
|
|
|
|
|
# define STATFS_FRSIZE(S) ((S)->f_frsize)
|
|
|
|
|
# else
|
|
|
|
|
# define STATFS_FRSIZE(S) 0
|
|
|
|
|
# endif
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
# endif
|
2004-11-17 03:12:06 +00:00
|
|
|
#endif
|
|
|
|
|
|
2006-04-12 20:14:42 +00:00
|
|
|
#ifdef SB_F_NAMEMAX
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
# define OUT_NAMEMAX out_uint
|
2006-04-12 20:14:42 +00:00
|
|
|
#else
|
2017-08-29 23:42:54 -07:00
|
|
|
/* Depending on whether statvfs or statfs is used,
|
|
|
|
|
neither f_namemax or f_namelen may be available. */
|
|
|
|
|
# define SB_F_NAMEMAX(S) "?"
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
# define OUT_NAMEMAX out_string
|
2002-06-21 12:34:36 +00:00
|
|
|
#endif
|
|
|
|
|
|
2003-03-22 21:32:22 +00:00
|
|
|
#if HAVE_STRUCT_STATVFS_F_BASETYPE
|
|
|
|
|
# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_basetype
|
|
|
|
|
#else
|
2006-08-18 18:36:04 +00:00
|
|
|
# if HAVE_STRUCT_STATVFS_F_FSTYPENAME || HAVE_STRUCT_STATFS_F_FSTYPENAME
|
2003-03-22 22:32:12 +00:00
|
|
|
# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_fstypename
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
# elif HAVE_OS_H /* BeOS */
|
|
|
|
|
# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME fsh_name
|
2003-03-22 21:32:22 +00:00
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
2014-03-18 16:12:26 -07:00
|
|
|
#if HAVE_GETATTRAT
|
|
|
|
|
# include <attr.h>
|
|
|
|
|
# include <sys/nvpair.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2010-11-06 13:57:08 -07:00
|
|
|
static char const digits[] = "0123456789";
|
|
|
|
|
|
|
|
|
|
/* Flags that are portable for use in printf, for at least one
|
2023-08-28 12:42:23 -07:00
|
|
|
conversion specifier; make_format removes non-portable flags as
|
2010-11-06 13:57:08 -07:00
|
|
|
needed for particular specifiers. The glibc 2.2 extension "I" is
|
|
|
|
|
listed here; it is removed by make_format because it has undefined
|
|
|
|
|
behavior elsewhere and because it is incompatible with
|
|
|
|
|
out_epoch_sec. */
|
|
|
|
|
static char const printf_flags[] = "'-+ #0I";
|
|
|
|
|
|
2017-10-11 22:33:28 +02:00
|
|
|
/* Formats for the --terse option. */
|
|
|
|
|
static char const fmt_terse_fs[] = "%n %i %l %t %s %S %b %f %a %c %d\n";
|
|
|
|
|
static char const fmt_terse_regular[] = "%n %s %b %f %u %g %D %i %h %t %T"
|
|
|
|
|
" %X %Y %Z %W %o\n";
|
|
|
|
|
static char const fmt_terse_selinux[] = "%n %s %b %f %u %g %D %i %h %t %T"
|
|
|
|
|
" %X %Y %Z %W %o %C\n";
|
|
|
|
|
|
2002-04-13 14:11:44 +00:00
|
|
|
#define PROGRAM_NAME "stat"
|
|
|
|
|
|
2008-05-19 16:24:27 +02:00
|
|
|
#define AUTHORS proper_name ("Michael Meskes")
|
2002-04-13 14:11:44 +00:00
|
|
|
|
2005-12-15 12:24:30 +00:00
|
|
|
enum
|
|
|
|
|
{
|
2006-11-27 11:27:46 +01:00
|
|
|
PRINTF_OPTION = CHAR_MAX + 1
|
2005-12-15 12:24:30 +00:00
|
|
|
};
|
|
|
|
|
|
2019-05-28 08:21:42 -04:00
|
|
|
enum cached_mode
|
|
|
|
|
{
|
|
|
|
|
cached_default,
|
|
|
|
|
cached_never,
|
|
|
|
|
cached_always
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static char const *const cached_args[] =
|
|
|
|
|
{
|
2026-01-18 15:55:38 +00:00
|
|
|
"default", "never", "always", NULL
|
2019-05-28 08:21:42 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static enum cached_mode const cached_modes[] =
|
|
|
|
|
{
|
|
|
|
|
cached_default, cached_never, cached_always
|
|
|
|
|
};
|
|
|
|
|
|
remove redundant const directives
In 1463824d8e7f72c31f1d803d7cfe2b608ccafc5c, I added some
missing "const" directives, as well as some new, redundant ones.
This removes the redundant ones. Pointed out by Eric Blake.
* base64.c, cat.c, chcon.c, chgrp.c, chmod.c, chown.c, comm.c:
* cp.c, csplit.c, cut.c, date.c, dd.c, df.c, dircolors.c, du.c:
* env.c, expand.c, fmt.c, fold.c, groups.c, head.c, id.c:
* install.c, join.c, kill.c, ln.c, ls.c, md5sum.c, mkdir.c:
* mkfifo.c, mknod.c, mktemp.c, mv.c, nice.c, nl.c, od.c:
* paste.c, pathchk.c, pinky.c, pr.c, ptx.c, readlink.c, rm.c:
* rmdir.c, runcon.c, seq.c, shred.c, shuf.c, sort.c, split.c:
* stat.c, stty.c, su.c, sum.c, tac.c, tail.c, tee.c, timeout.c:
* touch.c, tr.c, truncate.c, tty.c, uname.c, unexpand.c, uniq.c:
* wc.c, who.c: Remove redundant const directives.
* maint.mk (sc_const_long_option): Don't require redundant "const".
2008-06-16 14:55:06 +02:00
|
|
|
static struct option const long_options[] =
|
add "const" attribute, where possible
* maint.mk (sc_const_long_option): New rule. Enforce global change.
* src/base64.c (long_options): Use "const" where possible.
* src/cat.c (main): Likewise.
* src/chcon.c (long_options): Likewise.
* src/chgrp.c (long_options): Likewise.
* src/chmod.c (long_options): Likewise.
* src/chown.c (long_options): Likewise.
* src/comm.c (long_options, OUTPUT_DELIMITER_OPTION): Likewise.
* src/cp.c (long_opts): Likewise.
* src/csplit.c (longopts): Likewise.
* src/cut.c (longopts): Likewise.
* src/date.c (long_options): Likewise.
* src/dd.c (conversions, flags, statuses): Likewise.
* src/df.c (long_options): Likewise.
* src/dircolors.c (long_options): Likewise.
* src/du.c (long_options): Likewise.
* src/env.c (longopts): Likewise.
* src/expand.c (longopts): Likewise.
* src/fmt.c (long_options): Likewise.
* src/fold.c (longopts): Likewise.
* src/groups.c (longopts): Likewise.
* src/head.c (long_options): Likewise.
* src/id.c (longopts): Likewise.
* src/install.c (long_options): Likewise.
* src/join.c (longopts): Likewise.
* src/kill.c (long_options): Likewise.
* src/ln.c (long_options): Likewise.
* src/ls.c (long_time_format, long_options, sort_functions): Likewise.
* src/md5sum.c (long_options): Likewise.
* src/mkdir.c (longopts): Likewise.
* src/mkfifo.c (longopts): Likewise.
* src/mknod.c (longopts): Likewise.
* src/mktemp.c (longopts): Likewise.
* src/mv.c (long_options): Likewise.
* src/nice.c (longopts): Likewise.
* src/nl.c (longopts): Likewise.
* src/od.c (charname, long_options): Likewise.
* src/paste.c (longopts): Likewise.
* src/pathchk.c (longopts): Likewise.
* src/pinky.c (longopts): Likewise.
* src/pr.c (long_options): Likewise.
* src/ptx.c (long_options): Likewise.
* src/readlink.c (longopts): Likewise.
* src/rm.c (long_opts): Likewise.
* src/rmdir.c (longopts): Likewise.
* src/runcon.c (long_options): Likewise.
* src/seq.c (long_options): Likewise.
* src/shred.c (long_opts): Likewise.
* src/shuf.c (long_opts): Likewise.
* src/sort.c (monthtab, long_options): Likewise.
* src/split.c (longopts): Likewise.
* src/stat.c (long_options): Likewise.
* src/stty.c (mode_info, control_info, longopts, set_mode) Likewise.
(set_control_char, speeds): Likewise.
* src/su.c (longopts): Likewise.
* src/sum.c (longopts): Likewise.
* src/tac.c (longopts): Likewise.
* src/tail.c (long_options): Likewise.
* src/tee.c (long_options): Likewise.
* src/timeout.c (long_options): Likewise.
* src/touch.c (longopts): Likewise.
* src/tr.c (long_options): Likewise.
* src/truncate.c (longopts): Likewise.
* src/tty.c (longopts): Likewise.
* src/uname.c (uname_long_options, arch_long_options): Likewise.
* src/unexpand.c (longopts): Likewise.
* src/uniq.c (longopts): Likewise.
* src/wc.c (longopts): Likewise.
* src/who.c (longopts): Likewise.
2008-06-12 22:06:15 +02:00
|
|
|
{
|
2026-01-18 15:55:38 +00:00
|
|
|
{"dereference", no_argument, NULL, 'L'},
|
|
|
|
|
{"file-system", no_argument, NULL, 'f'},
|
|
|
|
|
{"format", required_argument, NULL, 'c'},
|
|
|
|
|
{"printf", required_argument, NULL, PRINTF_OPTION},
|
|
|
|
|
{"terse", no_argument, NULL, 't'},
|
|
|
|
|
{"cached", required_argument, NULL, 0},
|
2002-04-13 14:11:44 +00:00
|
|
|
{GETOPT_HELP_OPTION_DECL},
|
|
|
|
|
{GETOPT_VERSION_OPTION_DECL},
|
2026-01-18 15:55:38 +00:00
|
|
|
{NULL, 0, NULL, 0}
|
2002-04-13 14:11:44 +00:00
|
|
|
};
|
2002-04-13 13:47:14 +00:00
|
|
|
|
2007-01-07 09:15:42 +01:00
|
|
|
/* Whether to follow symbolic links; True for --dereference (-L). */
|
|
|
|
|
static bool follow_links;
|
|
|
|
|
|
2005-12-15 12:24:30 +00:00
|
|
|
/* Whether to interpret backslash-escape sequences.
|
|
|
|
|
True for --printf=FMT, not for --format=FMT (-c). */
|
|
|
|
|
static bool interpret_backslash_escapes;
|
|
|
|
|
|
|
|
|
|
/* The trailing delimiter string:
|
|
|
|
|
"" for --printf=FMT, "\n" for --format=FMT (-c). */
|
|
|
|
|
static char const *trailing_delim = "";
|
|
|
|
|
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
/* The representation of the decimal point in the current locale. */
|
|
|
|
|
static char const *decimal_point;
|
|
|
|
|
static size_t decimal_point_len;
|
|
|
|
|
|
2019-05-28 08:21:42 -04:00
|
|
|
static bool
|
2021-06-20 15:16:49 +01:00
|
|
|
print_stat (char *pformat, size_t prefix_len, char mod, char m,
|
2019-05-28 08:21:42 -04:00
|
|
|
int fd, char const *filename, void const *data);
|
|
|
|
|
|
2002-06-21 12:34:36 +00:00
|
|
|
/* Return the type of the specified file system.
|
2006-08-18 18:36:04 +00:00
|
|
|
Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, and Solaris).
|
|
|
|
|
Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0).
|
|
|
|
|
Others have statfs.f_fstypename[MFSNAMELEN] (NetBSD 1.5.2).
|
2009-04-06 07:43:49 +01:00
|
|
|
Still others have neither and have to get by with f_type (GNU/Linux).
|
2006-08-20 15:17:27 +00:00
|
|
|
But f_type may only exist in statfs (Cygwin). */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static char const *
|
2002-06-21 12:34:36 +00:00
|
|
|
human_fstype (STRUCT_STATVFS const *statfsbuf)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2003-03-22 21:32:22 +00:00
|
|
|
#ifdef STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME
|
2004-09-03 21:58:36 +00:00
|
|
|
return statfsbuf->STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME;
|
2002-06-21 12:34:36 +00:00
|
|
|
#else
|
2002-04-13 13:47:14 +00:00
|
|
|
switch (statfsbuf->f_type)
|
2002-04-13 14:34:58 +00:00
|
|
|
{
|
2019-01-29 20:32:53 -08:00
|
|
|
# if defined __linux__ || defined __ANDROID__
|
2003-04-10 19:09:30 +00:00
|
|
|
|
2007-08-27 23:46:49 +02:00
|
|
|
/* Compare with what's in libc:
|
2009-08-22 18:56:06 +02:00
|
|
|
f=/a/libc/sysdeps/unix/sysv/linux/linux_fsinfo.h
|
|
|
|
|
sed -n '/ADFS_SUPER_MAGIC/,/SYSFS_MAGIC/p' $f \
|
|
|
|
|
| perl -n -e '/#define (.*?)_(?:SUPER_)MAGIC\s+0x(\S+)/' \
|
|
|
|
|
-e 'and print "case S_MAGIC_$1: /\* 0x" . uc($2) . " *\/\n"' \
|
|
|
|
|
| sort > sym_libc
|
|
|
|
|
perl -ne '/^\s+(case S_MAGIC_.*?): \/\* 0x(\S+) \*\//' \
|
|
|
|
|
-e 'and do { $v=uc$2; print "$1: /\* 0x$v *\/\n"}' stat.c \
|
|
|
|
|
| sort > sym_stat
|
|
|
|
|
diff -u sym_stat sym_libc
|
2007-08-27 23:46:49 +02:00
|
|
|
*/
|
|
|
|
|
|
2009-12-21 18:43:02 +00:00
|
|
|
/* Also compare with the list in "man 2 statfs" using the
|
|
|
|
|
fs-magic-compare make target. */
|
2007-08-28 00:14:20 +02:00
|
|
|
|
2012-01-08 21:03:22 +01:00
|
|
|
/* IMPORTANT NOTE: Each of the following 'case S_MAGIC_...:'
|
2009-08-22 18:56:06 +02:00
|
|
|
statements must be followed by a hexadecimal constant in
|
|
|
|
|
a comment. The S_MAGIC_... name and constant are automatically
|
|
|
|
|
combined to produce the #define directives in fs.h. */
|
2003-04-10 19:09:30 +00:00
|
|
|
|
2017-08-29 01:04:32 -07:00
|
|
|
case S_MAGIC_AAFS: /* 0x5A3C69F0 local */
|
|
|
|
|
return "aafs";
|
2015-11-11 14:39:32 +00:00
|
|
|
case S_MAGIC_ACFS: /* 0x61636673 remote */
|
|
|
|
|
return "acfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_ADFS: /* 0xADF5 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "adfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_AFFS: /* 0xADFF local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "affs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_AFS: /* 0x5346414F remote */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "afs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_ANON_INODE_FS: /* 0x09041934 local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "anon-inode FS";
|
2012-06-30 18:19:53 +02:00
|
|
|
case S_MAGIC_AUFS: /* 0x61756673 remote */
|
|
|
|
|
/* FIXME: change syntax or add an optional attribute like "inotify:no".
|
|
|
|
|
The above is labeled as "remote" so that tail always uses polling,
|
|
|
|
|
but this isn't really a remote file system type. */
|
|
|
|
|
return "aufs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_AUTOFS: /* 0x0187 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "autofs";
|
2016-11-26 16:10:53 +00:00
|
|
|
case S_MAGIC_BALLOON_KVM: /* 0x13661366 local */
|
|
|
|
|
return "balloon-kvm-fs";
|
2024-05-28 13:29:15 +01:00
|
|
|
case S_MAGIC_BCACHEFS: /* 0xCA451A4E local */
|
|
|
|
|
return "bcachefs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_BEFS: /* 0x42465331 local */
|
2007-08-28 00:14:20 +02:00
|
|
|
return "befs";
|
2012-05-10 15:46:08 +02:00
|
|
|
case S_MAGIC_BDEVFS: /* 0x62646576 local */
|
|
|
|
|
return "bdevfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_BFS: /* 0x1BADFACE local */
|
2007-08-28 00:14:20 +02:00
|
|
|
return "bfs";
|
2020-02-09 14:10:50 +00:00
|
|
|
case S_MAGIC_BINDERFS: /* 0x6C6F6F70 local */
|
|
|
|
|
return "binderfs";
|
2015-11-11 14:39:32 +00:00
|
|
|
case S_MAGIC_BPF_FS: /* 0xCAFE4A11 local */
|
|
|
|
|
return "bpf_fs";
|
2012-05-10 15:46:08 +02:00
|
|
|
case S_MAGIC_BINFMTFS: /* 0x42494E4D local */
|
2007-08-28 00:14:20 +02:00
|
|
|
return "binfmt_misc";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_BTRFS: /* 0x9123683E local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "btrfs";
|
2015-11-11 14:39:32 +00:00
|
|
|
case S_MAGIC_BTRFS_TEST: /* 0x73727279 local */
|
|
|
|
|
return "btrfs_test";
|
2012-12-15 00:13:55 +01:00
|
|
|
case S_MAGIC_CEPH: /* 0x00C36400 remote */
|
|
|
|
|
return "ceph";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_CGROUP: /* 0x0027E0EB local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "cgroupfs";
|
2016-11-26 16:10:53 +00:00
|
|
|
case S_MAGIC_CGROUP2: /* 0x63677270 local */
|
|
|
|
|
return "cgroup2fs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_CIFS: /* 0xFF534D42 remote */
|
2009-10-08 09:05:08 +02:00
|
|
|
return "cifs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_CODA: /* 0x73757245 remote */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "coda";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_COH: /* 0x012FF7B7 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "coh";
|
2014-05-23 00:20:43 +01:00
|
|
|
case S_MAGIC_CONFIGFS: /* 0x62656570 local */
|
|
|
|
|
return "configfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_CRAMFS: /* 0x28CD3D45 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "cramfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_CRAMFS_WEND: /* 0x453DCD28 local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "cramfs-wend";
|
2016-11-26 16:10:53 +00:00
|
|
|
case S_MAGIC_DAXFS: /* 0x64646178 local */
|
|
|
|
|
return "daxfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_DEBUGFS: /* 0x64626720 local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "debugfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_DEVFS: /* 0x1373 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "devfs";
|
2020-10-27 20:15:43 +00:00
|
|
|
case S_MAGIC_DEVMEM: /* 0x454D444D local */
|
|
|
|
|
return "devmem";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_DEVPTS: /* 0x1CD1 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "devpts";
|
2020-02-09 14:10:50 +00:00
|
|
|
case S_MAGIC_DMA_BUF: /* 0x444D4142 local */
|
|
|
|
|
return "dma-buf-fs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_ECRYPTFS: /* 0xF15F local */
|
2011-04-25 14:40:45 +02:00
|
|
|
return "ecryptfs";
|
2013-03-22 12:15:04 +00:00
|
|
|
case S_MAGIC_EFIVARFS: /* 0xDE5E81E4 local */
|
|
|
|
|
return "efivarfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_EFS: /* 0x00414A53 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "efs";
|
2020-02-09 14:10:50 +00:00
|
|
|
case S_MAGIC_EROFS_V1: /* 0xE0F5E1E2 local */
|
|
|
|
|
return "erofs";
|
2021-02-18 11:18:04 +01:00
|
|
|
case S_MAGIC_EXFAT: /* 0x2011BAB0 local */
|
|
|
|
|
return "exfat";
|
2018-01-09 21:43:24 +00:00
|
|
|
case S_MAGIC_EXFS: /* 0x45584653 local */
|
|
|
|
|
return "exfs";
|
2013-03-22 12:15:04 +00:00
|
|
|
case S_MAGIC_EXOFS: /* 0x5DF5 local */
|
|
|
|
|
return "exofs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_EXT: /* 0x137D local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "ext";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_EXT2: /* 0xEF53 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "ext2/ext3";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_EXT2_OLD: /* 0xEF51 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "ext2";
|
2013-03-22 12:15:04 +00:00
|
|
|
case S_MAGIC_F2FS: /* 0xF2F52010 local */
|
|
|
|
|
return "f2fs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_FAT: /* 0x4006 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "fat";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_FHGFS: /* 0x19830326 remote */
|
2011-12-22 09:26:31 +01:00
|
|
|
return "fhgfs";
|
2024-05-28 13:29:15 +01:00
|
|
|
case S_MAGIC_FUSE: /* 0x65735546 remote */
|
|
|
|
|
return "fuse";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_FUSECTL: /* 0x65735543 remote */
|
2007-08-28 00:14:20 +02:00
|
|
|
return "fusectl";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_FUTEXFS: /* 0x0BAD1DEA local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "futexfs";
|
2014-05-22 02:16:14 +01:00
|
|
|
case S_MAGIC_GFS: /* 0x01161970 remote */
|
2009-12-22 12:21:45 +00:00
|
|
|
return "gfs/gfs2";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_GPFS: /* 0x47504653 remote */
|
2011-07-05 22:49:56 +02:00
|
|
|
return "gpfs";
|
2026-01-21 16:29:03 +00:00
|
|
|
case S_MAGIC_GUEST_MEMFD: /* 0x474D454D remote */
|
|
|
|
|
return "guest-memfd";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_HFS: /* 0x4244 local */
|
2009-10-08 09:05:08 +02:00
|
|
|
return "hfs";
|
2014-01-29 01:17:53 +00:00
|
|
|
case S_MAGIC_HFS_PLUS: /* 0x482B local */
|
|
|
|
|
return "hfs+";
|
|
|
|
|
case S_MAGIC_HFS_X: /* 0x4858 local */
|
|
|
|
|
return "hfsx";
|
2014-05-22 02:16:14 +01:00
|
|
|
case S_MAGIC_HOSTFS: /* 0x00C0FFEE local */
|
2013-12-13 14:05:53 +00:00
|
|
|
return "hostfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_HPFS: /* 0xF995E849 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "hpfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_HUGETLBFS: /* 0x958458F6 local */
|
2007-08-28 00:14:20 +02:00
|
|
|
return "hugetlbfs";
|
2012-05-10 15:46:08 +02:00
|
|
|
case S_MAGIC_MTD_INODE_FS: /* 0x11307854 local */
|
|
|
|
|
return "inodefs";
|
2015-02-27 18:52:51 +01:00
|
|
|
case S_MAGIC_IBRIX: /* 0x013111A8 remote */
|
|
|
|
|
return "ibrix";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_INOTIFYFS: /* 0x2BAD1DEA local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "inotifyfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_ISOFS: /* 0x9660 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "isofs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_ISOFS_R_WIN: /* 0x4004 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "isofs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_ISOFS_WIN: /* 0x4000 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "isofs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_JFFS: /* 0x07C0 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "jffs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_JFFS2: /* 0x72B6 local */
|
2009-10-08 09:05:08 +02:00
|
|
|
return "jffs2";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_JFS: /* 0x3153464A local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "jfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_KAFS: /* 0x6B414653 remote */
|
2009-12-22 12:21:45 +00:00
|
|
|
return "k-afs";
|
2014-05-23 00:20:43 +01:00
|
|
|
case S_MAGIC_LOGFS: /* 0xC97E8168 local */
|
|
|
|
|
return "logfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_LUSTRE: /* 0x0BD00BD0 remote */
|
2008-10-06 10:17:19 -06:00
|
|
|
return "lustre";
|
2016-04-13 16:15:20 +03:00
|
|
|
case S_MAGIC_M1FS: /* 0x5346314D local */
|
|
|
|
|
return "m1fs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_MINIX: /* 0x137F local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "minix";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_MINIX_30: /* 0x138F local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "minix (30 char.)";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_MINIX_V2: /* 0x2468 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "minix v2";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_MINIX_V2_30: /* 0x2478 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "minix v2 (30 char.)";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_MINIX_V3: /* 0x4D5A local */
|
2009-12-21 18:43:02 +00:00
|
|
|
return "minix3";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_MQUEUE: /* 0x19800202 local */
|
2011-06-24 08:22:06 +01:00
|
|
|
return "mqueue";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_MSDOS: /* 0x4D44 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "msdos";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_NCP: /* 0x564C remote */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "novell";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_NFS: /* 0x6969 remote */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "nfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_NFSD: /* 0x6E667364 remote */
|
2007-08-28 00:14:20 +02:00
|
|
|
return "nfsd";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_NILFS: /* 0x3434 local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "nilfs";
|
2015-11-11 14:39:32 +00:00
|
|
|
case S_MAGIC_NSFS: /* 0x6E736673 local */
|
|
|
|
|
return "nsfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_NTFS: /* 0x5346544E local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "ntfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_OPENPROM: /* 0x9FA1 local */
|
2007-08-28 00:14:20 +02:00
|
|
|
return "openprom";
|
2014-05-22 02:16:14 +01:00
|
|
|
case S_MAGIC_OCFS2: /* 0x7461636F remote */
|
2009-12-22 12:21:45 +00:00
|
|
|
return "ocfs2";
|
2015-12-13 14:58:53 +00:00
|
|
|
case S_MAGIC_OVERLAYFS: /* 0x794C7630 remote */
|
|
|
|
|
/* This may overlay remote file systems.
|
|
|
|
|
Also there have been issues reported with inotify and overlayfs,
|
|
|
|
|
so mark as "remote" so that polling is used. */
|
|
|
|
|
return "overlayfs";
|
2012-06-01 09:14:25 +02:00
|
|
|
case S_MAGIC_PANFS: /* 0xAAD7AAEA remote */
|
|
|
|
|
return "panfs";
|
2024-05-28 13:29:15 +01:00
|
|
|
case S_MAGIC_PID_FS: /* 0x50494446 local */
|
|
|
|
|
return "pidfs";
|
2011-12-26 16:09:48 +01:00
|
|
|
case S_MAGIC_PIPEFS: /* 0x50495045 remote */
|
|
|
|
|
/* FIXME: change syntax or add an optional attribute like "inotify:no".
|
2025-11-12 14:06:44 +00:00
|
|
|
pipefs is labeled as "remote" so that tail always polls,
|
|
|
|
|
but it isn't really remote file system type. */
|
2011-12-26 16:09:48 +01:00
|
|
|
return "pipefs";
|
2020-02-09 14:10:50 +00:00
|
|
|
case S_MAGIC_PPC_CMM: /* 0xC7571590 local */
|
|
|
|
|
return "ppc-cmm-fs";
|
2016-03-31 16:34:28 +01:00
|
|
|
case S_MAGIC_PRL_FS: /* 0x7C7C6673 remote */
|
|
|
|
|
return "prl_fs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_PROC: /* 0x9FA0 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "proc";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_PSTOREFS: /* 0x6165676C local */
|
2011-06-24 08:22:06 +01:00
|
|
|
return "pstorefs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_QNX4: /* 0x002F local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "qnx4";
|
2012-05-10 15:46:08 +02:00
|
|
|
case S_MAGIC_QNX6: /* 0x68191122 local */
|
|
|
|
|
return "qnx6";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_RAMFS: /* 0x858458F6 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "ramfs";
|
2017-03-08 17:48:15 -08:00
|
|
|
case S_MAGIC_RDTGROUP: /* 0x07655821 local */
|
|
|
|
|
return "rdt";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_REISERFS: /* 0x52654973 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "reiserfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_ROMFS: /* 0x7275 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "romfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_RPC_PIPEFS: /* 0x67596969 local */
|
2009-12-21 18:43:02 +00:00
|
|
|
return "rpc_pipefs";
|
2019-01-29 20:32:53 -08:00
|
|
|
case S_MAGIC_SDCARDFS: /* 0x5DCA2DF5 local */
|
|
|
|
|
return "sdcardfs";
|
2021-09-16 15:21:05 +01:00
|
|
|
case S_MAGIC_SECRETMEM: /* 0x5345434D local */
|
|
|
|
|
return "secretmem";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_SECURITYFS: /* 0x73636673 local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "securityfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_SELINUX: /* 0xF97CFF8C local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "selinux";
|
2013-12-13 14:05:53 +00:00
|
|
|
case S_MAGIC_SMACK: /* 0x43415D53 local */
|
|
|
|
|
return "smackfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_SMB: /* 0x517B remote */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "smb";
|
2016-05-12 09:50:48 +01:00
|
|
|
case S_MAGIC_SMB2: /* 0xFE534D42 remote */
|
|
|
|
|
return "smb2";
|
2013-04-24 22:59:46 +01:00
|
|
|
case S_MAGIC_SNFS: /* 0xBEEFDEAD remote */
|
|
|
|
|
return "snfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_SOCKFS: /* 0x534F434B local */
|
2009-12-13 11:00:41 +01:00
|
|
|
return "sockfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_SQUASHFS: /* 0x73717368 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "squashfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_SYSFS: /* 0x62656572 local */
|
2004-09-03 21:58:36 +00:00
|
|
|
return "sysfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_SYSV2: /* 0x012FF7B6 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "sysv2";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_SYSV4: /* 0x012FF7B5 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "sysv4";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_TMPFS: /* 0x01021994 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "tmpfs";
|
2015-11-11 14:39:32 +00:00
|
|
|
case S_MAGIC_TRACEFS: /* 0x74726163 local */
|
|
|
|
|
return "tracefs";
|
2013-03-22 12:15:04 +00:00
|
|
|
case S_MAGIC_UBIFS: /* 0x24051905 local */
|
|
|
|
|
return "ubifs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_UDF: /* 0x15013346 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "udf";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_UFS: /* 0x00011954 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "ufs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_UFS_BYTESWAPPED: /* 0x54190100 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "ufs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_USBDEVFS: /* 0x9FA2 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "usbdevfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_V9FS: /* 0x01021997 local */
|
2011-04-25 14:40:45 +02:00
|
|
|
return "v9fs";
|
2020-06-19 20:33:55 +02:00
|
|
|
case S_MAGIC_VBOXSF: /* 0x786F4256 remote */
|
|
|
|
|
return "vboxsf";
|
2012-09-19 21:52:05 +02:00
|
|
|
case S_MAGIC_VMHGFS: /* 0xBACBACBC remote */
|
|
|
|
|
return "vmhgfs";
|
2014-06-13 09:16:31 +01:00
|
|
|
case S_MAGIC_VXFS: /* 0xA501FCF5 remote */
|
|
|
|
|
/* Veritas File System can run in single instance or clustered mode,
|
|
|
|
|
so mark as remote to cater for the latter case. */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "vxfs";
|
2012-09-05 22:33:44 +02:00
|
|
|
case S_MAGIC_VZFS: /* 0x565A4653 local */
|
|
|
|
|
return "vzfs";
|
2016-04-21 21:48:50 +01:00
|
|
|
case S_MAGIC_WSLFS: /* 0x53464846 local */
|
|
|
|
|
return "wslfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_XENFS: /* 0xABBA1974 local */
|
stat: add support for many more file system types
* src/stat.c (human_fstype): Add the following FS types,
from <linux/magic.h>: afs, anon-inode FS, btrfs, cgroupfs,
cramfs-wend, debugfs, futexfs, inotifyfs, minux3, securityfs,
selinux, xenfs.
Also add "nilfs".
* src/Makefile.am (fs-kernel-magic): New rule.
* NEWS (Bug fixes): Mention this.
2009-10-08 10:06:42 +02:00
|
|
|
return "xenfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_XENIX: /* 0x012FF7B4 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "xenix";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_XFS: /* 0x58465342 local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "xfs";
|
2011-12-22 23:23:02 +01:00
|
|
|
case S_MAGIC_XIAFS: /* 0x012FD16D local */
|
2007-08-27 23:46:49 +02:00
|
|
|
return "xia";
|
2020-02-09 14:10:50 +00:00
|
|
|
case S_MAGIC_Z3FOLD: /* 0x0033 local */
|
|
|
|
|
return "z3fold";
|
2012-08-29 09:32:49 +02:00
|
|
|
case S_MAGIC_ZFS: /* 0x2FC12FC1 local */
|
|
|
|
|
return "zfs";
|
2020-10-27 20:15:43 +00:00
|
|
|
case S_MAGIC_ZONEFS: /* 0x5A4F4653 local */
|
|
|
|
|
return "zonefs";
|
2016-11-26 16:10:53 +00:00
|
|
|
case S_MAGIC_ZSMALLOC: /* 0x58295829 local */
|
|
|
|
|
return "zsmallocfs";
|
|
|
|
|
|
2007-08-27 23:46:49 +02:00
|
|
|
|
2003-03-22 21:32:22 +00:00
|
|
|
# elif __GNU__
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_UFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "ufs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_NFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "nfs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_GFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "gfs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_LFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "lfs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_SYSV:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "sysv";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_FTP:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "ftp";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_TAR:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "tar";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_AR:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "ar";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_CPIO:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "cpio";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_MSLOSS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "msloss";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_CPM:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "cpm";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_HFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "hfs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_DTFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "dtfs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_GRFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "grfs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_TERM:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "term";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_DEV:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "dev";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_PROC:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "proc";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_IFSOCK:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "ifsock";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_AFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "afs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_DFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "dfs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_PROC9:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "proc9";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_SOCKET:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "socket";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_MISC:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "misc";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_EXT2FS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "ext2/ext3";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_HTTP:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "http";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_MEMFS:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "memfs";
|
2002-04-13 14:34:58 +00:00
|
|
|
case FSTYPE_ISO9660:
|
2004-09-03 21:58:36 +00:00
|
|
|
return "iso9660";
|
2003-03-22 21:32:22 +00:00
|
|
|
# endif
|
2002-04-13 14:34:58 +00:00
|
|
|
default:
|
2004-09-03 21:58:36 +00:00
|
|
|
{
|
2009-08-22 18:56:06 +02:00
|
|
|
unsigned long int type = statfsbuf->f_type;
|
|
|
|
|
static char buf[sizeof "UNKNOWN (0x%lx)" - 3
|
|
|
|
|
+ (sizeof type * CHAR_BIT + 3) / 4];
|
|
|
|
|
sprintf (buf, "UNKNOWN (0x%lx)", type);
|
|
|
|
|
return buf;
|
2004-09-03 21:58:36 +00:00
|
|
|
}
|
2002-04-13 14:34:58 +00:00
|
|
|
}
|
2002-06-21 12:34:36 +00:00
|
|
|
#endif
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static char *
|
2003-01-31 18:28:39 +00:00
|
|
|
human_access (struct stat const *statbuf)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2006-04-17 23:23:43 +00:00
|
|
|
static char modebuf[12];
|
|
|
|
|
filemodestring (statbuf, modebuf);
|
2002-04-13 14:11:44 +00:00
|
|
|
modebuf[10] = 0;
|
2003-01-31 18:28:39 +00:00
|
|
|
return modebuf;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static char *
|
2005-09-16 07:50:33 +00:00
|
|
|
human_time (struct timespec t)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2018-03-05 15:50:39 -08:00
|
|
|
/* STR must be at least INT_BUFSIZE_BOUND (intmax_t) big, either
|
|
|
|
|
because localtime_rz fails, or because the time zone is truly
|
|
|
|
|
outlandish so that %z expands to a long string. */
|
|
|
|
|
static char str[INT_BUFSIZE_BOUND (intmax_t)
|
2016-03-17 10:35:18 -07:00
|
|
|
+ INT_STRLEN_BOUND (int) /* YYYY */
|
|
|
|
|
+ 1 /* because YYYY might equal INT_MAX + 1900 */
|
|
|
|
|
+ sizeof "-MM-DD HH:MM:SS.NNNNNNNNN +"];
|
2015-07-23 18:49:31 -07:00
|
|
|
static timezone_t tz;
|
|
|
|
|
if (!tz)
|
|
|
|
|
tz = tzalloc (getenv ("TZ"));
|
2016-03-17 10:35:18 -07:00
|
|
|
struct tm tm;
|
|
|
|
|
int ns = t.tv_nsec;
|
|
|
|
|
if (localtime_rz (tz, &t.tv_sec, &tm))
|
|
|
|
|
nstrftime (str, sizeof str, "%Y-%m-%d %H:%M:%S.%N %z", &tm, tz, ns);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
char secbuf[INT_BUFSIZE_BOUND (intmax_t)];
|
|
|
|
|
sprintf (str, "%s.%09d", timetostr (t.tv_sec, secbuf), ns);
|
|
|
|
|
}
|
2003-02-01 09:59:09 +00:00
|
|
|
return str;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2010-11-06 13:57:08 -07:00
|
|
|
/* PFORMAT points to a '%' followed by a prefix of a format, all of
|
|
|
|
|
size PREFIX_LEN. The flags allowed for this format are
|
|
|
|
|
ALLOWED_FLAGS; remove other printf flags from the prefix, then
|
|
|
|
|
append SUFFIX. */
|
|
|
|
|
static void
|
|
|
|
|
make_format (char *pformat, size_t prefix_len, char const *allowed_flags,
|
|
|
|
|
char const *suffix)
|
|
|
|
|
{
|
|
|
|
|
char *dst = pformat + 1;
|
|
|
|
|
char const *src;
|
|
|
|
|
char const *srclim = pformat + prefix_len;
|
|
|
|
|
for (src = dst; src < srclim && strchr (printf_flags, *src); src++)
|
|
|
|
|
if (strchr (allowed_flags, *src))
|
|
|
|
|
*dst++ = *src;
|
|
|
|
|
while (src < srclim)
|
|
|
|
|
*dst++ = *src++;
|
|
|
|
|
strcpy (dst, suffix);
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-12 10:59:23 +00:00
|
|
|
static void
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_string (char *pformat, size_t prefix_len, char const *arg)
|
|
|
|
|
{
|
2010-11-06 13:57:08 -07:00
|
|
|
make_format (pformat, prefix_len, "-", "s");
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
printf (pformat, arg);
|
|
|
|
|
}
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
static int
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_int (char *pformat, size_t prefix_len, intmax_t arg)
|
|
|
|
|
{
|
2023-09-13 23:08:02 +01:00
|
|
|
make_format (pformat, prefix_len, "'-+ 0", "jd");
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
return printf (pformat, arg);
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
}
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
static int
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_uint (char *pformat, size_t prefix_len, uintmax_t arg)
|
|
|
|
|
{
|
2023-09-13 23:08:02 +01:00
|
|
|
make_format (pformat, prefix_len, "'-0", "ju");
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
return printf (pformat, arg);
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
}
|
|
|
|
|
static void
|
|
|
|
|
out_uint_o (char *pformat, size_t prefix_len, uintmax_t arg)
|
|
|
|
|
{
|
2023-09-13 23:08:02 +01:00
|
|
|
make_format (pformat, prefix_len, "-#0", "jo");
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
printf (pformat, arg);
|
|
|
|
|
}
|
|
|
|
|
static void
|
|
|
|
|
out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg)
|
2005-03-12 10:59:23 +00:00
|
|
|
{
|
2023-09-13 23:08:02 +01:00
|
|
|
make_format (pformat, prefix_len, "-#0", "jx");
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
printf (pformat, arg);
|
2005-03-12 10:59:23 +00:00
|
|
|
}
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
static int
|
|
|
|
|
out_minus_zero (char *pformat, size_t prefix_len)
|
|
|
|
|
{
|
2010-11-06 13:57:08 -07:00
|
|
|
make_format (pformat, prefix_len, "'-+ 0", ".0f");
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
return printf (pformat, -0.25);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Output the number of seconds since the Epoch, using a format that
|
|
|
|
|
acts like printf's %f format. */
|
|
|
|
|
static void
|
2011-12-04 14:08:54 +01:00
|
|
|
out_epoch_sec (char *pformat, size_t prefix_len,
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
struct timespec arg)
|
|
|
|
|
{
|
|
|
|
|
char *dot = memchr (pformat, '.', prefix_len);
|
|
|
|
|
size_t sec_prefix_len = prefix_len;
|
|
|
|
|
int width = 0;
|
|
|
|
|
int precision = 0;
|
|
|
|
|
bool frac_left_adjust = false;
|
|
|
|
|
|
|
|
|
|
if (dot)
|
|
|
|
|
{
|
|
|
|
|
sec_prefix_len = dot - pformat;
|
|
|
|
|
pformat[prefix_len] = '\0';
|
|
|
|
|
|
2024-12-30 10:45:54 -08:00
|
|
|
if (c_isdigit (dot[1]))
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
{
|
2026-01-18 15:55:38 +00:00
|
|
|
long int lprec = strtol (dot + 1, NULL, 10);
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
precision = (lprec <= INT_MAX ? lprec : INT_MAX);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2010-11-13 08:02:02 +01:00
|
|
|
precision = 9;
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
}
|
|
|
|
|
|
2024-12-30 10:45:54 -08:00
|
|
|
if (precision && c_isdigit (dot[-1]))
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
{
|
|
|
|
|
/* If a nontrivial width is given, subtract the width of the
|
|
|
|
|
decimal point and PRECISION digits that will be output
|
|
|
|
|
later. */
|
|
|
|
|
char *p = dot;
|
|
|
|
|
*dot = '\0';
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
--p;
|
2024-12-30 10:45:54 -08:00
|
|
|
while (c_isdigit (p[-1]));
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
|
2026-01-18 15:55:38 +00:00
|
|
|
long int lwidth = strtol (p, NULL, 10);
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
width = (lwidth <= INT_MAX ? lwidth : INT_MAX);
|
|
|
|
|
if (1 < width)
|
|
|
|
|
{
|
|
|
|
|
p += (*p == '0');
|
|
|
|
|
sec_prefix_len = p - pformat;
|
|
|
|
|
int w_d = (decimal_point_len < width
|
|
|
|
|
? width - decimal_point_len
|
|
|
|
|
: 0);
|
|
|
|
|
if (1 < w_d)
|
|
|
|
|
{
|
|
|
|
|
int w = w_d - precision;
|
|
|
|
|
if (1 < w)
|
|
|
|
|
{
|
|
|
|
|
char *dst = pformat;
|
|
|
|
|
for (char const *src = dst; src < p; src++)
|
|
|
|
|
{
|
|
|
|
|
if (*src == '-')
|
|
|
|
|
frac_left_adjust = true;
|
|
|
|
|
else
|
|
|
|
|
*dst++ = *src;
|
|
|
|
|
}
|
|
|
|
|
sec_prefix_len =
|
|
|
|
|
(dst - pformat
|
|
|
|
|
+ (frac_left_adjust ? 0 : sprintf (dst, "%d", w)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int divisor = 1;
|
|
|
|
|
for (int i = precision; i < 9; i++)
|
|
|
|
|
divisor *= 10;
|
|
|
|
|
int frac_sec = arg.tv_nsec / divisor;
|
|
|
|
|
int int_len;
|
|
|
|
|
|
|
|
|
|
if (TYPE_SIGNED (time_t))
|
|
|
|
|
{
|
|
|
|
|
bool minus_zero = false;
|
|
|
|
|
if (arg.tv_sec < 0 && arg.tv_nsec != 0)
|
|
|
|
|
{
|
|
|
|
|
int frac_sec_modulus = 1000000000 / divisor;
|
|
|
|
|
frac_sec = (frac_sec_modulus - frac_sec
|
|
|
|
|
- (arg.tv_nsec % divisor != 0));
|
|
|
|
|
arg.tv_sec += (frac_sec != 0);
|
|
|
|
|
minus_zero = (arg.tv_sec == 0);
|
|
|
|
|
}
|
|
|
|
|
int_len = (minus_zero
|
|
|
|
|
? out_minus_zero (pformat, sec_prefix_len)
|
|
|
|
|
: out_int (pformat, sec_prefix_len, arg.tv_sec));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
int_len = out_uint (pformat, sec_prefix_len, arg.tv_sec);
|
|
|
|
|
|
|
|
|
|
if (precision)
|
|
|
|
|
{
|
|
|
|
|
int prec = (precision < 9 ? precision : 9);
|
|
|
|
|
int trailing_prec = precision - prec;
|
|
|
|
|
int ilen = (int_len < 0 ? 0 : int_len);
|
|
|
|
|
int trailing_width = (ilen < width && decimal_point_len < width - ilen
|
|
|
|
|
? width - ilen - decimal_point_len - prec
|
|
|
|
|
: 0);
|
|
|
|
|
printf ("%s%.*d%-*.*d", decimal_point, prec, frac_sec,
|
|
|
|
|
trailing_width, trailing_prec, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-03-12 10:59:23 +00:00
|
|
|
|
2010-10-05 09:02:37 -06:00
|
|
|
/* Print the context information of FILENAME, and return true iff the
|
|
|
|
|
context could not be obtained. */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static bool
|
2010-10-05 09:02:37 -06:00
|
|
|
out_file_context (char *pformat, size_t prefix_len, char const *filename)
|
2007-01-07 09:15:42 +01:00
|
|
|
{
|
|
|
|
|
char *scontext;
|
2010-07-05 17:18:29 +02:00
|
|
|
bool fail = false;
|
|
|
|
|
|
2007-01-07 09:15:42 +01:00
|
|
|
if ((follow_links
|
|
|
|
|
? getfilecon (filename, &scontext)
|
|
|
|
|
: lgetfilecon (filename, &scontext)) < 0)
|
|
|
|
|
{
|
|
|
|
|
error (0, errno, _("failed to get security context of %s"),
|
2015-11-01 18:53:26 +00:00
|
|
|
quoteaf (filename));
|
2026-01-18 15:55:38 +00:00
|
|
|
scontext = NULL;
|
2010-07-05 17:18:29 +02:00
|
|
|
fail = true;
|
2007-01-07 09:15:42 +01:00
|
|
|
}
|
|
|
|
|
strcpy (pformat + prefix_len, "s");
|
|
|
|
|
printf (pformat, (scontext ? scontext : "?"));
|
|
|
|
|
if (scontext)
|
|
|
|
|
freecon (scontext);
|
2010-07-05 17:18:29 +02:00
|
|
|
return fail;
|
2007-01-07 09:15:42 +01:00
|
|
|
}
|
|
|
|
|
|
2010-07-05 17:18:29 +02:00
|
|
|
/* Print statfs info. Return zero upon success, nonzero upon failure. */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static bool
|
2021-11-18 21:36:47 -08:00
|
|
|
print_statfs (char *pformat, size_t prefix_len, MAYBE_UNUSED char mod, char m,
|
2025-05-09 15:52:15 -07:00
|
|
|
MAYBE_UNUSED int fd, char const *filename,
|
2009-08-22 18:56:06 +02:00
|
|
|
void const *data)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2002-06-21 12:34:36 +00:00
|
|
|
STRUCT_STATVFS const *statfsbuf = data;
|
2010-07-05 17:18:29 +02:00
|
|
|
bool fail = false;
|
2002-04-13 13:47:14 +00:00
|
|
|
|
2002-04-14 08:20:15 +00:00
|
|
|
switch (m)
|
|
|
|
|
{
|
|
|
|
|
case 'n':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_string (pformat, prefix_len, filename);
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
2002-04-14 06:55:13 +00:00
|
|
|
|
2002-04-14 08:20:15 +00:00
|
|
|
case 'i':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
{
|
2006-09-01 19:40:46 +00:00
|
|
|
#if STRUCT_STATXFS_F_FSID_IS_INTEGER
|
2009-08-22 18:56:06 +02:00
|
|
|
uintmax_t fsid = statfsbuf->f_fsid;
|
2006-09-01 19:40:46 +00:00
|
|
|
#else
|
2009-08-22 18:56:06 +02:00
|
|
|
typedef unsigned int fsid_word;
|
maint: prefer static_assert to verify
* bootstrap.conf: Add assert-h.
* gl/lib/randperm.c: Do not include verify.h.
* gl/lib/randperm.c, src/basenc.c, src/dd.c, src/digest.c:
* src/dircolors.c, src/expr.c, src/factor.c, src/ls.c, src/numfmt.c:
* src/od.c, src/seq.c, src/shred.c, src/sort.c, src/stat.c:
Prefer C23’s static_assert to nonstandard verify.
* gl/modules/randperm (Depends-on): Add assert-h.
2022-09-15 00:55:08 -05:00
|
|
|
static_assert (alignof (STRUCT_STATVFS) % alignof (fsid_word) == 0);
|
|
|
|
|
static_assert (offsetof (STRUCT_STATVFS, f_fsid) % alignof (fsid_word)
|
|
|
|
|
== 0);
|
|
|
|
|
static_assert (sizeof statfsbuf->f_fsid % alignof (fsid_word) == 0);
|
2009-08-22 18:56:06 +02:00
|
|
|
fsid_word const *p = (fsid_word *) &statfsbuf->f_fsid;
|
|
|
|
|
|
|
|
|
|
/* Assume a little-endian word order, as that is compatible
|
|
|
|
|
with glibc's statvfs implementation. */
|
|
|
|
|
uintmax_t fsid = 0;
|
|
|
|
|
int words = sizeof statfsbuf->f_fsid / sizeof *p;
|
2017-06-17 14:54:23 -07:00
|
|
|
for (int i = 0; i < words && i * sizeof *p < sizeof fsid; i++)
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
|
|
|
|
uintmax_t u = p[words - 1 - i];
|
|
|
|
|
fsid |= u << (i * CHAR_BIT * sizeof *p);
|
|
|
|
|
}
|
2002-04-13 13:47:14 +00:00
|
|
|
#endif
|
2009-08-22 18:56:06 +02:00
|
|
|
out_uint_x (pformat, prefix_len, fsid);
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
}
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'l':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
OUT_NAMEMAX (pformat, prefix_len, SB_F_NAMEMAX (statfsbuf));
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
case 't':
|
2002-06-21 12:34:36 +00:00
|
|
|
#if HAVE_STRUCT_STATXFS_F_TYPE
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_uint_x (pformat, prefix_len, statfsbuf->f_type);
|
2002-06-21 12:34:36 +00:00
|
|
|
#else
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
fputc ('?', stdout);
|
2002-06-21 12:34:36 +00:00
|
|
|
#endif
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
case 'T':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_string (pformat, prefix_len, human_fstype (statfsbuf));
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
case 'b':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_int (pformat, prefix_len, statfsbuf->f_blocks);
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
case 'f':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_int (pformat, prefix_len, statfsbuf->f_bfree);
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
case 'a':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_int (pformat, prefix_len, statfsbuf->f_bavail);
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
case 's':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_uint (pformat, prefix_len, statfsbuf->f_bsize);
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
2005-02-08 21:38:53 +00:00
|
|
|
case 'S':
|
|
|
|
|
{
|
2009-08-22 18:56:06 +02:00
|
|
|
uintmax_t frsize = STATFS_FRSIZE (statfsbuf);
|
|
|
|
|
if (! frsize)
|
|
|
|
|
frsize = statfsbuf->f_bsize;
|
|
|
|
|
out_uint (pformat, prefix_len, frsize);
|
2005-02-08 21:38:53 +00:00
|
|
|
}
|
|
|
|
|
break;
|
2002-04-14 08:20:15 +00:00
|
|
|
case 'c':
|
2009-01-02 16:40:52 +01:00
|
|
|
out_uint (pformat, prefix_len, statfsbuf->f_files);
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
case 'd':
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
out_int (pformat, prefix_len, statfsbuf->f_ffree);
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
|
|
|
|
default:
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
fputc ('?', stdout);
|
2002-04-14 08:20:15 +00:00
|
|
|
break;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
2010-07-05 17:18:29 +02:00
|
|
|
return fail;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2010-07-15 19:54:49 -06:00
|
|
|
/* Return any bind mounted source for a path.
|
|
|
|
|
The caller should not free the returned buffer.
|
2026-01-18 15:55:38 +00:00
|
|
|
Return NULL if no bind mount found. */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static char const *
|
2010-07-15 19:54:49 -06:00
|
|
|
find_bind_mount (char const * name)
|
|
|
|
|
{
|
2026-01-18 15:55:38 +00:00
|
|
|
char const * bind_mount = NULL;
|
2010-07-15 19:54:49 -06:00
|
|
|
|
|
|
|
|
static struct mount_entry *mount_list;
|
|
|
|
|
static bool tried_mount_list = false;
|
|
|
|
|
if (!tried_mount_list) /* attempt/warn once per process. */
|
|
|
|
|
{
|
|
|
|
|
if (!(mount_list = read_file_system_list (false)))
|
|
|
|
|
error (0, errno, "%s", _("cannot read table of mounted file systems"));
|
|
|
|
|
tried_mount_list = true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-29 16:44:50 +01:00
|
|
|
struct stat name_stats;
|
|
|
|
|
if (stat (name, &name_stats) != 0)
|
2026-01-18 15:55:38 +00:00
|
|
|
return NULL;
|
2014-05-29 16:44:50 +01:00
|
|
|
|
maint: use C99 initialization syntax for single-variable 'for' loops
* src/chroot.c (parse_additional_groups): Declare variable in the 'for'
clause.
* src/comm.c (compare_files): Likewise.
* src/cp.c (re_protect): Likewise.
* src/csplit.c (save_buffer, find_line, write_to_file)
(split_file, main): Likewise.
* src/dd.c (apply_translations, translate_buffer)
(copy_with_block, main): Likewise.
* src/df.c (selected_fstype, excluded_fstype, filter_mount_list)
(last_device_for_mount, get_device, get_point, get_all_entries)
(main): Likewise.
* src/fmt.c (copy_rest, get_prefix, fmt_paragraph, put_paragraph)
(put_word): Likewise.
* src/fold.c (main): Likewise.
* src/head.c (elide_tail_bytes_pipe, main): Likewise.
* src/install.c (main): Likewise.
* src/join.c (prfields, join, main): Likewise.
* src/kill.c (list_signals): Likewise.
* src/ls.c (main, decode_switches, parse_ls_color, patterns_match):
Likewise.
* src/operand2sig.c (operand2sig): Likewise.
* src/pathchk.c (no_leading_hyphen, validate_file_name): Likewise.
* src/pr.c (char_to_clump): Likewise.
* src/printenv.c (main): Likewise.
* src/ptx.c (initialize_regex, digest_break_file)
(find_occurs_in_text, print_field): Likewise.
* src/remove.c (mark_ancestor_dirs): Likewise.
* src/seq.c (print_numbers): Likewise.
* src/shred.c (do_wipefd, main): Likewise.
* src/sort.c (cleanup, inittables, key_warnings, mergefps)
(check_ordering_compatibility, main): Likewise.
* src/split.c (closeout): Likewise.
* src/stat.c (find_bind_mount, print_it, format_to_mask): Likewise.
* src/stdbuf.c (set_program_path): Likewise.
* src/stty.c (apply_settings, display_changed, display_all)
(recover_mode, sane_mode): Likewise.
* src/system.h (stzncpy): Likewise.
* src/tail.c (pipe_lines): Likewise.
* src/tee.c (tee_files): Likewise.
* src/tr.c (look_up_char_class, get_spec_stats): Likewise.
* src/users.c (list_entries_users): Likewise.
2025-11-16 20:23:30 -08:00
|
|
|
for (struct mount_entry *me = mount_list; me; me = me->me_next)
|
2010-07-15 19:54:49 -06:00
|
|
|
{
|
|
|
|
|
if (me->me_dummy && me->me_devname[0] == '/'
|
2025-09-17 09:12:23 -07:00
|
|
|
&& streq (me->me_mountdir, name))
|
2010-07-15 19:54:49 -06:00
|
|
|
{
|
|
|
|
|
struct stat dev_stats;
|
|
|
|
|
|
2014-05-29 16:44:50 +01:00
|
|
|
if (stat (me->me_devname, &dev_stats) == 0
|
maint: prefer psame_inode, PSAME_INODE, STP_*
Prefer psame_inode, PSAME_INODE, STP_NBLOCKS, and STP_BLKSIZE,
which take addresses of objects, to their counterparts that
take the whole objects. In some cases the whole objects might
not be initialized, which would be undefined behavior strictly
speaking.
* gl/lib/root-dev-ino.h (ROOT_DEV_INO_CHECK):
* src/cp-hash.c (src_to_dest_compare):
* src/ls.c (dev_ino_compare):
* src/pwd.c (robust_getcwd):
Prefer PSAME_INODE to SAME_INODE.
* src/chown-core.c (restricted_chown):
* src/copy.c (copy_reg, same_file_ok, source_is_dst_backup)
(copy_internal):
* src/ln.c (do_link):
* src/pwd.c (logical_getcwd):
* src/sort.c (avoid_trashing_input):
* src/split.c (create):
* src/stat.c (find_bind_mount):
Prefer psame_inode to SAME_INODE.
* src/copy.c (infer_scantype):
* src/du.c (process_file):
* src/ls.c (gobble_file, print_long_format)
(print_file_name_and_frills, length_of_file_name_and_frills):
* src/stat.c (print_stat):
Prefer STP_NBLOCKS to ST_NBLOCKS.
* src/copy.c (copy_reg):
* src/head.c (elide_tail_bytes_file, elide_tail_lines_file):
* src/ioblksize.h (io_blksize):
* src/od.c (skip):
* src/shred.c (do_wipefd):
* src/stat.c (print_stat):
* src/tail.c (tail_bytes):
* src/truncate.c (do_ftruncate):
* src/wc.c (wc):
Prefer STP_BLKSIZE to ST_BLKSIZE.
* src/ioblksize.h (io_blksize):
Arg is now struct stat const *, not struct stat. All callers changed.
2023-09-04 23:04:47 -07:00
|
|
|
&& psame_inode (&name_stats, &dev_stats))
|
2010-07-15 19:54:49 -06:00
|
|
|
{
|
|
|
|
|
bind_mount = me->me_devname;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bind_mount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Print mount point. Return zero upon success, nonzero upon failure. */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static bool
|
2010-07-15 19:54:49 -06:00
|
|
|
out_mount_point (char const *filename, char *pformat, size_t prefix_len,
|
|
|
|
|
const struct stat *statp)
|
|
|
|
|
{
|
|
|
|
|
|
2026-01-18 15:55:38 +00:00
|
|
|
char const *np = "?", *bp = NULL;
|
|
|
|
|
char *mp = NULL;
|
2010-07-15 19:54:49 -06:00
|
|
|
bool fail = true;
|
|
|
|
|
|
|
|
|
|
/* Look for bind mounts first. Note we output the immediate alias,
|
|
|
|
|
rather than further resolving to a base device mount point. */
|
|
|
|
|
if (follow_links || !S_ISLNK (statp->st_mode))
|
|
|
|
|
{
|
|
|
|
|
char *resolved = canonicalize_file_name (filename);
|
|
|
|
|
if (!resolved)
|
|
|
|
|
{
|
2015-11-01 18:53:26 +00:00
|
|
|
error (0, errno, _("failed to canonicalize %s"), quoteaf (filename));
|
2010-07-15 19:54:49 -06:00
|
|
|
goto print_mount_point;
|
|
|
|
|
}
|
|
|
|
|
bp = find_bind_mount (resolved);
|
|
|
|
|
free (resolved);
|
|
|
|
|
if (bp)
|
|
|
|
|
{
|
|
|
|
|
fail = false;
|
|
|
|
|
goto print_mount_point;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If there is no direct bind mount, then navigate
|
|
|
|
|
back up the tree looking for a device change.
|
|
|
|
|
Note we don't detect if any of the directory components
|
|
|
|
|
are bind mounted to the same device, but that's OK
|
|
|
|
|
since we've not directly queried them. */
|
|
|
|
|
if ((mp = find_mount_point (filename, statp)))
|
|
|
|
|
{
|
|
|
|
|
/* This dir might be bind mounted to another device,
|
|
|
|
|
so we resolve the bound source in that case also. */
|
|
|
|
|
bp = find_bind_mount (mp);
|
|
|
|
|
fail = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print_mount_point:
|
|
|
|
|
|
|
|
|
|
out_string (pformat, prefix_len, bp ? bp : mp ? mp : np);
|
|
|
|
|
free (mp);
|
|
|
|
|
return fail;
|
|
|
|
|
}
|
|
|
|
|
|
stat: revert %X-%Y-%Z change; use e.g., %:X to print fractional seconds
This reverts part of the recent commit 9069af45,
"stat: print timestamps to full resolution", which made %X, %Y, %Z
print floating point numbers. We prefer to retain portability of
%X, %Y and %Z uses, while still providing access to full-resolution
time stamps via modified format strings. Also make the new
%W consistent.
* src/stat.c: Include "xstrtol.h".
(print_it): Accept a new %...:[XYZ] format directive,
e.g., %:X, to print the nanoseconds portion of the corresponding time.
For example, %3.3:Y prints the zero-padded, truncated, milliseconds
part of the time of last modification.
(print_it): Update print_func signature to match.
(neg_to_zero): New helper function.
(epoch_time): Remove function; replace with...
(epoch_sec): New function; use timetostr.
(out_ns): New function. Use "09" only when no other modifier
is specified.
(print_statfs): Change type of "m" to unsigned int,
now that it must accommodate values larger than 255.
(print_stat): Likewise.
Map :X to a code of 'X' + 256. Likewise for Y, Z and W.
(usage): Update.
* tests/touch/60-seconds: Use %Y.%:Y in place of %Y.
* tests/misc/stat-nanoseconds: New file.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Changes in behavior): Mention this.
With improvements by Pádraig Brady.
Thanks to Andreas Schwab for raising the issue.
2010-10-21 18:41:24 +02:00
|
|
|
/* Map a TS with negative TS.tv_nsec to {0,0}. */
|
|
|
|
|
static inline struct timespec
|
|
|
|
|
neg_to_zero (struct timespec ts)
|
|
|
|
|
{
|
|
|
|
|
if (0 <= ts.tv_nsec)
|
|
|
|
|
return ts;
|
2023-08-30 07:39:34 -07:00
|
|
|
struct timespec z = {0};
|
stat: revert %X-%Y-%Z change; use e.g., %:X to print fractional seconds
This reverts part of the recent commit 9069af45,
"stat: print timestamps to full resolution", which made %X, %Y, %Z
print floating point numbers. We prefer to retain portability of
%X, %Y and %Z uses, while still providing access to full-resolution
time stamps via modified format strings. Also make the new
%W consistent.
* src/stat.c: Include "xstrtol.h".
(print_it): Accept a new %...:[XYZ] format directive,
e.g., %:X, to print the nanoseconds portion of the corresponding time.
For example, %3.3:Y prints the zero-padded, truncated, milliseconds
part of the time of last modification.
(print_it): Update print_func signature to match.
(neg_to_zero): New helper function.
(epoch_time): Remove function; replace with...
(epoch_sec): New function; use timetostr.
(out_ns): New function. Use "09" only when no other modifier
is specified.
(print_statfs): Change type of "m" to unsigned int,
now that it must accommodate values larger than 255.
(print_stat): Likewise.
Map :X to a code of 'X' + 256. Likewise for Y, Z and W.
(usage): Update.
* tests/touch/60-seconds: Use %Y.%:Y in place of %Y.
* tests/misc/stat-nanoseconds: New file.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Changes in behavior): Mention this.
With improvements by Pádraig Brady.
Thanks to Andreas Schwab for raising the issue.
2010-10-21 18:41:24 +02:00
|
|
|
return z;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-03 15:36:48 +00:00
|
|
|
/* Set the quoting style default if the environment variable
|
|
|
|
|
QUOTING_STYLE is set. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
getenv_quoting_style (void)
|
|
|
|
|
{
|
|
|
|
|
char const *q_style = getenv ("QUOTING_STYLE");
|
|
|
|
|
if (q_style)
|
|
|
|
|
{
|
|
|
|
|
int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals);
|
|
|
|
|
if (0 <= i)
|
2026-01-18 15:55:38 +00:00
|
|
|
set_quoting_style (NULL, quoting_style_vals[i]);
|
2016-11-03 15:36:48 +00:00
|
|
|
else
|
|
|
|
|
{
|
2026-01-18 15:55:38 +00:00
|
|
|
set_quoting_style (NULL, shell_escape_always_quoting_style);
|
2016-11-03 15:36:48 +00:00
|
|
|
error (0, 0, _("ignoring invalid value of environment "
|
|
|
|
|
"variable QUOTING_STYLE: %s"), quote (q_style));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2026-01-18 15:55:38 +00:00
|
|
|
set_quoting_style (NULL, shell_escape_always_quoting_style);
|
2016-11-03 15:36:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Equivalent to quotearg(), but explicit to avoid syntax checks. */
|
2026-01-18 15:55:38 +00:00
|
|
|
#define quoteN(x) quotearg_style (get_quoting_style (NULL), x)
|
2016-11-03 15:36:48 +00:00
|
|
|
|
2005-12-15 12:24:30 +00:00
|
|
|
/* Output a single-character \ escape. */
|
|
|
|
|
|
2002-04-13 14:23:00 +00:00
|
|
|
static void
|
2005-12-15 12:24:30 +00:00
|
|
|
print_esc_char (char c)
|
|
|
|
|
{
|
|
|
|
|
switch (c)
|
|
|
|
|
{
|
|
|
|
|
case 'a': /* Alert. */
|
|
|
|
|
c ='\a';
|
|
|
|
|
break;
|
|
|
|
|
case 'b': /* Backspace. */
|
|
|
|
|
c ='\b';
|
|
|
|
|
break;
|
2009-10-27 10:04:34 +00:00
|
|
|
case 'e': /* Escape. */
|
|
|
|
|
c ='\x1B';
|
|
|
|
|
break;
|
2005-12-15 12:24:30 +00:00
|
|
|
case 'f': /* Form feed. */
|
|
|
|
|
c ='\f';
|
|
|
|
|
break;
|
|
|
|
|
case 'n': /* New line. */
|
|
|
|
|
c ='\n';
|
|
|
|
|
break;
|
|
|
|
|
case 'r': /* Carriage return. */
|
|
|
|
|
c ='\r';
|
|
|
|
|
break;
|
|
|
|
|
case 't': /* Horizontal tab. */
|
|
|
|
|
c ='\t';
|
|
|
|
|
break;
|
|
|
|
|
case 'v': /* Vertical tab. */
|
|
|
|
|
c ='\v';
|
|
|
|
|
break;
|
|
|
|
|
case '"':
|
|
|
|
|
case '\\':
|
|
|
|
|
break;
|
|
|
|
|
default:
|
maint: adjust quoting: emit '...', not `...' in diagnostics
* src/csplit.c (parse_repeat_count, extract_regexp): As above.
* src/date.c (main): Likewise.
* src/ls.c (decode_switches): Likewise.
* src/od.c (decode_one_format, main): Likewise.
* src/pathchk.c (no_leading_hyphen): Likewise.
* src/pr.c (main, getoptarg): Likewise.
* src/rm.c (diagnose_leading_hyphen): Likewise.
* src/sort.c (key_warnings, incompatible_options, main): Likewise.
* src/stat.c (print_esc_char): Print '\x', not `\x' in diagnostic.
* src/test.c (main): Likewise.
* src/touch.c (main): Likewise.
* src/tr.c (build_spec_list, validate, append_range): Likewise.
* tests/misc/mktemp: This is an unusual case, since the affected
string contains only the ` of an `...' string. So we change
the long ` to a lone '.
* tests/pr/pr-tests: Manual quote adapting fix-up.
* tests/ln/hard-to-sym: Likewise.
* tests/split/suffix-length: Likewise.
* tests/mv/part-fail: Likewise.
* tests/misc/chcon: Likewise.
* tests/misc/stat-printf: Likewise.
2012-01-07 18:30:14 +01:00
|
|
|
error (0, 0, _("warning: unrecognized escape '\\%c'"), c);
|
2005-12-15 12:24:30 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
putchar (c);
|
|
|
|
|
}
|
|
|
|
|
|
maint: prefer attribute.h in .c files
This will help us make the transition to C2x, where some
attributes must come at the start of function decls.
Leave the attributes alone in .h files for now,
as the Gnulib tradition is to not expose attribute.h to users.
* bootstrap.conf (gnulib_modules): Add ‘attribute’.
* gl/lib/randperm.c, src/make-prime-list.c, src/system.h:
Include attribute.h.
* gl/lib/strnumcmp.c (strnumcmp): Remove _GL_ATTRIBUTE_PURE here,
as this belongs in the .h file.
* gl/lib/strnumcmp.h (strnumcmp): Add _GL_ATTRIBUTE_PURE here.
* src/sort.c (human_numcompare, numcompare): Now ATTRIBUTE_PURE;
discovered due to strnumcmp.h change.
* gl/lib/randperm.c, src/copy.c, src/dd.c, src/df.c, src/digest.c:
* src/env.c, src/expr.c, src/factor.c, src/ls.c:
* src/make-prime-list.c, src/numfmt.c, src/od.c, src/pathchk.c:
* src/pinky.c, src/pr.c, src/ptx.c, src/realpath.c, src/relpath.c:
* src/seq.c, src/sort.c, src/stat.c, src/stty.c, src/system.h:
* src/tr.c, src/uniq.c, src/wc.c:
In .c files, crefer ATTRIBUTE_CONST to _GL_ATTRIBUTE_CONST, and
similarly for ATTRIBUTE_FORMAT and ATTRIBUTE_PURE.
* src/system.h (FALLTHROUGH): Remove; attribute.h defines it.
2021-10-31 22:30:38 -07:00
|
|
|
ATTRIBUTE_PURE
|
|
|
|
|
static size_t
|
2021-12-18 09:34:31 -08:00
|
|
|
format_code_offset (char const *directive)
|
2019-05-28 08:21:42 -04:00
|
|
|
{
|
|
|
|
|
size_t len = strspn (directive + 1, printf_flags);
|
|
|
|
|
char const *fmt_char = directive + len + 1;
|
|
|
|
|
fmt_char += strspn (fmt_char, digits);
|
|
|
|
|
if (*fmt_char == '.')
|
|
|
|
|
fmt_char += 1 + strspn (fmt_char + 1, digits);
|
|
|
|
|
return fmt_char - directive;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-05 17:18:29 +02:00
|
|
|
/* Print the information specified by the format string, FORMAT,
|
|
|
|
|
calling PRINT_FUNC for each %-directive encountered.
|
|
|
|
|
Return zero upon success, nonzero upon failure. */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static bool
|
2014-03-18 16:12:26 -07:00
|
|
|
print_it (char const *format, int fd, char const *filename,
|
2021-06-20 15:16:49 +01:00
|
|
|
bool (*print_func) (char *, size_t, char, char,
|
2014-03-18 16:12:26 -07:00
|
|
|
int, char const *, void const *),
|
2009-08-22 18:56:06 +02:00
|
|
|
void const *data)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2010-07-05 17:18:29 +02:00
|
|
|
bool fail = false;
|
|
|
|
|
|
2012-01-08 15:08:30 +01:00
|
|
|
/* Add 2 to accommodate our conversion of the stat '%s' format string
|
|
|
|
|
to the longer printf '%llu' one. */
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
MAX_ADDITIONAL_BYTES =
|
2023-09-13 23:08:02 +01:00
|
|
|
(MAX (sizeof "jd",
|
|
|
|
|
MAX (sizeof "jo", MAX (sizeof "ju", sizeof "jx")))
|
2009-08-22 18:56:06 +02:00
|
|
|
- 1)
|
* src/stat.c (HAVE_STRUCT_STATXFS_F_FSID___VAL): Define. This
macro was being used without being defined.
(SB_F_NAMEMAX): Remove cast.
(f_fsid) [BeOS]: Likewise.
(OUT_NAMEMAX): Renamed from NAMEMAX_FORMAT, with a new meaning.
All uses changed.
(out_string, out_int, out_uint, out_uint_o, out_uint_x): New
functions.
(xstrcat): Remove. All uses changed to use the above functions.
(print_statfs, print_stat): 2nd arg is now the prefix len, not the
buffer len. All uses changed. Output '?', not '*', for unknown
data or errors. Do not assume signed values can be interchanged
with unsigned when printing.
(print_statfs): For %i, print the fsid as a single int, not as a
pair.
(print_it): Quote invalid format better.
(STRUCT_STATVFS, statfs, f_fsid, f_blocks, f_bfree) [BeOS]:
(f_bavail, f_bsize, STATFS_FRSIZE, f_files, f_ffree) [BeOS]:
(STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME) [BeOS]: Define.
2006-08-23 23:40:21 +00:00
|
|
|
};
|
|
|
|
|
size_t n_alloc = strlen (format) + MAX_ADDITIONAL_BYTES + 1;
|
2005-03-12 10:59:23 +00:00
|
|
|
char *dest = xmalloc (n_alloc);
|
maint: use C99 initialization syntax for single-variable 'for' loops
* src/chroot.c (parse_additional_groups): Declare variable in the 'for'
clause.
* src/comm.c (compare_files): Likewise.
* src/cp.c (re_protect): Likewise.
* src/csplit.c (save_buffer, find_line, write_to_file)
(split_file, main): Likewise.
* src/dd.c (apply_translations, translate_buffer)
(copy_with_block, main): Likewise.
* src/df.c (selected_fstype, excluded_fstype, filter_mount_list)
(last_device_for_mount, get_device, get_point, get_all_entries)
(main): Likewise.
* src/fmt.c (copy_rest, get_prefix, fmt_paragraph, put_paragraph)
(put_word): Likewise.
* src/fold.c (main): Likewise.
* src/head.c (elide_tail_bytes_pipe, main): Likewise.
* src/install.c (main): Likewise.
* src/join.c (prfields, join, main): Likewise.
* src/kill.c (list_signals): Likewise.
* src/ls.c (main, decode_switches, parse_ls_color, patterns_match):
Likewise.
* src/operand2sig.c (operand2sig): Likewise.
* src/pathchk.c (no_leading_hyphen, validate_file_name): Likewise.
* src/pr.c (char_to_clump): Likewise.
* src/printenv.c (main): Likewise.
* src/ptx.c (initialize_regex, digest_break_file)
(find_occurs_in_text, print_field): Likewise.
* src/remove.c (mark_ancestor_dirs): Likewise.
* src/seq.c (print_numbers): Likewise.
* src/shred.c (do_wipefd, main): Likewise.
* src/sort.c (cleanup, inittables, key_warnings, mergefps)
(check_ordering_compatibility, main): Likewise.
* src/split.c (closeout): Likewise.
* src/stat.c (find_bind_mount, print_it, format_to_mask): Likewise.
* src/stdbuf.c (set_program_path): Likewise.
* src/stty.c (apply_settings, display_changed, display_all)
(recover_mode, sane_mode): Likewise.
* src/system.h (stzncpy): Likewise.
* src/tail.c (pipe_lines): Likewise.
* src/tee.c (tee_files): Likewise.
* src/tr.c (look_up_char_class, get_spec_stats): Likewise.
* src/users.c (list_entries_users): Likewise.
2025-11-16 20:23:30 -08:00
|
|
|
for (char const *b = format; *b; b++)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2005-12-15 12:24:30 +00:00
|
|
|
switch (*b)
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
|
|
|
|
case '%':
|
|
|
|
|
{
|
2019-05-28 08:21:42 -04:00
|
|
|
size_t len = format_code_offset (b);
|
2021-06-20 15:16:49 +01:00
|
|
|
char fmt_char = *(b + len);
|
|
|
|
|
char mod_char = 0;
|
2019-05-28 08:21:42 -04:00
|
|
|
memcpy (dest, b, len);
|
|
|
|
|
b += len;
|
|
|
|
|
|
2021-06-20 15:16:49 +01:00
|
|
|
switch (fmt_char)
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
|
|
|
|
case '\0':
|
|
|
|
|
--b;
|
2017-06-10 10:02:31 -07:00
|
|
|
FALLTHROUGH;
|
2009-08-22 18:56:06 +02:00
|
|
|
case '%':
|
2019-05-28 08:21:42 -04:00
|
|
|
if (1 < len)
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
2021-06-20 15:16:49 +01:00
|
|
|
dest[len] = fmt_char;
|
2019-05-28 08:21:42 -04:00
|
|
|
dest[len + 1] = '\0';
|
2023-07-01 11:31:40 -07:00
|
|
|
error (EXIT_FAILURE, 0, _("%s: invalid directive"),
|
|
|
|
|
quote (dest));
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
|
|
|
|
putchar ('%');
|
|
|
|
|
break;
|
2021-06-20 15:16:49 +01:00
|
|
|
case 'H':
|
|
|
|
|
case 'L':
|
|
|
|
|
mod_char = fmt_char;
|
|
|
|
|
fmt_char = *(b + 1);
|
|
|
|
|
if (print_func == print_stat
|
|
|
|
|
&& (fmt_char == 'd' || fmt_char == 'r'))
|
|
|
|
|
{
|
|
|
|
|
b++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fmt_char = mod_char;
|
|
|
|
|
mod_char = 0;
|
|
|
|
|
}
|
|
|
|
|
FALLTHROUGH;
|
2009-08-22 18:56:06 +02:00
|
|
|
default:
|
2021-06-20 15:16:49 +01:00
|
|
|
fail |= print_func (dest, len, mod_char, fmt_char,
|
2014-03-18 16:12:26 -07:00
|
|
|
fd, filename, data);
|
2009-08-22 18:56:06 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case '\\':
|
|
|
|
|
if ( ! interpret_backslash_escapes)
|
|
|
|
|
{
|
|
|
|
|
putchar ('\\');
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++b;
|
2024-05-05 12:55:00 +03:00
|
|
|
if (isoct (*b))
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
2024-05-05 12:55:00 +03:00
|
|
|
int esc_value = fromoct (*b);
|
2009-08-22 18:56:06 +02:00
|
|
|
int esc_length = 1; /* number of octal digits */
|
2024-05-05 12:55:00 +03:00
|
|
|
for (++b; esc_length < 3 && isoct (*b);
|
2009-08-22 18:56:06 +02:00
|
|
|
++esc_length, ++b)
|
|
|
|
|
{
|
2024-05-05 12:55:00 +03:00
|
|
|
esc_value = esc_value * 8 + fromoct (*b);
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
|
|
|
|
putchar (esc_value);
|
|
|
|
|
--b;
|
|
|
|
|
}
|
2024-11-19 09:18:50 -08:00
|
|
|
else if (*b == 'x' && c_isxdigit (b[1]))
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
2024-05-05 12:55:00 +03:00
|
|
|
int esc_value = fromhex (b[1]); /* Value of \xhh escape. */
|
2009-08-22 18:56:06 +02:00
|
|
|
/* A hexadecimal \xhh escape sequence must have
|
|
|
|
|
1 or 2 hex. digits. */
|
|
|
|
|
++b;
|
2024-11-19 09:18:50 -08:00
|
|
|
if (c_isxdigit (b[1]))
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
|
|
|
|
++b;
|
2024-05-05 12:55:00 +03:00
|
|
|
esc_value = esc_value * 16 + fromhex (*b);
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
|
|
|
|
putchar (esc_value);
|
|
|
|
|
}
|
|
|
|
|
else if (*b == '\0')
|
|
|
|
|
{
|
|
|
|
|
error (0, 0, _("warning: backslash at end of format"));
|
|
|
|
|
putchar ('\\');
|
|
|
|
|
/* Arrange to exit the loop. */
|
|
|
|
|
--b;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
print_esc_char (*b);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
putchar (*b);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
2002-07-13 08:05:04 +00:00
|
|
|
free (dest);
|
2005-12-15 12:24:30 +00:00
|
|
|
|
|
|
|
|
fputs (trailing_delim, stdout);
|
2010-07-05 17:18:29 +02:00
|
|
|
|
|
|
|
|
return fail;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2004-06-30 22:31:43 +00:00
|
|
|
/* Stat the file system and print what we find. */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static bool
|
2011-12-04 14:08:54 +01:00
|
|
|
do_statfs (char const *filename, char const *format)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2002-06-21 12:34:36 +00:00
|
|
|
STRUCT_STATVFS statfsbuf;
|
2002-04-14 12:52:48 +00:00
|
|
|
|
2025-09-17 09:12:23 -07:00
|
|
|
if (streq (filename, "-"))
|
2009-09-15 23:07:18 +02:00
|
|
|
{
|
|
|
|
|
error (0, 0, _("using %s to denote standard input does not work"
|
2015-11-01 18:53:26 +00:00
|
|
|
" in file system mode"), quoteaf (filename));
|
2009-09-15 23:07:18 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2004-11-17 03:12:06 +00:00
|
|
|
if (STATFS (filename, &statfsbuf) != 0)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2002-07-13 08:05:04 +00:00
|
|
|
error (0, errno, _("cannot read file system information for %s"),
|
2015-11-01 18:53:26 +00:00
|
|
|
quoteaf (filename));
|
2004-08-03 19:08:31 +00:00
|
|
|
return false;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2014-03-18 16:12:26 -07:00
|
|
|
bool fail = print_it (format, -1, filename, print_statfs, &statfsbuf);
|
2010-07-05 17:18:29 +02:00
|
|
|
return ! fail;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-28 08:21:42 -04:00
|
|
|
struct print_args {
|
|
|
|
|
struct stat *st;
|
|
|
|
|
struct timespec btime;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Ask statx to avoid syncing? */
|
|
|
|
|
static bool dont_sync;
|
|
|
|
|
|
|
|
|
|
/* Ask statx to force sync? */
|
|
|
|
|
static bool force_sync;
|
|
|
|
|
|
|
|
|
|
#if USE_STATX
|
|
|
|
|
static unsigned int
|
|
|
|
|
fmt_to_mask (char fmt)
|
|
|
|
|
{
|
|
|
|
|
switch (fmt)
|
|
|
|
|
{
|
|
|
|
|
case 'N':
|
2019-06-27 02:25:55 -06:00
|
|
|
return STATX_MODE;
|
2019-05-28 08:21:42 -04:00
|
|
|
case 'd':
|
|
|
|
|
case 'D':
|
|
|
|
|
return STATX_MODE;
|
|
|
|
|
case 'i':
|
|
|
|
|
return STATX_INO;
|
|
|
|
|
case 'a':
|
|
|
|
|
case 'A':
|
|
|
|
|
return STATX_MODE;
|
|
|
|
|
case 'f':
|
|
|
|
|
return STATX_MODE|STATX_TYPE;
|
|
|
|
|
case 'F':
|
|
|
|
|
return STATX_TYPE;
|
|
|
|
|
case 'h':
|
|
|
|
|
return STATX_NLINK;
|
|
|
|
|
case 'u':
|
|
|
|
|
case 'U':
|
|
|
|
|
return STATX_UID;
|
|
|
|
|
case 'g':
|
|
|
|
|
case 'G':
|
|
|
|
|
return STATX_GID;
|
|
|
|
|
case 'm':
|
|
|
|
|
return STATX_MODE|STATX_INO;
|
|
|
|
|
case 's':
|
|
|
|
|
return STATX_SIZE;
|
|
|
|
|
case 't':
|
|
|
|
|
case 'T':
|
|
|
|
|
return STATX_MODE;
|
|
|
|
|
case 'b':
|
|
|
|
|
return STATX_BLOCKS;
|
|
|
|
|
case 'w':
|
|
|
|
|
case 'W':
|
|
|
|
|
return STATX_BTIME;
|
|
|
|
|
case 'x':
|
|
|
|
|
case 'X':
|
|
|
|
|
return STATX_ATIME;
|
|
|
|
|
case 'y':
|
|
|
|
|
case 'Y':
|
|
|
|
|
return STATX_MTIME;
|
|
|
|
|
case 'z':
|
|
|
|
|
case 'Z':
|
|
|
|
|
return STATX_CTIME;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
maint: prefer attribute.h in .c files
This will help us make the transition to C2x, where some
attributes must come at the start of function decls.
Leave the attributes alone in .h files for now,
as the Gnulib tradition is to not expose attribute.h to users.
* bootstrap.conf (gnulib_modules): Add ‘attribute’.
* gl/lib/randperm.c, src/make-prime-list.c, src/system.h:
Include attribute.h.
* gl/lib/strnumcmp.c (strnumcmp): Remove _GL_ATTRIBUTE_PURE here,
as this belongs in the .h file.
* gl/lib/strnumcmp.h (strnumcmp): Add _GL_ATTRIBUTE_PURE here.
* src/sort.c (human_numcompare, numcompare): Now ATTRIBUTE_PURE;
discovered due to strnumcmp.h change.
* gl/lib/randperm.c, src/copy.c, src/dd.c, src/df.c, src/digest.c:
* src/env.c, src/expr.c, src/factor.c, src/ls.c:
* src/make-prime-list.c, src/numfmt.c, src/od.c, src/pathchk.c:
* src/pinky.c, src/pr.c, src/ptx.c, src/realpath.c, src/relpath.c:
* src/seq.c, src/sort.c, src/stat.c, src/stty.c, src/system.h:
* src/tr.c, src/uniq.c, src/wc.c:
In .c files, crefer ATTRIBUTE_CONST to _GL_ATTRIBUTE_CONST, and
similarly for ATTRIBUTE_FORMAT and ATTRIBUTE_PURE.
* src/system.h (FALLTHROUGH): Remove; attribute.h defines it.
2021-10-31 22:30:38 -07:00
|
|
|
ATTRIBUTE_PURE
|
|
|
|
|
static unsigned int
|
2019-05-28 08:21:42 -04:00
|
|
|
format_to_mask (char const *format)
|
|
|
|
|
{
|
|
|
|
|
unsigned int mask = 0;
|
|
|
|
|
|
maint: use C99 initialization syntax for single-variable 'for' loops
* src/chroot.c (parse_additional_groups): Declare variable in the 'for'
clause.
* src/comm.c (compare_files): Likewise.
* src/cp.c (re_protect): Likewise.
* src/csplit.c (save_buffer, find_line, write_to_file)
(split_file, main): Likewise.
* src/dd.c (apply_translations, translate_buffer)
(copy_with_block, main): Likewise.
* src/df.c (selected_fstype, excluded_fstype, filter_mount_list)
(last_device_for_mount, get_device, get_point, get_all_entries)
(main): Likewise.
* src/fmt.c (copy_rest, get_prefix, fmt_paragraph, put_paragraph)
(put_word): Likewise.
* src/fold.c (main): Likewise.
* src/head.c (elide_tail_bytes_pipe, main): Likewise.
* src/install.c (main): Likewise.
* src/join.c (prfields, join, main): Likewise.
* src/kill.c (list_signals): Likewise.
* src/ls.c (main, decode_switches, parse_ls_color, patterns_match):
Likewise.
* src/operand2sig.c (operand2sig): Likewise.
* src/pathchk.c (no_leading_hyphen, validate_file_name): Likewise.
* src/pr.c (char_to_clump): Likewise.
* src/printenv.c (main): Likewise.
* src/ptx.c (initialize_regex, digest_break_file)
(find_occurs_in_text, print_field): Likewise.
* src/remove.c (mark_ancestor_dirs): Likewise.
* src/seq.c (print_numbers): Likewise.
* src/shred.c (do_wipefd, main): Likewise.
* src/sort.c (cleanup, inittables, key_warnings, mergefps)
(check_ordering_compatibility, main): Likewise.
* src/split.c (closeout): Likewise.
* src/stat.c (find_bind_mount, print_it, format_to_mask): Likewise.
* src/stdbuf.c (set_program_path): Likewise.
* src/stty.c (apply_settings, display_changed, display_all)
(recover_mode, sane_mode): Likewise.
* src/system.h (stzncpy): Likewise.
* src/tail.c (pipe_lines): Likewise.
* src/tee.c (tee_files): Likewise.
* src/tr.c (look_up_char_class, get_spec_stats): Likewise.
* src/users.c (list_entries_users): Likewise.
2025-11-16 20:23:30 -08:00
|
|
|
for (char const *b = format; *b; b++)
|
2019-05-28 08:21:42 -04:00
|
|
|
{
|
|
|
|
|
if (*b != '%')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
b += format_code_offset (b);
|
|
|
|
|
if (*b == '\0')
|
|
|
|
|
break;
|
|
|
|
|
mask |= fmt_to_mask (*b);
|
|
|
|
|
}
|
|
|
|
|
return mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* statx the file and print what we find */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static bool
|
2019-05-28 08:21:42 -04:00
|
|
|
do_stat (char const *filename, char const *format, char const *format2)
|
|
|
|
|
{
|
2025-09-17 09:12:23 -07:00
|
|
|
int fd = streq (filename, "-") ? 0 : AT_FDCWD;
|
2019-05-28 08:21:42 -04:00
|
|
|
int flags = 0;
|
|
|
|
|
struct stat st;
|
2023-08-30 07:39:34 -07:00
|
|
|
struct statx stx = {0};
|
2021-04-11 18:23:21 +01:00
|
|
|
char const *pathname = filename;
|
2019-05-28 08:21:42 -04:00
|
|
|
struct print_args pa;
|
|
|
|
|
pa.st = &st;
|
2023-08-30 07:39:34 -07:00
|
|
|
pa.btime = (struct timespec) {.tv_sec = -1, .tv_nsec = -1};
|
2019-05-28 08:21:42 -04:00
|
|
|
|
|
|
|
|
if (AT_FDCWD != fd)
|
|
|
|
|
{
|
|
|
|
|
pathname = "";
|
|
|
|
|
flags = AT_EMPTY_PATH;
|
|
|
|
|
}
|
|
|
|
|
else if (!follow_links)
|
|
|
|
|
{
|
|
|
|
|
flags = AT_SYMLINK_NOFOLLOW;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dont_sync)
|
|
|
|
|
flags |= AT_STATX_DONT_SYNC;
|
|
|
|
|
else if (force_sync)
|
|
|
|
|
flags |= AT_STATX_FORCE_SYNC;
|
|
|
|
|
|
2022-03-07 23:29:20 +00:00
|
|
|
if (! force_sync)
|
|
|
|
|
flags |= AT_NO_AUTOMOUNT;
|
|
|
|
|
|
2019-05-28 08:21:42 -04:00
|
|
|
fd = statx (fd, pathname, flags, format_to_mask (format), &stx);
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
{
|
|
|
|
|
if (flags & AT_EMPTY_PATH)
|
|
|
|
|
error (0, errno, _("cannot stat standard input"));
|
|
|
|
|
else
|
|
|
|
|
error (0, errno, _("cannot statx %s"), quoteaf (filename));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (S_ISBLK (stx.stx_mode) || S_ISCHR (stx.stx_mode))
|
|
|
|
|
format = format2;
|
|
|
|
|
|
|
|
|
|
statx_to_stat (&stx, &st);
|
|
|
|
|
if (stx.stx_mask & STATX_BTIME)
|
|
|
|
|
pa.btime = statx_timestamp_to_timespec (stx.stx_btime);
|
|
|
|
|
|
|
|
|
|
bool fail = print_it (format, fd, filename, print_stat, &pa);
|
|
|
|
|
return ! fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else /* USE_STATX */
|
|
|
|
|
|
|
|
|
|
static struct timespec
|
|
|
|
|
get_birthtime (int fd, char const *filename, struct stat const *st)
|
|
|
|
|
{
|
|
|
|
|
struct timespec ts = get_stat_birthtime (st);
|
|
|
|
|
|
|
|
|
|
# if HAVE_GETATTRAT
|
|
|
|
|
if (ts.tv_nsec < 0)
|
|
|
|
|
{
|
|
|
|
|
nvlist_t *response;
|
|
|
|
|
if ((fd < 0
|
|
|
|
|
? getattrat (AT_FDCWD, XATTR_VIEW_READWRITE, filename, &response)
|
|
|
|
|
: fgetattr (fd, XATTR_VIEW_READWRITE, &response))
|
|
|
|
|
== 0)
|
|
|
|
|
{
|
|
|
|
|
uint64_t *val;
|
|
|
|
|
uint_t n;
|
|
|
|
|
if (nvlist_lookup_uint64_array (response, A_CRTIME, &val, &n) == 0
|
|
|
|
|
&& 2 <= n
|
|
|
|
|
&& val[0] <= TYPE_MAXIMUM (time_t)
|
|
|
|
|
&& val[1] < 1000000000 * 2 /* for leap seconds */)
|
|
|
|
|
{
|
|
|
|
|
ts.tv_sec = val[0];
|
|
|
|
|
ts.tv_nsec = val[1];
|
|
|
|
|
}
|
|
|
|
|
nvlist_free (response);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
return ts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-04-13 13:47:14 +00:00
|
|
|
/* stat the file and print what we find */
|
2021-10-31 22:30:38 -07:00
|
|
|
NODISCARD
|
|
|
|
|
static bool
|
2011-12-04 14:08:54 +01:00
|
|
|
do_stat (char const *filename, char const *format,
|
2010-10-01 11:44:05 -06:00
|
|
|
char const *format2)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2025-09-17 09:12:23 -07:00
|
|
|
int fd = streq (filename, "-") ? 0 : -1;
|
2002-04-13 13:47:14 +00:00
|
|
|
struct stat statbuf;
|
2019-05-28 08:21:42 -04:00
|
|
|
struct print_args pa;
|
|
|
|
|
pa.st = &statbuf;
|
2023-08-30 07:39:34 -07:00
|
|
|
pa.btime = (struct timespec) {.tv_sec = -1, .tv_nsec = -1};
|
2002-04-13 13:47:14 +00:00
|
|
|
|
2014-03-18 16:12:26 -07:00
|
|
|
if (0 <= fd)
|
2009-09-15 23:07:18 +02:00
|
|
|
{
|
2014-03-18 16:12:26 -07:00
|
|
|
if (fstat (fd, &statbuf) != 0)
|
2009-09-15 23:07:18 +02:00
|
|
|
{
|
|
|
|
|
error (0, errno, _("cannot stat standard input"));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-10-08 06:04:09 -06:00
|
|
|
/* We can't use the shorter
|
2009-10-23 06:06:46 -06:00
|
|
|
(follow_links?stat:lstat) (filename, &statbug)
|
2009-10-08 06:04:09 -06:00
|
|
|
since stat might be a function-like macro. */
|
|
|
|
|
else if ((follow_links
|
|
|
|
|
? stat (filename, &statbuf)
|
|
|
|
|
: lstat (filename, &statbuf)) != 0)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2015-11-01 18:53:26 +00:00
|
|
|
error (0, errno, _("cannot stat %s"), quoteaf (filename));
|
2004-08-03 19:08:31 +00:00
|
|
|
return false;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2010-10-01 11:44:05 -06:00
|
|
|
if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode))
|
|
|
|
|
format = format2;
|
|
|
|
|
|
2019-05-28 08:21:42 -04:00
|
|
|
bool fail = print_it (format, fd, filename, print_stat, &pa);
|
2010-10-01 11:44:05 -06:00
|
|
|
return ! fail;
|
|
|
|
|
}
|
2019-05-28 08:21:42 -04:00
|
|
|
#endif /* USE_STATX */
|
|
|
|
|
|
2022-07-22 13:50:31 -07:00
|
|
|
/* POSIX requires 'ls' to print file sizes without a sign, even
|
|
|
|
|
when negative. Be consistent with that. */
|
|
|
|
|
|
|
|
|
|
static uintmax_t
|
|
|
|
|
unsigned_file_size (off_t size)
|
|
|
|
|
{
|
|
|
|
|
return size + (size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1);
|
|
|
|
|
}
|
2019-05-28 08:21:42 -04:00
|
|
|
|
|
|
|
|
/* Print stat info. Return zero upon success, nonzero upon failure. */
|
|
|
|
|
static bool
|
2021-06-20 15:16:49 +01:00
|
|
|
print_stat (char *pformat, size_t prefix_len, char mod, char m,
|
2025-05-09 15:52:15 -07:00
|
|
|
MAYBE_UNUSED int fd, char const *filename, void const *data)
|
2019-05-28 08:21:42 -04:00
|
|
|
{
|
|
|
|
|
struct print_args *parg = (struct print_args *) data;
|
|
|
|
|
struct stat *statbuf = parg->st;
|
|
|
|
|
struct timespec btime = parg->btime;
|
|
|
|
|
struct passwd *pw_ent;
|
|
|
|
|
struct group *gw_ent;
|
|
|
|
|
bool fail = false;
|
|
|
|
|
|
|
|
|
|
switch (m)
|
|
|
|
|
{
|
|
|
|
|
case 'n':
|
|
|
|
|
out_string (pformat, prefix_len, filename);
|
|
|
|
|
break;
|
|
|
|
|
case 'N':
|
|
|
|
|
out_string (pformat, prefix_len, quoteN (filename));
|
|
|
|
|
if (S_ISLNK (statbuf->st_mode))
|
|
|
|
|
{
|
|
|
|
|
char *linkname = areadlink_with_size (filename, statbuf->st_size);
|
2026-01-18 15:55:38 +00:00
|
|
|
if (linkname == NULL)
|
2019-05-28 08:21:42 -04:00
|
|
|
{
|
|
|
|
|
error (0, errno, _("cannot read symbolic link %s"),
|
|
|
|
|
quoteaf (filename));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
printf (" -> ");
|
|
|
|
|
out_string (pformat, prefix_len, quoteN (linkname));
|
|
|
|
|
free (linkname);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'd':
|
2021-06-20 15:16:49 +01:00
|
|
|
if (mod == 'H')
|
|
|
|
|
out_uint (pformat, prefix_len, major (statbuf->st_dev));
|
|
|
|
|
else if (mod == 'L')
|
|
|
|
|
out_uint (pformat, prefix_len, minor (statbuf->st_dev));
|
|
|
|
|
else
|
|
|
|
|
out_uint (pformat, prefix_len, statbuf->st_dev);
|
2019-05-28 08:21:42 -04:00
|
|
|
break;
|
|
|
|
|
case 'D':
|
|
|
|
|
out_uint_x (pformat, prefix_len, statbuf->st_dev);
|
|
|
|
|
break;
|
|
|
|
|
case 'i':
|
|
|
|
|
out_uint (pformat, prefix_len, statbuf->st_ino);
|
|
|
|
|
break;
|
|
|
|
|
case 'a':
|
|
|
|
|
out_uint_o (pformat, prefix_len, statbuf->st_mode & CHMOD_MODE_BITS);
|
|
|
|
|
break;
|
|
|
|
|
case 'A':
|
|
|
|
|
out_string (pformat, prefix_len, human_access (statbuf));
|
|
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
out_uint_x (pformat, prefix_len, statbuf->st_mode);
|
|
|
|
|
break;
|
|
|
|
|
case 'F':
|
|
|
|
|
out_string (pformat, prefix_len, file_type (statbuf));
|
|
|
|
|
break;
|
|
|
|
|
case 'h':
|
|
|
|
|
out_uint (pformat, prefix_len, statbuf->st_nlink);
|
|
|
|
|
break;
|
|
|
|
|
case 'u':
|
|
|
|
|
out_uint (pformat, prefix_len, statbuf->st_uid);
|
|
|
|
|
break;
|
|
|
|
|
case 'U':
|
|
|
|
|
pw_ent = getpwuid (statbuf->st_uid);
|
|
|
|
|
out_string (pformat, prefix_len,
|
|
|
|
|
pw_ent ? pw_ent->pw_name : "UNKNOWN");
|
|
|
|
|
break;
|
|
|
|
|
case 'g':
|
|
|
|
|
out_uint (pformat, prefix_len, statbuf->st_gid);
|
|
|
|
|
break;
|
|
|
|
|
case 'G':
|
|
|
|
|
gw_ent = getgrgid (statbuf->st_gid);
|
|
|
|
|
out_string (pformat, prefix_len,
|
|
|
|
|
gw_ent ? gw_ent->gr_name : "UNKNOWN");
|
|
|
|
|
break;
|
|
|
|
|
case 'm':
|
|
|
|
|
fail |= out_mount_point (filename, pformat, prefix_len, statbuf);
|
|
|
|
|
break;
|
|
|
|
|
case 's':
|
2022-07-22 13:50:31 -07:00
|
|
|
out_uint (pformat, prefix_len, unsigned_file_size (statbuf->st_size));
|
2019-05-28 08:21:42 -04:00
|
|
|
break;
|
2021-06-20 15:16:49 +01:00
|
|
|
case 'r':
|
|
|
|
|
if (mod == 'H')
|
|
|
|
|
out_uint (pformat, prefix_len, major (statbuf->st_rdev));
|
|
|
|
|
else if (mod == 'L')
|
|
|
|
|
out_uint (pformat, prefix_len, minor (statbuf->st_rdev));
|
|
|
|
|
else
|
|
|
|
|
out_uint (pformat, prefix_len, statbuf->st_rdev);
|
|
|
|
|
break;
|
|
|
|
|
case 'R':
|
|
|
|
|
out_uint_x (pformat, prefix_len, statbuf->st_rdev);
|
|
|
|
|
break;
|
2019-05-28 08:21:42 -04:00
|
|
|
case 't':
|
|
|
|
|
out_uint_x (pformat, prefix_len, major (statbuf->st_rdev));
|
|
|
|
|
break;
|
|
|
|
|
case 'T':
|
|
|
|
|
out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev));
|
|
|
|
|
break;
|
|
|
|
|
case 'B':
|
|
|
|
|
out_uint (pformat, prefix_len, ST_NBLOCKSIZE);
|
|
|
|
|
break;
|
|
|
|
|
case 'b':
|
maint: prefer psame_inode, PSAME_INODE, STP_*
Prefer psame_inode, PSAME_INODE, STP_NBLOCKS, and STP_BLKSIZE,
which take addresses of objects, to their counterparts that
take the whole objects. In some cases the whole objects might
not be initialized, which would be undefined behavior strictly
speaking.
* gl/lib/root-dev-ino.h (ROOT_DEV_INO_CHECK):
* src/cp-hash.c (src_to_dest_compare):
* src/ls.c (dev_ino_compare):
* src/pwd.c (robust_getcwd):
Prefer PSAME_INODE to SAME_INODE.
* src/chown-core.c (restricted_chown):
* src/copy.c (copy_reg, same_file_ok, source_is_dst_backup)
(copy_internal):
* src/ln.c (do_link):
* src/pwd.c (logical_getcwd):
* src/sort.c (avoid_trashing_input):
* src/split.c (create):
* src/stat.c (find_bind_mount):
Prefer psame_inode to SAME_INODE.
* src/copy.c (infer_scantype):
* src/du.c (process_file):
* src/ls.c (gobble_file, print_long_format)
(print_file_name_and_frills, length_of_file_name_and_frills):
* src/stat.c (print_stat):
Prefer STP_NBLOCKS to ST_NBLOCKS.
* src/copy.c (copy_reg):
* src/head.c (elide_tail_bytes_file, elide_tail_lines_file):
* src/ioblksize.h (io_blksize):
* src/od.c (skip):
* src/shred.c (do_wipefd):
* src/stat.c (print_stat):
* src/tail.c (tail_bytes):
* src/truncate.c (do_ftruncate):
* src/wc.c (wc):
Prefer STP_BLKSIZE to ST_BLKSIZE.
* src/ioblksize.h (io_blksize):
Arg is now struct stat const *, not struct stat. All callers changed.
2023-09-04 23:04:47 -07:00
|
|
|
out_uint (pformat, prefix_len, STP_NBLOCKS (statbuf));
|
2019-05-28 08:21:42 -04:00
|
|
|
break;
|
|
|
|
|
case 'o':
|
maint: prefer psame_inode, PSAME_INODE, STP_*
Prefer psame_inode, PSAME_INODE, STP_NBLOCKS, and STP_BLKSIZE,
which take addresses of objects, to their counterparts that
take the whole objects. In some cases the whole objects might
not be initialized, which would be undefined behavior strictly
speaking.
* gl/lib/root-dev-ino.h (ROOT_DEV_INO_CHECK):
* src/cp-hash.c (src_to_dest_compare):
* src/ls.c (dev_ino_compare):
* src/pwd.c (robust_getcwd):
Prefer PSAME_INODE to SAME_INODE.
* src/chown-core.c (restricted_chown):
* src/copy.c (copy_reg, same_file_ok, source_is_dst_backup)
(copy_internal):
* src/ln.c (do_link):
* src/pwd.c (logical_getcwd):
* src/sort.c (avoid_trashing_input):
* src/split.c (create):
* src/stat.c (find_bind_mount):
Prefer psame_inode to SAME_INODE.
* src/copy.c (infer_scantype):
* src/du.c (process_file):
* src/ls.c (gobble_file, print_long_format)
(print_file_name_and_frills, length_of_file_name_and_frills):
* src/stat.c (print_stat):
Prefer STP_NBLOCKS to ST_NBLOCKS.
* src/copy.c (copy_reg):
* src/head.c (elide_tail_bytes_file, elide_tail_lines_file):
* src/ioblksize.h (io_blksize):
* src/od.c (skip):
* src/shred.c (do_wipefd):
* src/stat.c (print_stat):
* src/tail.c (tail_bytes):
* src/truncate.c (do_ftruncate):
* src/wc.c (wc):
Prefer STP_BLKSIZE to ST_BLKSIZE.
* src/ioblksize.h (io_blksize):
Arg is now struct stat const *, not struct stat. All callers changed.
2023-09-04 23:04:47 -07:00
|
|
|
out_uint (pformat, prefix_len, STP_BLKSIZE (statbuf));
|
2019-05-28 08:21:42 -04:00
|
|
|
break;
|
|
|
|
|
case 'w':
|
|
|
|
|
{
|
|
|
|
|
#if ! USE_STATX
|
|
|
|
|
btime = get_birthtime (fd, filename, statbuf);
|
|
|
|
|
#endif
|
|
|
|
|
if (btime.tv_nsec < 0)
|
|
|
|
|
out_string (pformat, prefix_len, "-");
|
|
|
|
|
else
|
|
|
|
|
out_string (pformat, prefix_len, human_time (btime));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'W':
|
|
|
|
|
{
|
|
|
|
|
#if ! USE_STATX
|
|
|
|
|
btime = get_birthtime (fd, filename, statbuf);
|
|
|
|
|
#endif
|
|
|
|
|
out_epoch_sec (pformat, prefix_len, neg_to_zero (btime));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'x':
|
|
|
|
|
out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf)));
|
|
|
|
|
break;
|
|
|
|
|
case 'X':
|
|
|
|
|
out_epoch_sec (pformat, prefix_len, get_stat_atime (statbuf));
|
|
|
|
|
break;
|
|
|
|
|
case 'y':
|
|
|
|
|
out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf)));
|
|
|
|
|
break;
|
|
|
|
|
case 'Y':
|
|
|
|
|
out_epoch_sec (pformat, prefix_len, get_stat_mtime (statbuf));
|
|
|
|
|
break;
|
|
|
|
|
case 'z':
|
|
|
|
|
out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf)));
|
|
|
|
|
break;
|
|
|
|
|
case 'Z':
|
|
|
|
|
out_epoch_sec (pformat, prefix_len, get_stat_ctime (statbuf));
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
fail |= out_file_context (pformat, prefix_len, filename);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fputc ('?', stdout);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return fail;
|
|
|
|
|
}
|
2010-10-01 11:44:05 -06:00
|
|
|
|
|
|
|
|
/* Return an allocated format string in static storage that
|
|
|
|
|
corresponds to whether FS and TERSE options were declared. */
|
|
|
|
|
static char *
|
|
|
|
|
default_format (bool fs, bool terse, bool device)
|
|
|
|
|
{
|
|
|
|
|
char *format;
|
|
|
|
|
if (fs)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2004-08-03 19:08:31 +00:00
|
|
|
if (terse)
|
2017-10-11 22:33:28 +02:00
|
|
|
format = xstrdup (fmt_terse_fs);
|
2010-10-01 11:44:05 -06:00
|
|
|
else
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
2010-10-01 11:44:05 -06:00
|
|
|
/* TRANSLATORS: This string uses format specifiers from
|
|
|
|
|
'stat --help' with --file-system, and NOT from printf. */
|
2012-01-09 22:56:54 +01:00
|
|
|
format = xstrdup (_(" File: \"%n\"\n"
|
|
|
|
|
" ID: %-8i Namelen: %-7l Type: %T\n"
|
|
|
|
|
"Block size: %-10s Fundamental block size: %S\n"
|
|
|
|
|
"Blocks: Total: %-10b Free: %-10f Available: %a\n"
|
|
|
|
|
"Inodes: Total: %-10c Free: %d\n"));
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
2010-10-01 11:44:05 -06:00
|
|
|
}
|
|
|
|
|
else /* ! fs */
|
|
|
|
|
{
|
|
|
|
|
if (terse)
|
2010-10-01 11:54:34 -06:00
|
|
|
{
|
|
|
|
|
if (0 < is_selinux_enabled ())
|
2017-10-11 22:33:28 +02:00
|
|
|
format = xstrdup (fmt_terse_selinux);
|
2010-10-01 11:54:34 -06:00
|
|
|
else
|
2017-10-11 22:33:28 +02:00
|
|
|
format = xstrdup (fmt_terse_regular);
|
2010-10-01 11:54:34 -06:00
|
|
|
}
|
2002-04-14 08:20:15 +00:00
|
|
|
else
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
2010-10-01 11:44:05 -06:00
|
|
|
char *temp;
|
|
|
|
|
/* TRANSLATORS: This string uses format specifiers from
|
|
|
|
|
'stat --help' without --file-system, and NOT from printf. */
|
|
|
|
|
format = xstrdup (_("\
|
|
|
|
|
File: %N\n\
|
|
|
|
|
Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n\
|
|
|
|
|
"));
|
|
|
|
|
|
|
|
|
|
temp = format;
|
|
|
|
|
if (device)
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
2010-10-01 11:44:05 -06:00
|
|
|
/* TRANSLATORS: This string uses format specifiers from
|
|
|
|
|
'stat --help' without --file-system, and NOT from printf. */
|
|
|
|
|
format = xasprintf ("%s%s", format, _("\
|
2021-06-20 21:26:21 +01:00
|
|
|
" "Device: %Hd,%Ld\tInode: %-10i Links: %-5h Device type: %Hr,%Lr\n\
|
2010-10-01 11:44:05 -06:00
|
|
|
"));
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2010-10-01 11:44:05 -06:00
|
|
|
/* TRANSLATORS: This string uses format specifiers from
|
|
|
|
|
'stat --help' without --file-system, and NOT from printf. */
|
|
|
|
|
format = xasprintf ("%s%s", format, _("\
|
2021-06-20 21:26:21 +01:00
|
|
|
" "Device: %Hd,%Ld\tInode: %-10i Links: %h\n\
|
2010-10-01 11:44:05 -06:00
|
|
|
"));
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
2010-10-01 11:44:05 -06:00
|
|
|
free (temp);
|
|
|
|
|
|
|
|
|
|
temp = format;
|
|
|
|
|
/* TRANSLATORS: This string uses format specifiers from
|
|
|
|
|
'stat --help' without --file-system, and NOT from printf. */
|
|
|
|
|
format = xasprintf ("%s%s", format, _("\
|
2012-01-09 22:56:54 +01:00
|
|
|
" "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n\
|
2010-10-01 11:54:34 -06:00
|
|
|
"));
|
|
|
|
|
free (temp);
|
|
|
|
|
|
|
|
|
|
if (0 < is_selinux_enabled ())
|
|
|
|
|
{
|
|
|
|
|
temp = format;
|
|
|
|
|
/* TRANSLATORS: This string uses format specifiers from
|
|
|
|
|
'stat --help' without --file-system, and NOT from printf. */
|
2012-01-09 22:56:54 +01:00
|
|
|
format = xasprintf ("%s%s", format, _("Context: %C\n"));
|
2010-10-01 11:54:34 -06:00
|
|
|
free (temp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
temp = format;
|
2012-01-09 22:56:54 +01:00
|
|
|
format = xasprintf ("%s%s", format,
|
2024-06-25 12:18:40 +02:00
|
|
|
/* TRANSLATORS: This string uses format specifiers
|
|
|
|
|
from 'stat --help' without --file-system, and
|
|
|
|
|
NOT from printf. */
|
2012-01-09 22:56:54 +01:00
|
|
|
_("Access: %x\n"
|
|
|
|
|
"Modify: %y\n"
|
|
|
|
|
"Change: %z\n"
|
2012-01-11 15:29:18 +00:00
|
|
|
" Birth: %w\n"));
|
2010-10-01 11:44:05 -06:00
|
|
|
free (temp);
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
2010-10-01 11:44:05 -06:00
|
|
|
return format;
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2002-04-13 14:11:44 +00:00
|
|
|
usage (int status)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
2004-01-21 23:45:21 +00:00
|
|
|
if (status != EXIT_SUCCESS)
|
2012-01-07 16:54:26 +01:00
|
|
|
emit_try_help ();
|
2002-04-13 14:11:44 +00:00
|
|
|
else
|
|
|
|
|
{
|
2008-06-28 09:53:03 +02:00
|
|
|
printf (_("Usage: %s [OPTION]... FILE...\n"), program_name);
|
2002-04-13 14:11:44 +00:00
|
|
|
fputs (_("\
|
2004-06-30 22:31:43 +00:00
|
|
|
Display file or file system status.\n\
|
maint: define usage note about mandatory args centrally
Each program with at least one long option which is marked as
'required_argument' and which has also a short option for that
option, should print a note about mandatory arguments.
Define that well-known note centrally and use it rather than
literal printf/fputs, and add it where it was missing.
* src/system.h (emit_mandatory_arg_note): Add new function.
* src/cp.c (usage): Use it rather than literal printf/fputs.
* src/csplit.c, src/cut.c, src/date.c, src/df.c, src/du.c:
* src/expand.c, src/fmt.c, src/fold.c, src/head.c, src/install.c:
* src/kill.c, src/ln.c, src/ls.c, src/mkdir.c, src/mkfifo.c:
* src/mknod.c, src/mv.c, src/nl.c, src/od.c, src/paste.c:
* src/pr.c, src/ptx.c, src/shred.c, src/shuf.c, src/sort.c:
* src/split.c, src/stdbuf.c, src/tac.c, src/tail.c, src/timeout.c:
* src/touch.c, src/truncate.c, src/unexpand.c, src/uniq.c:
Likewise.
* src/base64.c (usage): Add call of the above new function
because at least one long option has a required argument.
* src/basename.c, src/chcon.c, src/date.c, src/env.c:
* src/nice.c, src/runcon.c, src/seq.c, src/stat.c, src/stty.c:
Likewise.
2013-01-23 01:03:38 +01:00
|
|
|
"), stdout);
|
|
|
|
|
|
|
|
|
|
emit_mandatory_arg_note ();
|
|
|
|
|
|
2026-01-01 16:31:44 +00:00
|
|
|
oputs (_("\
|
|
|
|
|
-L, --dereference\n\
|
|
|
|
|
follow links\n\
|
|
|
|
|
"));
|
|
|
|
|
oputs (_("\
|
|
|
|
|
-f, --file-system\n\
|
|
|
|
|
display file system status instead of file status\n\
|
|
|
|
|
"));
|
|
|
|
|
oputs (_("\
|
|
|
|
|
--cached=MODE\n\
|
|
|
|
|
specify how to use cached attributes;\n\
|
|
|
|
|
useful on remote file systems. See MODE below\n\
|
|
|
|
|
"));
|
|
|
|
|
oputs (_("\
|
2026-01-22 16:15:26 +00:00
|
|
|
-c, --format=FORMAT\n\
|
2026-01-01 16:31:44 +00:00
|
|
|
use the specified FORMAT instead of the default;\n\
|
|
|
|
|
output a newline after each use of FORMAT\n\
|
|
|
|
|
"));
|
|
|
|
|
oputs (_("\
|
|
|
|
|
--printf=FORMAT\n\
|
|
|
|
|
like --format, but interpret backslash escapes,\n\
|
|
|
|
|
and do not output a mandatory trailing newline;\n\
|
|
|
|
|
if you want a newline, include \\n in FORMAT\n\
|
|
|
|
|
"));
|
|
|
|
|
oputs (_("\
|
|
|
|
|
-t, --terse\n\
|
|
|
|
|
print the information in terse form\n\
|
|
|
|
|
"));
|
|
|
|
|
oputs (HELP_OPTION_DESCRIPTION);
|
|
|
|
|
oputs (VERSION_OPTION_DESCRIPTION);
|
2002-04-14 07:47:44 +00:00
|
|
|
|
2019-05-28 08:21:42 -04:00
|
|
|
fputs (_("\n\
|
2020-09-29 14:31:52 +02:00
|
|
|
The MODE argument of --cached can be: always, never, or default.\n\
|
|
|
|
|
'always' will use cached attributes if available, while\n\
|
|
|
|
|
'never' will try to synchronize with the latest attributes, and\n\
|
|
|
|
|
'default' will leave it up to the underlying file system.\n\
|
2019-05-28 08:21:42 -04:00
|
|
|
"), stdout);
|
|
|
|
|
|
2002-04-14 07:47:44 +00:00
|
|
|
fputs (_("\n\
|
2004-06-30 22:31:43 +00:00
|
|
|
The valid format sequences for files (without --file-system):\n\
|
2002-04-14 07:47:44 +00:00
|
|
|
\n\
|
2024-02-24 14:03:42 -08:00
|
|
|
%a permission bits in octal (see '#' and '0' printf flags)\n\
|
2020-02-15 11:16:35 +00:00
|
|
|
%A permission bits and file type in human readable form\n\
|
2011-12-24 12:03:18 +01:00
|
|
|
%b number of blocks allocated (see %B)\n\
|
|
|
|
|
%B the size in bytes of each block reported by %b\n\
|
2007-01-07 09:15:42 +01:00
|
|
|
%C SELinux security context string\n\
|
2002-04-14 07:47:44 +00:00
|
|
|
"), stdout);
|
|
|
|
|
fputs (_("\
|
2021-06-20 15:16:49 +01:00
|
|
|
%d device number in decimal (st_dev)\n\
|
|
|
|
|
%D device number in hex (st_dev)\n\
|
|
|
|
|
%Hd major device number in decimal\n\
|
|
|
|
|
%Ld minor device number in decimal\n\
|
2011-12-24 12:03:18 +01:00
|
|
|
%f raw mode in hex\n\
|
|
|
|
|
%F file type\n\
|
|
|
|
|
%g group ID of owner\n\
|
|
|
|
|
%G group name of owner\n\
|
2002-04-14 07:47:44 +00:00
|
|
|
"), stdout);
|
|
|
|
|
fputs (_("\
|
2011-12-24 12:03:18 +01:00
|
|
|
%h number of hard links\n\
|
|
|
|
|
%i inode number\n\
|
|
|
|
|
%m mount point\n\
|
|
|
|
|
%n file name\n\
|
|
|
|
|
%N quoted file name with dereference if symbolic link\n\
|
2012-01-20 14:22:56 +00:00
|
|
|
%o optimal I/O transfer size hint\n\
|
2011-12-24 12:03:18 +01:00
|
|
|
%s total size, in bytes\n\
|
2021-06-20 15:16:49 +01:00
|
|
|
%r device type in decimal (st_rdev)\n\
|
|
|
|
|
%R device type in hex (st_rdev)\n\
|
|
|
|
|
%Hr major device type in decimal, for character/block device special files\n\
|
|
|
|
|
%Lr minor device type in decimal, for character/block device special files\n\
|
2013-03-12 13:43:08 +00:00
|
|
|
%t major device type in hex, for character/block device special files\n\
|
|
|
|
|
%T minor device type in hex, for character/block device special files\n\
|
2002-04-14 07:47:44 +00:00
|
|
|
"), stdout);
|
|
|
|
|
fputs (_("\
|
2011-12-24 12:03:18 +01:00
|
|
|
%u user ID of owner\n\
|
|
|
|
|
%U user name of owner\n\
|
|
|
|
|
%w time of file birth, human-readable; - if unknown\n\
|
|
|
|
|
%W time of file birth, seconds since Epoch; 0 if unknown\n\
|
|
|
|
|
%x time of last access, human-readable\n\
|
|
|
|
|
%X time of last access, seconds since Epoch\n\
|
2014-04-21 14:31:23 -04:00
|
|
|
%y time of last data modification, human-readable\n\
|
|
|
|
|
%Y time of last data modification, seconds since Epoch\n\
|
|
|
|
|
%z time of last status change, human-readable\n\
|
|
|
|
|
%Z time of last status change, seconds since Epoch\n\
|
2002-04-14 07:47:44 +00:00
|
|
|
\n\
|
|
|
|
|
"), stdout);
|
|
|
|
|
|
|
|
|
|
fputs (_("\
|
|
|
|
|
Valid format sequences for file systems:\n\
|
|
|
|
|
\n\
|
2011-12-24 12:03:18 +01:00
|
|
|
%a free blocks available to non-superuser\n\
|
|
|
|
|
%b total data blocks in file system\n\
|
|
|
|
|
%c total file nodes in file system\n\
|
|
|
|
|
%d free file nodes in file system\n\
|
|
|
|
|
%f free blocks in file system\n\
|
2002-04-14 07:47:44 +00:00
|
|
|
"), stdout);
|
|
|
|
|
fputs (_("\
|
2011-12-24 12:03:18 +01:00
|
|
|
%i file system ID in hex\n\
|
|
|
|
|
%l maximum length of filenames\n\
|
|
|
|
|
%n file name\n\
|
|
|
|
|
%s block size (for faster transfers)\n\
|
|
|
|
|
%S fundamental block size (for block counts)\n\
|
|
|
|
|
%t file system type in hex\n\
|
|
|
|
|
%T file system type in human readable form\n\
|
2002-04-14 07:47:44 +00:00
|
|
|
"), stdout);
|
2017-10-11 22:33:28 +02:00
|
|
|
|
|
|
|
|
printf (_("\n\
|
|
|
|
|
--terse is equivalent to the following FORMAT:\n\
|
|
|
|
|
%s\
|
|
|
|
|
"),
|
|
|
|
|
#if HAVE_SELINUX_SELINUX_H
|
|
|
|
|
fmt_terse_selinux
|
|
|
|
|
#else
|
|
|
|
|
fmt_terse_regular
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
printf (_("\
|
|
|
|
|
--terse --file-system is equivalent to the following FORMAT:\n\
|
|
|
|
|
%s\
|
|
|
|
|
"), fmt_terse_fs);
|
|
|
|
|
|
2005-04-04 22:30:57 +00:00
|
|
|
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
|
2014-09-18 14:50:47 +01:00
|
|
|
emit_ancillary_info (PROGRAM_NAME);
|
2002-04-13 14:11:44 +00:00
|
|
|
}
|
|
|
|
|
exit (status);
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
|
{
|
2002-04-13 14:11:44 +00:00
|
|
|
int c;
|
2004-08-03 19:08:31 +00:00
|
|
|
bool fs = false;
|
|
|
|
|
bool terse = false;
|
2026-01-18 15:55:38 +00:00
|
|
|
char *format = NULL;
|
2010-10-01 11:44:05 -06:00
|
|
|
char *format2;
|
2004-08-03 19:08:31 +00:00
|
|
|
bool ok = true;
|
2002-04-13 13:47:14 +00:00
|
|
|
|
2003-06-17 18:13:23 +00:00
|
|
|
initialize_main (&argc, &argv);
|
2008-06-03 08:34:09 +02:00
|
|
|
set_program_name (argv[0]);
|
2002-04-13 14:11:44 +00:00
|
|
|
setlocale (LC_ALL, "");
|
|
|
|
|
bindtextdomain (PACKAGE, LOCALEDIR);
|
|
|
|
|
textdomain (PACKAGE);
|
|
|
|
|
|
stat: use e.g. %.3X instead of %X.%3:X for sub-second precision
* NEWS: Document this.
* doc/coreutils.texi (stat invocation): Likewise.
* gl/lib/fstimeprec.c, gl/lib/fstimeprec.h, gl/modules/fstimeprec:
* gl/modules/fstimeprec-tests, gl/tests/test-fstimeprec.c:
New files.
* bootstrap.conf (gnulib_modules): Add fstimeprec.
* src/stat.c: Include fstimeprec.h. Don't include xstrtol.h.
(decimal_point, decimal_point_len): New static vars.
(main): Initialize them.
(epoch_sec, out_ns): Remove.
(out_int, out_uint): Now returns whatever printf returned.
(out_minus_zero, out_epoch_secs): New functions.
(print_stat): Use out_epoch_sec instead of out_ns and epoch_sec.
(print_stat, print_it, usage): Remove the %:X-style formats.
* tests/misc/stat-nanoseconds: Set TZ=UTC0 to avoid problems
with weird time zones. Use a time stamp near the Epoch so that we
don't have to worry about leap seconds. Redo test cases to match
new behavior.
* tests/touch/60-seconds: Change %Y.%:Y to %.9Y, to adjust to
new behavior.
2010-11-05 19:35:12 -07:00
|
|
|
struct lconv const *locale = localeconv ();
|
|
|
|
|
decimal_point = (locale->decimal_point[0] ? locale->decimal_point : ".");
|
|
|
|
|
decimal_point_len = strlen (decimal_point);
|
|
|
|
|
|
2002-04-13 14:11:44 +00:00
|
|
|
atexit (close_stdout);
|
|
|
|
|
|
2026-01-18 15:55:38 +00:00
|
|
|
while ((c = getopt_long (argc, argv, "c:fLt", long_options, NULL)) != -1)
|
2002-04-13 13:47:14 +00:00
|
|
|
{
|
|
|
|
|
switch (c)
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
|
|
|
|
case PRINTF_OPTION:
|
|
|
|
|
format = optarg;
|
|
|
|
|
interpret_backslash_escapes = true;
|
|
|
|
|
trailing_delim = "";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'c':
|
|
|
|
|
format = optarg;
|
|
|
|
|
interpret_backslash_escapes = false;
|
|
|
|
|
trailing_delim = "\n";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'L':
|
|
|
|
|
follow_links = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'f':
|
|
|
|
|
fs = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 't':
|
|
|
|
|
terse = true;
|
|
|
|
|
break;
|
|
|
|
|
|
2019-05-28 08:21:42 -04:00
|
|
|
case 0:
|
|
|
|
|
switch (XARGMATCH ("--cached", optarg, cached_args, cached_modes))
|
|
|
|
|
{
|
|
|
|
|
case cached_never:
|
|
|
|
|
force_sync = true;
|
|
|
|
|
dont_sync = false;
|
|
|
|
|
break;
|
|
|
|
|
case cached_always:
|
|
|
|
|
force_sync = false;
|
|
|
|
|
dont_sync = true;
|
|
|
|
|
break;
|
|
|
|
|
case cached_default:
|
|
|
|
|
force_sync = false;
|
|
|
|
|
dont_sync = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2009-08-22 18:56:06 +02:00
|
|
|
case_GETOPT_HELP_CHAR;
|
|
|
|
|
|
|
|
|
|
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
usage (EXIT_FAILURE);
|
|
|
|
|
}
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|
2002-04-13 14:11:44 +00:00
|
|
|
|
2002-04-13 13:47:14 +00:00
|
|
|
if (argc == optind)
|
2002-04-13 14:11:44 +00:00
|
|
|
{
|
2004-06-21 15:03:35 +00:00
|
|
|
error (0, 0, _("missing operand"));
|
2002-04-13 14:11:44 +00:00
|
|
|
usage (EXIT_FAILURE);
|
|
|
|
|
}
|
2002-04-13 13:47:14 +00:00
|
|
|
|
2010-10-01 11:44:05 -06:00
|
|
|
if (format)
|
2016-11-03 15:36:48 +00:00
|
|
|
{
|
|
|
|
|
if (strstr (format, "%N"))
|
|
|
|
|
getenv_quoting_style ();
|
|
|
|
|
format2 = format;
|
|
|
|
|
}
|
2010-10-01 11:44:05 -06:00
|
|
|
else
|
|
|
|
|
{
|
2016-11-03 15:36:48 +00:00
|
|
|
format = default_format (fs, terse, /* device= */ false);
|
|
|
|
|
format2 = default_format (fs, terse, /* device= */ true);
|
2010-10-01 11:44:05 -06:00
|
|
|
}
|
|
|
|
|
|
2017-06-17 14:54:23 -07:00
|
|
|
for (int i = optind; i < argc; i++)
|
2004-08-03 19:08:31 +00:00
|
|
|
ok &= (fs
|
2011-12-04 14:08:54 +01:00
|
|
|
? do_statfs (argv[i], format)
|
|
|
|
|
: do_stat (argv[i], format, format2));
|
2002-04-13 13:47:14 +00:00
|
|
|
|
2022-01-31 08:42:07 -08:00
|
|
|
main_exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
|
2002-04-13 13:47:14 +00:00
|
|
|
}
|