usr.bin/stat Update
Change-Id: I029160c73baab1b3465bc5397a36c55886db225b
This commit is contained in:
parent
f84d21b043
commit
474b24f91c
3 changed files with 131 additions and 35 deletions
|
@ -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
|
||||
|
|
|
@ -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 ,
|
||||
|
|
|
@ -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
|
||||
|
@ -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).
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue