usr.bin/stat Update

Change-Id: I029160c73baab1b3465bc5397a36c55886db225b
This commit is contained in:
Lionel Sambuc 2013-04-19 13:16:51 +02:00
parent f84d21b043
commit 474b24f91c
3 changed files with 131 additions and 35 deletions

View file

@ -228,7 +228,7 @@
2012/10/17 12:00:00,usr.bin/soelim
2012/10/17 12:00:00,usr.bin/sort
2012/10/17 12:00:00,usr.bin/split
2011/01/15 22:54:10,usr.bin/stat
2012/10/17 12:00:00,usr.bin/stat
2012/02/10 16:16:12,usr.bin/su
2013/10/06 12:00:00,usr.bin/tee
2012/06/01 12:08:40,usr.bin/tic

View file

@ -1,6 +1,6 @@
.\" $NetBSD: stat.1,v 1.28 2010/04/05 21:25:01 joerg Exp $
.\" $NetBSD: stat.1,v 1.34 2011/09/22 20:23:55 apb Exp $
.\"
.\" Copyright (c) 2002-2005 The NetBSD Foundation, Inc.
.\" Copyright (c) 2002-2011 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 7, 2008
.Dd September 22, 2011
.Dt STAT 1
.Os
.Sh NAME
@ -47,7 +47,7 @@
.Op Fl t Ar timefmt
.Op Ar
.Nm readlink
.Op Fl fn
.Op Fl fnqsv
.Op Ar
.Sh DESCRIPTION
The
@ -165,11 +165,16 @@ epoch, etc.)
Display information in
.Dq shell output ,
suitable for initializing variables.
When run as
.Nm readlink ,
suppress error messages.
.It Fl t Ar timefmt
Display timestamps using the specified format.
This format is
passed directly to
.Xr strftime 3 .
.It Fl v
Turn off quiet mode.
.It Fl x
Display information in a more verbose way as known from some Linux
distributions.
@ -197,9 +202,12 @@ examined for the following:
Any of the following optional flags:
.Bl -tag -width Ds
.It Cm #
Selects an alternate output form for octal and hexadecimal output.
Non-zero octal output will have a leading zero, and non-zero
hexadecimal output will have
Selects an alternate output form for string, octal and hexadecimal output.
String output will be encoded in
.Xr vis 3
style.
Non-zero octal output will have a leading zero.
Non-zero hexadecimal output will have
.Dq 0x
prepended to it.
.It Cm +
@ -430,7 +438,7 @@ is given.
The target of a symbolic link.
.It Cm Z
Expands to
.Dq major,minor
.Dq Ar major , Ns Ar minor
from the rdev field for character or block
special devices and gives size output for all others.
.El
@ -468,6 +476,41 @@ If no options are specified, the default format is
0 78852 -rw-r--r-- 1 root wheel 0 0 "Jul 8 10:26:03 2004" "Jul 8 10:26:03 2004" "Jul 8 10:28:13 2004" "Jan 1 09:00:00 1970" 16384 0 0 /tmp/bar
.Ed
.Pp
This example produces output very similar to that from
.Ic find ... -ls
(except that
.Xr find 1
displays the time in a different format, and
.Xr find 1
sometimes adds one or more spaces after the comma in
.Dq Ar major , Ns Ar minor
for device nodes):
.Bd -literal -offset indent
\*[Gt] stat -f "%7i %6b %-11Sp %3l %-17Su %-17Sg %9Z %Sm %N%SY" /tmp/bar
78852 0 -rw-r--r-- 1 root wheel 0 Jul 8 10:26:03 2004 /tmp/bar
\*[Gt] find /tmp/bar -ls -exit
78852 0 -rw-r--r-- 1 root wheel 0 Jul 8 2004 /tmp/bar
.Ed
.Pp
This example produces output very similar to that from
.Ic ls -lTd
(except that
.Xr ls 1
adjusts the column spacing differently when listing multiple files,
and
.Xr ls 1
adds at least one space after the comma in
.Dq Ar major , Ns Ar minor
for device nodes):
.Bd -literal -offset indent
\*[Gt] stat -f "%-11Sp %l %Su %Sg %Z %Sm %N%SY" /tmp/bar
-rw-r--r-- 1 root wheel 0 Jul 8 10:26:03 2004 /tmp/bar
\*[Gt] ls -lTd /tmp/bar
-rw-r--r-- 1 root wheel 0 Jul 8 10:26:03 2004 /tmp/bar
.Ed
.Pp
Given a symbolic link
.Dq foo
that points from
@ -542,6 +585,18 @@ Apr 25 11:47:00 2002 /tmp/blah
Apr 25 10:36:34 2002 /tmp/bar
Apr 24 16:47:35 2002 /tmp/foo
.Ed
.Pp
User names, group names, and file names that contain spaces
or other special characters may be encoded in
.Xr vis 3
style, using the
.Cm \&#
modifier:
.Bd -literal -offset indent
\*[Gt] ln -s 'target with spaces' 'link with spaces'
\*[Gt] stat -f "%#N%#SY" 'link with spaces'
link\eswith\esspaces -\*[Gt] target\eswith\esspaces
.Ed
.Sh SEE ALSO
.Xr basename 1 ,
.Xr dirname 1 ,

View file

@ -1,7 +1,7 @@
/* $NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $ */
/* $NetBSD: stat.c,v 1.36 2011/09/22 20:23:56 apb Exp $ */
/*
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* Copyright (c) 2002-2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if !defined(lint)
__RCSID("$NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $");
__RCSID("$NetBSD: stat.c,v 1.36 2011/09/22 20:23:56 apb Exp $");
#endif
#if ! HAVE_NBTOOL_CONFIG_H
@ -46,7 +46,7 @@ __RCSID("$NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $");
#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1
#ifdef __minix
/* Not supported in Minix. */
#define HAVE_DEVNAME 0
#define HAVE_DEVNAME 0
#else /* __minix */
#define HAVE_DEVNAME 1
#endif /* __minx */
@ -66,6 +66,7 @@ __RCSID("$NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $");
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <vis.h>
#if HAVE_STRUCT_STAT_ST_FLAGS
#define DEF_F "%#Xf "
@ -179,18 +180,18 @@ __RCSID("$NetBSD: stat.c,v 1.33 2011/01/15 22:54:10 njoly Exp $");
#define SHOW_filename 'N'
#define SHOW_sizerdev 'Z'
void usage(const char *);
void output(const struct stat *, const char *,
const char *, int, int);
int format1(const struct stat *, /* stat info */
static void usage(const char *) __dead;
static void output(const struct stat *, const char *,
const char *, int, int, int);
static int format1(const struct stat *, /* stat info */
const char *, /* the file name */
const char *, int, /* the format string itself */
char *, size_t, /* a place to put the output */
int, int, int, int, /* the parsed format */
int, int);
int, int, int);
const char *timefmt;
int linkfail;
static const char *timefmt;
static int linkfail;
#define addchar(s, c, nl) \
do { \
@ -216,10 +217,12 @@ main(int argc, char *argv[])
statfmt = NULL;
timefmt = NULL;
setprogname(argv[0]);
if (strcmp(getprogname(), "readlink") == 0) {
am_readlink = 1;
options = "fn";
synopsis = "[-fn] [file ...]";
options = "fnqsv";
synopsis = "[-fnqsv] [file ...]";
statfmt = "%Y";
fmtchar = 'f';
quiet = 1;
@ -252,6 +255,11 @@ main(int argc, char *argv[])
case 'l':
case 'r':
case 's':
if (am_readlink) {
quiet = 1;
break;
}
/*FALLTHROUGH*/
case 'x':
if (fmtchar != 0)
errx(1, "can't use format '%c' with '%c'",
@ -261,6 +269,9 @@ main(int argc, char *argv[])
case 't':
timefmt = optarg;
break;
case 'v':
quiet = 0;
break;
default:
usage(synopsis);
}
@ -334,7 +345,7 @@ main(int argc, char *argv[])
usestat ? "stat" : "lstat");
}
else
output(&st, argv[0], statfmt, fn, nonl);
output(&st, argv[0], statfmt, fn, nonl, quiet);
argv++;
argc--;
@ -344,7 +355,7 @@ main(int argc, char *argv[])
return (am_readlink ? linkfail : errs);
}
void
static void
usage(const char *synopsis)
{
@ -355,12 +366,17 @@ usage(const char *synopsis)
/*
* Parses a format string.
*/
void
static void
output(const struct stat *st, const char *file,
const char *statfmt, int fn, int nonl)
const char *statfmt, int fn, int nonl, int quiet)
{
int flags, size, prec, ofmt, hilo, what;
char buf[PATH_MAX + 4 + 1];
/*
* buf size is enough for an item of length PATH_MAX,
* multiplied by 4 for vis encoding, plus 4 for symlink
* " -> " prefix, plus 1 for \0 terminator.
*/
char buf[PATH_MAX * 4 + 4 + 1];
const char *subfmt;
int nl, t, i;
@ -431,6 +447,7 @@ output(const struct stat *st, const char *file,
* the leading " -> " if STRING is explicitly specified. The
* sizerdev datum will generate rdev output for character or
* block devices, and size output for all others.
* For STRING output, the # format requests vis encoding.
*/
flags = 0;
do {
@ -528,7 +545,7 @@ output(const struct stat *st, const char *file,
file,
subfmt, statfmt - subfmt,
buf, sizeof(buf),
flags, size, prec, ofmt, hilo, what);
flags, size, prec, ofmt, hilo, what, quiet);
for (i = 0; i < t && i < (int)(sizeof(buf) - 1); i++)
addchar(stdout, buf[i], &nl);
@ -548,24 +565,29 @@ output(const struct stat *st, const char *file,
/*
* Arranges output according to a single parsed format substring.
*/
int
static int
format1(const struct stat *st,
const char *file,
const char *fmt, int flen,
char *buf, size_t blen,
int flags, int size, int prec, int ofmt,
int hilo, int what)
int hilo, int what, int quiet)
{
u_int64_t data;
char *stmp, lfmt[24], tmp[20];
const char *sdata;
char smode[12], sid[12], path[PATH_MAX + 4];
char smode[12], sid[12], path[PATH_MAX + 4], visbuf[PATH_MAX * 4 + 4];
struct passwd *pw;
struct group *gr;
struct tm *tm;
time_t secs;
long nsecs;
int l, small, formats, gottime, shift;
int l;
int formats; /* bitmap of allowed formats for this datum */
int small; /* true if datum is a small integer */
int gottime; /* true if secs and nsecs are valid */
int shift; /* powers of 2 to scale numbers before printing */
size_t prefixlen; /* length of constant prefix for string data */
formats = 0;
small = 0;
@ -573,6 +595,7 @@ format1(const struct stat *st,
secs = 0;
nsecs = 0;
shift = 0;
prefixlen = 0;
/*
* First, pick out the data and tweak it based on hilo or
@ -802,11 +825,14 @@ format1(const struct stat *st,
} else {
snprintf(path, sizeof(path), " -> ");
if (realpath(file, path + 4) == NULL) {
if (!quiet)
warn("realpath `%s'", file);
linkfail = 1;
l = 0;
path[0] = '\0';
}
sdata = path + (ofmt == FMTF_STRING ? 0 : 4);
prefixlen = (ofmt == FMTF_STRING ? 4 : 0);
}
formats = FMTF_STRING;
@ -820,12 +846,15 @@ format1(const struct stat *st,
snprintf(path, sizeof(path), " -> ");
l = readlink(file, path + 4, sizeof(path) - 4 - 1);
if (l == -1) {
if (!quiet)
warn("readlink `%s'", file);
linkfail = 1;
l = 0;
path[0] = '\0';
}
path[l + 4] = '\0';
sdata = path + (ofmt == FMTF_STRING ? 0 : 4);
prefixlen = (ofmt == FMTF_STRING ? 4 : 0);
}
else {
linkfail = 1;
@ -938,13 +967,13 @@ format1(const struct stat *st,
fmt, flen,
majdev, sizeof(majdev),
flags, size, prec,
ofmt, HIGH_PIECE, SHOW_st_rdev);
ofmt, HIGH_PIECE, SHOW_st_rdev, quiet);
l2 = format1(st,
file,
fmt, flen,
mindev, sizeof(mindev),
flags, size, prec,
ofmt, LOW_PIECE, SHOW_st_rdev);
ofmt, LOW_PIECE, SHOW_st_rdev, quiet);
return (snprintf(buf, blen, "%.*s,%.*s",
l1, majdev, l2, mindev));
}
@ -954,7 +983,7 @@ format1(const struct stat *st,
fmt, flen,
buf, blen,
flags, size, prec,
ofmt, 0, SHOW_st_size));
ofmt, 0, SHOW_st_size, quiet));
}
/*NOTREACHED*/
default:
@ -968,6 +997,18 @@ format1(const struct stat *st,
if (hilo != 0 || (ofmt & formats) == 0)
errx(1, "%.*s: bad format", (int)flen, fmt);
/*
* FLAG_POUND with FMTF_STRING means use vis(3) encoding.
* First prefixlen chars are not encoded.
*/
if ((flags & FLAG_POUND) != 0 && ofmt == FMTF_STRING) {
flags &= !FLAG_POUND;
strncpy(visbuf, sdata, prefixlen);
strnvis(visbuf + prefixlen, sizeof(visbuf) - prefixlen,
sdata + prefixlen, VIS_WHITE | VIS_OCTAL | VIS_CSTYLE);
sdata = visbuf;
}
/*
* Assemble the format string for passing to printf(3).
*/