diff options
Diffstat (limited to 'usr.bin')
48 files changed, 1168 insertions, 289 deletions
diff --git a/usr.bin/asa/asa.1 b/usr.bin/asa/asa.1 index da1af0e8ce84..68d0735774a6 100644 --- a/usr.bin/asa/asa.1 +++ b/usr.bin/asa/asa.1 @@ -84,8 +84,6 @@ To format the output of a program and redirect it to a line-printer: .Pp .Dl "a.out | asa | lpr" -.Sh SEE ALSO -.Xr f77 1 .Sh STANDARDS The .Nm diff --git a/usr.bin/bmake/Makefile b/usr.bin/bmake/Makefile index a8bcdfd9f859..bbceea3ae8c2 100644 --- a/usr.bin/bmake/Makefile +++ b/usr.bin/bmake/Makefile @@ -99,8 +99,6 @@ COPTS.filemon_ktrace.c+= -Wno-error=unused-parameter SUBDIR.${MK_TESTS}+= unit-tests .endif -MAN1= ${MAN} - .if ${MK_GEN_MAN:Uno} == "yes" # we use this to generate ${MAN} diff --git a/usr.bin/bmake/Makefile.config b/usr.bin/bmake/Makefile.config index 78babc2f1382..8ff6c81b8c78 100644 --- a/usr.bin/bmake/Makefile.config +++ b/usr.bin/bmake/Makefile.config @@ -6,7 +6,7 @@ SRCTOP?= ${.CURDIR:H:H} # things set by configure -_MAKE_VERSION?=20250618 +_MAKE_VERSION?=20250707 prefix?= /usr srcdir= ${SRCTOP}/contrib/bmake diff --git a/usr.bin/bmake/Makefile.inc b/usr.bin/bmake/Makefile.inc index 5140bd18bb37..a064563a2283 100644 --- a/usr.bin/bmake/Makefile.inc +++ b/usr.bin/bmake/Makefile.inc @@ -3,6 +3,8 @@ MK_host_egacy= no .sinclude <src.opts.mk> +PACKAGE?= bmake + .if defined(.PARSEDIR) # make sure this is available to unit-tests/Makefile .export SRCTOP diff --git a/usr.bin/bmake/unit-tests/Makefile b/usr.bin/bmake/unit-tests/Makefile index 1b9a47febe11..d4ee6f33f862 100644 --- a/usr.bin/bmake/unit-tests/Makefile +++ b/usr.bin/bmake/unit-tests/Makefile @@ -1,9 +1,9 @@ # This is a generated file, do NOT edit! # See contrib/bmake/bsd.after-import.mk # -# $Id: Makefile,v 1.239 2025/06/15 21:32:16 sjg Exp $ +# $Id: Makefile,v 1.240 2025/06/30 18:40:54 sjg Exp $ # -# $NetBSD: Makefile,v 1.367 2025/06/13 20:23:16 rillig Exp $ +# $NetBSD: Makefile,v 1.369 2025/06/29 09:40:13 rillig Exp $ # # Unit tests for make(1) # @@ -61,6 +61,7 @@ rm-tmpdir: .NOMETA # src/tests/usr.bin/make/t_make.sh as well. #TESTS+= archive #TESTS+= archive-suffix +TESTS+= char-005c-reverse-solidus TESTS+= cmd-errors TESTS+= cmd-errors-jobs TESTS+= cmd-errors-lint @@ -416,6 +417,7 @@ TESTS+= varmod-to-upper TESTS+= varmod-undefined TESTS+= varmod-unique TESTS+= varname +TESTS+= varname-circumflex TESTS+= varname-dollar TESTS+= varname-dot-alltargets TESTS+= varname-dot-curdir @@ -544,7 +546,6 @@ TESTS:= ${TESTS:${BROKEN_TESTS:S,^,N,:ts:}} # Ideas for more tests: # char-0020-space.mk -# char-005C-backslash.mk # escape-cond-str.mk # escape-cond-func-arg.mk # escape-varmod.mk diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index 0b1a37f43723..1ca63b371f65 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -259,6 +259,7 @@ 06/11 Alonso Cardenas Marquez <acm@FreeBSD.org> born in Arequipa, Peru, 1979 06/14 Josh Paetzel <jpaetzel@FreeBSD.org> born in Minneapolis, Minnesota, United States, 1973 06/15 Second quarterly status reports are due on 06/30 +06/15 Aymeric Wibo <obiwac@FreeBSD.org> born in Plaistow, London, United Kingdom, 2004 06/17 Tilman Linneweh <arved@FreeBSD.org> born in Weinheim, Baden-Wuerttemberg, Germany, 1978 06/18 Li-Wen Hsu <lwhsu@FreeBSD.org> born in Taipei, Taiwan, Republic of China, 1984 06/18 Roman Bogorodskiy <novel@FreeBSD.org> born in Saratov, Russian Federation, 1986 diff --git a/usr.bin/clang/clang-scan-deps/Makefile b/usr.bin/clang/clang-scan-deps/Makefile index 16fecdb88867..8da12faccc45 100644 --- a/usr.bin/clang/clang-scan-deps/Makefile +++ b/usr.bin/clang/clang-scan-deps/Makefile @@ -10,13 +10,14 @@ SRCS+= ClangScanDeps.cpp \ .include "${SRCTOP}/lib/clang/clang.pre.mk" CFLAGS+= -I${.OBJDIR} -TDFILE= Opts.td -INCFILE= ${TDFILE:.td=.inc} + +INCFILE= Opts.inc +TDFILE= ${LLVM_BASE}/${SRCDIR}/Opts.td GENOPT= -gen-opt-parser-defs ${INCFILE}: ${TDFILE} ${LLVM_TBLGEN} ${GENOPT} -I ${LLVM_SRCS}/include -d ${.TARGET:C/$/.d/} \ - -o ${.TARGET} ${.ALLSRC} + -o ${.TARGET} ${TDFILE} TGHDRS+= ${INCFILE} DEPENDFILES+= ${TGHDRS:C/$/.d/} diff --git a/usr.bin/clang/clang.prog.mk b/usr.bin/clang/clang.prog.mk index 36c601bcbe36..3baf3d0baf0f 100644 --- a/usr.bin/clang/clang.prog.mk +++ b/usr.bin/clang/clang.prog.mk @@ -31,7 +31,7 @@ DPADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} LDADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} .endfor -PACKAGE= clang +PACKAGE?= clang .if ${.MAKE.OS} == "FreeBSD" || !defined(BOOTSTRAPPING) LIBADD+= execinfo diff --git a/usr.bin/clang/llvm-ar/Makefile b/usr.bin/clang/llvm-ar/Makefile index fd12b1ddef57..e019c89b3581 100644 --- a/usr.bin/clang/llvm-ar/Makefile +++ b/usr.bin/clang/llvm-ar/Makefile @@ -1,5 +1,6 @@ .include <src.opts.mk> +PACKAGE= toolchain PROG_CXX= llvm-ar MAN= llvm-ar.1 llvm-ranlib.1 diff --git a/usr.bin/clang/llvm-nm/Makefile b/usr.bin/clang/llvm-nm/Makefile index 825faf74719b..7e089d1b408d 100644 --- a/usr.bin/clang/llvm-nm/Makefile +++ b/usr.bin/clang/llvm-nm/Makefile @@ -1,5 +1,6 @@ .include <src.opts.mk> +PACKAGE= toolchain PROG_CXX= llvm-nm SRCDIR= llvm/tools/llvm-nm diff --git a/usr.bin/clang/llvm-size/Makefile b/usr.bin/clang/llvm-size/Makefile index 2860a0069538..9d3505cdd319 100644 --- a/usr.bin/clang/llvm-size/Makefile +++ b/usr.bin/clang/llvm-size/Makefile @@ -1,5 +1,6 @@ .include <src.opts.mk> +PACKAGE= toolchain PROG_CXX= llvm-size SRCDIR= llvm/tools/llvm-size diff --git a/usr.bin/clang/llvm.prog.mk b/usr.bin/clang/llvm.prog.mk index f702082e31bd..c369fe8d5944 100644 --- a/usr.bin/clang/llvm.prog.mk +++ b/usr.bin/clang/llvm.prog.mk @@ -25,7 +25,7 @@ DPADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} LDADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} .endfor -PACKAGE= clang +PACKAGE?= clang .if ${.MAKE.OS} == "FreeBSD" || !defined(BOOTSTRAPPING) LIBADD+= execinfo diff --git a/usr.bin/du/du.1 b/usr.bin/du/du.1 index 37f7d7837b11..1b6d800b0285 100644 --- a/usr.bin/du/du.1 +++ b/usr.bin/du/du.1 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 29, 2024 +.Dd July 16, 2025 .Dt DU 1 .Os .Sh NAME @@ -58,7 +58,7 @@ Generate output via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .It Fl A Display the apparent size instead of the disk usage. @@ -225,7 +225,7 @@ Also display a grand total at the end: .Xr chflags 2 , .Xr fts 3 , .Xr libxo 3 , -.Xr xo_parse_args 3 , +.Xr xo_options 7 , .Xr symlink 7 , .Xr quot 8 .Sh STANDARDS diff --git a/usr.bin/find/Makefile b/usr.bin/find/Makefile index 904c08620833..48b164133bb0 100644 --- a/usr.bin/find/Makefile +++ b/usr.bin/find/Makefile @@ -3,7 +3,7 @@ PACKAGE= runtime PROG= find -SRCS= find.c function.c ls.c main.c misc.c operator.c option.c \ +SRCS= find.c function.c ls.c main.c misc.c operator.c option.c printf.c \ getdate.y YFLAGS= CFLAGS.clang+= -Werror=undef diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h index feb2e0202056..02c85d06a34c 100644 --- a/usr.bin/find/extern.h +++ b/usr.bin/find/extern.h @@ -44,6 +44,8 @@ void printlong(char *, char *, struct stat *); int queryuser(char **); OPTION *lookup_option(const char *); void finish_execplus(void); +void do_printf(PLAN *plan, FTSENT *entry, FILE *fout); + creat_f c_Xmin; creat_f c_Xtime; @@ -55,6 +57,7 @@ creat_f c_empty; creat_f c_exec; creat_f c_flags; creat_f c_follow; +creat_f c_fprint; creat_f c_fstype; creat_f c_group; creat_f c_ignore_readdir_race; @@ -68,6 +71,7 @@ creat_f c_nogroup; creat_f c_nouser; creat_f c_perm; creat_f c_print; +creat_f c_printf; creat_f c_regex; creat_f c_samefile; creat_f c_simple; @@ -90,6 +94,8 @@ exec_f f_executable; exec_f f_expr; exec_f f_false; exec_f f_flags; +exec_f f_fprint; +exec_f f_fprint0; exec_f f_fstype; exec_f f_group; exec_f f_inum; @@ -106,6 +112,7 @@ exec_f f_path; exec_f f_perm; exec_f f_print; exec_f f_print0; +exec_f f_printf; exec_f f_prune; exec_f f_quit; exec_f f_readable; diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1 index eb3fd4d0dbde..b16c4bcc95a2 100644 --- a/usr.bin/find/find.1 +++ b/usr.bin/find/find.1 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 23, 2024 +.Dd July 26, 2025 .Dt FIND 1 .Os .Sh NAME @@ -515,6 +515,28 @@ and none of the .Ar flags bits match those of .Ar notflags . +.It Ic -fprint Ar filename +This primary always evaluates to true. +This creates +.Ar filename +or truncates the file if it already exists. +The file is created at startup. +It writes the pathname of the current file to this file, followed +by a newline character. +The file will be empty if no files are matched. +.Pp +.It Ic -fprint0 Ar filename +This primary always evaluates to true. +This creates +.Ar filename +or truncates the file if it already exists. +The file is created at startup. +It writes the pathname of the current file to this file, followed +by an ASCII +.Dv NUL +character (character code 0). +The file will be empty if no files are matched. +.Pp .It Ic -fstype Ar type True if the file is contained in a file system of type .Ar type . @@ -821,6 +843,17 @@ It prints the pathname of the current file to standard output, followed by an ASCII .Dv NUL character (character code 0). +.It Ic -printf Ar fmt +This primary always evaluates to true. +It prints information about the file, interpreting +.Sq \ +and +.Sq % +escape sequences as described in the PRINTF FORMATS section. +Unlike +.Ic -print , +.Ic -printf +does not add a newline automatically. .It Ic -prune This primary always evaluates to true. It causes @@ -993,6 +1026,149 @@ All operands and primaries must be separate arguments to Primaries which themselves take arguments expect each argument to be a separate argument to .Nm . +.Sh PRINTF FORMATS +The following +.Sq \e +escapes are recognized: +.Bl -tag -width Ds -offset indent -compact +.It Cm \ea +Write a <bell> character. +.It Cm \eb +Write a <backspace> character. +.It Cm \ec +Writes no characters, but terminates the string and flushes the output so far +after each match. +.It Cm \ef +Write a <form-feed> character. +.It Cm \en +Write a <new-line> character. +.It Cm \er +Write a <carriage return> character. +.It Cm \et +Write a <tab> character. +.It Cm \ev +Write a <vertical tab> character. +.It Cm \e\' +Write a <single quote> character. +.It Cm \e\e +Write a backslash character. +.It Cm \e Ns Ar num +Write a byte whose +value is the 1-, 2-, or 3-digit +octal number +.Ar num . +Multibyte characters can be constructed using multiple +.Cm \e Ns Ar num +sequences. +.El +.Pp +Each format specification is introduced by the percent character +(``%''). +The remainder of the format specification includes, +in the following order: +.Bl -tag -width Ds +.It "Zero or more of the following flags:" +.Bl -tag -width Ds +.It Cm # +A `#' character, has no effect on almost all formats. +It is not yet implemented. +.It Cm \&\- +A minus sign `\-' which specifies +.Em left adjustment +of the output in the indicated field; +It is not yet implemented. +.It "Field Width:" +An optional digit string specifying a +.Em field width ; +if the output string has fewer bytes than the field width it will +be blank-padded on the left (or right, if the left-adjustment indicator +has been given) to make up the field width (note that a leading zero +is a flag, but an embedded zero is part of a field width); +It is not yet implemented. +.It Precision: +An optional period, +.Sq Cm \&.\& , +followed by an optional digit string giving a +.Em precision +which specifies the maximum number of bytes to be printed +from a string; if the digit string is missing, the precision is treated +as zero; +It is not yet implemented. +.It Format: +One or two characters, described below, which indicates the information to display. +.Bl -tag -width Ds +.It p +Path to file +.It f +Filename without directories. +.It h +Path relative to the starting point, or '.' if that's empty for some reason. +.It P +Unimplemented -- File with command line arg. +.It H +Unimplemented -- Command line arg. +.It g +gid in human readable form. +.It G +gid as a number. +.It h +uid in human readable form. +.It U +uid as a number. +.It m +File permission mode in octal. +.It M +File mode in +.Xr ls 1 +standard form. +.It k +File size in KiB (units of 1024 bytes). +.It b +File size in blocks (Always 512 byte units, even if underlying storage +size differs). +.It s +Size in bytes of the file. +.It S +Sparseness of the file. +The blocks the file occupies times 512 divided by the file size. +.It d +Depth in the tree +.It D +Device number for the file. +.It F +Unimplemented -- Filesystem type where the file resides. +.It l +Object of the symbolic link. +.It i +Inode of the file. +.It n +Number of hard links. +.It y +Unimplemented -- Type of the file +.It Y +Unimplemented -- Type of the file with loop detection +.It a +Access time of the file. +.It A +Access time of the file in strftime format. +Takes an additional argument. +.It B +Birth time of the file in strftime format. +Takes an additional argument. +.It c +Creation time of the file. +.It C +Creation time of the file in strftime format. +Takes an additional argument. +.It t +Modification time of the file. +.It T +Modification time of the file in strftime format. +Takes an additional argument. +.El +Any format not listed is not supported, though the error changes. +.El +.El .Sh ENVIRONMENT The .Ev LANG , LC_ALL , LC_COLLATE , LC_CTYPE , LC_MESSAGES @@ -1156,7 +1332,7 @@ and was removed in .At v3 . It was rewritten for .At v5 -and later be enhanced for the Programmer's Workbench (PWB). +and was later enhanced for the Programmer's Workbench (PWB). These changes were later incorporated in .At v7 . .Sh BUGS diff --git a/usr.bin/find/find.h b/usr.bin/find/find.h index 1664eeb9a93f..e8bb0ca8c649 100644 --- a/usr.bin/find/find.h +++ b/usr.bin/find/find.h @@ -97,6 +97,8 @@ typedef struct _plandata *creat_f(struct _option *, char ***); #define F_TIME2_B 0x00080000 /* one of -newer?B */ #endif #define F_LINK 0x00100000 /* lname or ilname */ +/* Notes about execution */ +#define F_HAS_WARNED 0x10000000 /* Has issued a warning for maybe bad input */ /* node definition */ typedef struct _plandata { @@ -133,6 +135,7 @@ typedef struct _plandata { char *_a_data[2]; /* array of char pointers */ char *_c_data; /* char pointer */ regex_t *_re_data; /* regex */ + FILE *_fprint_file; /* file stream for -fprint */ } p_un; } PLAN; #define a_data p_un._a_data @@ -160,6 +163,7 @@ typedef struct _plandata { #define e_pbsize p_un.ex._e_pbsize #define e_psizemax p_un.ex._e_psizemax #define e_next p_un.ex._e_next +#define fprint_file p_un._fprint_file typedef struct _option { const char *name; /* option name */ diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index ef610903cc00..b260a71ef4a9 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -866,6 +866,49 @@ c_follow(OPTION *option, char ***argvp __unused) return palloc(option); } +/* + * -fprint functions -- + * + * Always true, causes the current pathname to be written to + * specified file followed by a newline + */ +int +f_fprint(PLAN *plan, FTSENT *entry) +{ + fprintf(plan->fprint_file, "%s\n", entry->fts_path); + return 1; +} + +PLAN * +c_fprint(OPTION *option, char ***argvp) +{ + PLAN *new; + char *fn; + + isoutput = 1; + + new = palloc(option); + fn = nextarg(option, argvp); + new->fprint_file = fopen(fn, "w"); + if (new->fprint_file == NULL) + err(1, "fprint: cannot create %s", fn); + + return (new); +} + +/* + * -fprint0 functions -- + * + * Always true, causes the current pathname to be written to + * specified file followed by a NUL + */ +int +f_fprint0(PLAN *plan, FTSENT *entry) +{ + fprintf(plan->fprint_file, "%s%c", entry->fts_path, '\0'); + return 1; +} + #if HAVE_STRUCT_STATFS_F_FSTYPENAME /* * -fstype functions -- @@ -1389,6 +1432,37 @@ f_print0(PLAN *plan __unused, FTSENT *entry) /* c_print0 is the same as c_print */ /* + * -printf functions -- + * + * Always true. Causes information as specified in the + * argument to be written to standard output. + */ +int +f_printf(PLAN *plan, FTSENT *entry) +{ + do_printf(plan, entry, stdout); + return 1; +} + +PLAN * +c_printf(OPTION *option, char ***argvp) +{ + PLAN *new; + + /* + * XXX We could scan the format looking for stat-dependent formats, and + * turn off the nostat bit for trival cases: `%p`/`%f`/`%h`. + */ + isoutput = 1; + ftsoptions &= ~FTS_NOSTAT; + + new = palloc(option); + new->c_data = nextarg(option, argvp); + + return (new); +} + +/* * -prune functions -- * * Prune a portion of the hierarchy. diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c index 268803343a8d..fa09231a3152 100644 --- a/usr.bin/find/option.c +++ b/usr.bin/find/option.c @@ -83,8 +83,8 @@ static OPTION const options[] = { #endif // -fls { "-follow", c_follow, f_always_true, 0 }, -// -fprint -// -fprint0 + { "-fprint", c_fprint, f_fprint, 0 }, + { "-fprint0", c_fprint, f_fprint0, 0 }, // -fprintf #if HAVE_STRUCT_STATFS_F_FSTYPENAME { "-fstype", c_fstype, f_fstype, 0 }, @@ -148,7 +148,7 @@ static OPTION const options[] = { { "-perm", c_perm, f_perm, 0 }, { "-print", c_print, f_print, 0 }, { "-print0", c_print, f_print0, 0 }, -// -printf + { "-printf", c_printf, f_printf, 0 }, { "-prune", c_simple, f_prune, 0 }, { "-quit", c_simple, f_quit, 0 }, { "-readable", c_simple, f_readable, 0 }, diff --git a/usr.bin/find/printf.c b/usr.bin/find/printf.c new file mode 100644 index 000000000000..671d1d1dbb9a --- /dev/null +++ b/usr.bin/find/printf.c @@ -0,0 +1,307 @@ +/*- + * Copyright (c) 2023, Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/types.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <fts.h> +#include <grp.h> +#include <pwd.h> +#include <time.h> + +#include "find.h" + +/* translate \X to proper escape, or to itself if no special meaning */ +static const char *esc = "\a\bcde\fghijklm\nopq\rs\tu\v"; + +static inline bool +isoct(char c) +{ + return (c >= '0' && c <= '7'); +} + +static inline bool +isesc(char c) +{ + return (c >= 'a' && c <= 'v' && esc[c - 'a'] != c); +} + +static const char * +escape(const char *str, bool *flush, bool *warned) +{ + char c; + int value; + char *tmpstr; + size_t tmplen; + FILE *fp; + + fp = open_memstream(&tmpstr, &tmplen); + + /* + * Copy the str string into a new struct sbuf and return that expanding + * the different ANSI escape sequences. + */ + *flush = false; + for (c = *str++; c; c = *str++) { + if (c != '\\') { + putc(c, fp); + continue; + } + c = *str++; + + /* + * User error \ at end of string + */ + if (c == '\0') { + putc('\\', fp); + break; + } + + /* + * \c terminates output now and is supposed to flush the output + * too... + */ + if (c == 'c') { + *flush = true; + break; + } + + /* + * Is it octal? If so, decode up to 3 octal characters. + */ + if (isoct(c)) { + value = 0; + for (int i = 3; i-- > 0 && isoct(c); + c = *str++) { + value <<= 3; + value += c - '0'; + } + str--; + putc((char)value, fp); + continue; + } + + /* + * It's an ANSI X3.159-1989 escape, use the mini-escape lookup + * table to translate. + */ + if (isesc(c)) { + putc(esc[c - 'a'], fp); + continue; + } + + /* + * Otherwise, it's self inserting. gnu find specifically says + * not to rely on this behavior though. gnu find will issue + * a warning here, while printf(1) won't. + */ + if (!*warned) { + warn("Unknown character %c after \\.", c); + *warned = true; + } + putc(c, fp); + } + fclose(fp); + + return (tmpstr); +} + +static void +fp_ctime(FILE *fp, time_t t) +{ + char s[26]; + + ctime_r(&t, s); + s[24] = '\0'; /* kill newline, though gnu find info silent on issue */ + fputs(s, fp); +} + +/* + * Assumes all times are displayed in UTC rather than local time, gnu find info + * page silent on the issue. + * + * Also assumes that gnu find doesn't support multiple character escape sequences, + * which it's info page is also silent on. + */ +static void +fp_strftime(FILE *fp, time_t t, char mod) +{ + struct tm tm; + char buffer[128]; + char fmt[3] = "% "; + + /* + * Gnu libc extension we don't yet support -- seconds since epoch + * Used in Linux kernel build, so we kinda have to support it here + */ + if (mod == '@') { + fprintf(fp, "%ju", (uintmax_t)t); + return; + } + + gmtime_r(&t, &tm); + fmt[1] = mod; + printf("fmt is '%s'\n", fmt); + if (strftime(buffer, sizeof(buffer), fmt, &tm) == 0) + errx(1, "Format bad or data too long for buffer"); /* Can't really happen ??? */ + fputs(buffer, fp); +} + +void +do_printf(PLAN *plan, FTSENT *entry, FILE *fout) +{ + const char *fmt, *path, *pend, *all; + char c; + FILE *fp; + bool flush, warned; + struct stat *sb; + char *tmp; + size_t tmplen; + + fp = open_memstream(&tmp, &tmplen); + warned = (plan->flags & F_HAS_WARNED) != 0; + all = fmt = escape(plan->c_data, &flush, &warned); + if (warned) + plan->flags |= F_HAS_WARNED; + sb = entry->fts_statp; + for (c = *fmt++; c; c = *fmt++) { + if (c != '%') { + putc(c, fp); + continue; + } + c = *fmt++; + /* Style(9) deviation: case order same as gnu find info doc */ + switch (c) { + case '%': + putc(c, fp); + break; + case 'p': /* Path to file */ + fputs(entry->fts_path, fp); + break; + case 'f': /* filename w/o dirs */ + fputs(entry->fts_name, fp); + break; + case 'h': + /* + * path, relative to the starting point, of the file, or + * '.' if that's empty for some reason. + */ + path = entry->fts_path; + pend = strrchr(path, '/'); + if (pend == NULL) + putc('.', fp); + else { + char *t = malloc(pend - path + 1); + memcpy(t, path, pend - path); + t[pend - path] = '\0'; + fputs(t, fp); + free(t); + } + break; + case 'P': /* file with command line arg rm'd -- HOW? fts_parent? */ + errx(1, "%%%c is unimplemented", c); + case 'H': /* Command line arg -- HOW? */ + errx(1, "%%%c is unimplemented", c); + case 'g': /* gid human readable */ + fputs(group_from_gid(sb->st_gid, 0), fp); + break; + case 'G': /* gid numeric */ + fprintf(fp, "%d", sb->st_gid); + break; + case 'u': /* uid human readable */ + fputs(user_from_uid(sb->st_uid, 0), fp); + break; + case 'U': /* uid numeric */ + fprintf(fp, "%d", sb->st_uid); + break; + case 'm': /* mode in octal */ + fprintf(fp, "%o", sb->st_mode & 07777); + break; + case 'M': { /* Mode in ls-standard form */ + char mode[12]; + strmode(sb->st_mode, mode); + fputs(mode, fp); + break; + } + case 'k': /* kbytes used by file */ + fprintf(fp, "%jd", (intmax_t)sb->st_blocks / 2); + break; + case 'b': /* blocks used by file */ + fprintf(fp, "%jd", (intmax_t)sb->st_blocks); + break; + case 's': /* size in bytes of file */ + fprintf(fp, "%ju", (uintmax_t)sb->st_size); + break; + case 'S': /* sparseness of file */ + fprintf(fp, "%3.1f", + (float)sb->st_blocks * 512 / (float)sb->st_size); + break; + case 'd': /* Depth in tree */ + fprintf(fp, "%ld", entry->fts_level); + break; + case 'D': /* device number */ + fprintf(fp, "%ju", (uintmax_t)sb->st_dev); + break; + case 'F': /* Filesystem type */ + errx(1, "%%%c is unimplemented", c); + case 'l': /* object of symbolic link */ + fprintf(fp, "%s", entry->fts_accpath); + break; + case 'i': /* inode # */ + fprintf(fp, "%ju", (uintmax_t)sb->st_ino); + break; + case 'n': /* number of hard links */ + fprintf(fp, "%ju", (uintmax_t)sb->st_nlink); + break; + case 'y': /* -type of file, incl 'l' */ + errx(1, "%%%c is unimplemented", c); + case 'Y': /* -type of file, following 'l' types L loop ? error */ + errx(1, "%%%c is unimplemented", c); + case 'a': /* access time ctime */ + fp_ctime(fp, sb->st_atime); + break; + case 'A': /* access time with next char strftime format */ + fp_strftime(fp, sb->st_atime, *fmt++); + break; + case 'B': /* birth time with next char strftime format */ +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME + if (sb->st_birthtime != 0) + fp_strftime(fp, sb->st_birthtime, *fmt); +#endif + fmt++; + break; /* blank on systems that don't support it */ + case 'c': /* status change time ctime */ + fp_ctime(fp, sb->st_ctime); + break; + case 'C': /* status change time with next char strftime format */ + fp_strftime(fp, sb->st_ctime, *fmt++); + break; + case 't': /* modification change time ctime */ + fp_ctime(fp, sb->st_mtime); + break; + case 'T': /* modification time with next char strftime format */ + fp_strftime(fp, sb->st_mtime, *fmt++); + break; + case 'Z': /* empty string for compat SELinux context string */ + break; + /* Modifier parsing here, but also need to modify above somehow */ + case '#': case '-': case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': case '.': + errx(1, "Format modifier %c not yet supported: '%s'", c, all); + /* Any FeeeBSD-specific modifications here -- none yet */ + default: + errx(1, "Unknown format %c '%s'", c, all); + } + } + fputs(tmp, fout); + if (flush) + fflush(fout); + free(__DECONST(char *, fmt)); + free(tmp); +} diff --git a/usr.bin/fortune/datfiles/freebsd-tips b/usr.bin/fortune/datfiles/freebsd-tips index 1e9501e3a6fb..6a2b59ff5fa7 100644 --- a/usr.bin/fortune/datfiles/freebsd-tips +++ b/usr.bin/fortune/datfiles/freebsd-tips @@ -555,7 +555,7 @@ Use "sysrc name=value" to add an entry and "sysrc -x name" to delete an entry. You can upload the dmesg of your system to help developers get an overview of commonly used hardware and peripherals for FreeBSD. Use the curl package to upload it like this: curl -v -d "nickname=$USER" -d "description=FreeBSD/$(uname -m) on \ -$(kenv smbios.system.maker) $(kenv smbios.system.product)" -d "do=addd" \ +$(kenv smbios.system.maker) $(kenv smbios.system.product)" -d "do=add" \ --data-urlencode 'dmesg@/var/run/dmesg.boot' http://dmesgd.nycbug.org/index.cgi % Want to know how much memory (in bytes) your machine has installed? Let diff --git a/usr.bin/fstat/Makefile b/usr.bin/fstat/Makefile index fa51a92eb52f..f8617fd0c6a4 100644 --- a/usr.bin/fstat/Makefile +++ b/usr.bin/fstat/Makefile @@ -3,6 +3,6 @@ SRCS= fstat.c fuser.c main.c LINKS= ${BINDIR}/fstat ${BINDIR}/fuser LIBADD= procstat -MAN1= fuser.1 fstat.1 +MAN= fuser.1 fstat.1 .include <bsd.prog.mk> diff --git a/usr.bin/grep/Makefile b/usr.bin/grep/Makefile index 2204758ece5a..c72b86656148 100644 --- a/usr.bin/grep/Makefile +++ b/usr.bin/grep/Makefile @@ -6,7 +6,7 @@ PACKAGE= runtime PROG= grep -MAN1= grep.1 zgrep.1 +MAN= grep.1 zgrep.1 SRCS= file.c grep.c queue.c util.c diff --git a/usr.bin/iscsictl/iscsictl.8 b/usr.bin/iscsictl/iscsictl.8 index 74394063a007..88c79c297848 100644 --- a/usr.bin/iscsictl/iscsictl.8 +++ b/usr.bin/iscsictl/iscsictl.8 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 27, 2018 +.Dd July 16, 2025 .Dt ISCSICTL 8 .Os .Sh NAME @@ -88,7 +88,7 @@ Generate output via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .It Fl A Add session. @@ -190,7 +190,7 @@ Disconnect all iSCSI sessions: .Dl Nm Fl Ra .Sh SEE ALSO .Xr libxo 3 , -.Xr xo_parse_args 3 , +.Xr xo_options 7 , .Xr iscsi 4 , .Xr iscsi.conf 5 , .Xr iscsid 8 diff --git a/usr.bin/last/last.1 b/usr.bin/last/last.1 index f3ccc6e772af..b026ed6a7921 100644 --- a/usr.bin/last/last.1 +++ b/usr.bin/last/last.1 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd January 9, 2021 +.Dd July 16, 2025 .Dt LAST 1 .Os .Sh NAME @@ -75,7 +75,7 @@ Generate output via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .It Fl d Ar date Specify the snapshot date and time. @@ -223,7 +223,7 @@ alice ttyv0 Mon Dec 7 19:18 - 22:27 (03:09) .Xr lastcomm 1 , .Xr getutxent 3 , .Xr libxo 3 , -.Xr xo_parse_args 3 , +.Xr xo_options 7 , .Xr ac 8 , .Xr lastlogin 8 .Sh HISTORY diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh index ec20fc813bf4..18595042da5f 100755 --- a/usr.bin/man/man.sh +++ b/usr.bin/man/man.sh @@ -313,6 +313,8 @@ manpath_warnings() { # redirected to another source file. man_check_for_so() { local IFS line tstr + local counter_so=0 + local counter_so_limit=32 unset IFS if [ -n "$catpage" ]; then @@ -320,13 +322,16 @@ man_check_for_so() { fi # We need to loop to accommodate multiple .so directives. - while true + while [ $counter_so -lt $counter_so_limit ] do + counter_so=$((counter_so + 1)) + line=$($cattool "$manpage" 2>/dev/null | grep -E -m1 -v '^\.\\"[ ]*|^[ ]*$') case "$line" in '.so /'*) break ;; # ignore absolute path '.so '*) trim "${line#.so}" - decho "$manpage includes $tstr" + decho "$manpage includes $tstri level=$counter_so" + # Glob and check for the file. if ! check_man "$1/$tstr" ""; then decho " Unable to find $tstr" @@ -337,6 +342,10 @@ man_check_for_so() { esac done + if [ $counter_so -ge $counter_so_limit ]; then + decho ".so include limit of $counter_so_limit reached, stop" + fi + return 0 } diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1 index cf6a907c6aa4..1931c38a1fad 100644 --- a/usr.bin/netstat/netstat.1 +++ b/usr.bin/netstat/netstat.1 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 30, 2025 +.Dd July 16, 2025 .Dt NETSTAT 1 .Os .Sh NAME @@ -166,7 +166,7 @@ Generate output via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .It Fl 4 Show IPv4 only. @@ -954,7 +954,7 @@ Show IPv4 listening sockets: .Xr ps 1 , .Xr sockstat 1 , .Xr libxo 3 , -.Xr xo_parse_args 3 , +.Xr xo_options 7 , .Xr bpf 4 , .Xr inet 4 , .Xr route 4 , diff --git a/usr.bin/nfsstat/nfsstat.1 b/usr.bin/nfsstat/nfsstat.1 index 7d641b50f1ac..a4a00586f21b 100644 --- a/usr.bin/nfsstat/nfsstat.1 +++ b/usr.bin/nfsstat/nfsstat.1 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 28, 2023 +.Dd July 16, 2025 .Dt NFSSTAT 1 .Os .Sh NAME @@ -123,7 +123,7 @@ Generate output via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .El .Sh SEE ALSO diff --git a/usr.bin/pom/pom.6 b/usr.bin/pom/pom.6 index a3dc68b0a46b..a4dbdde2d4f5 100644 --- a/usr.bin/pom/pom.6 +++ b/usr.bin/pom/pom.6 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 14, 2010 +.Dd July 24, 2025 .Dt POM 6 .Os .Sh NAME @@ -60,4 +60,10 @@ but not has been specified, it will calculate the phase of the moon on that day at midnight. .Sh SEE ALSO -`Practical Astronomy with Your Calculator' by Duffett-Smith. +.Rs +.%A Peter Duffett-Smith +.%B Practical Astronomy with Your Calculator +.%I Cambridge University Press +.%C Cambridge, UK +.%D 1979 +.Re diff --git a/usr.bin/pom/pom.c b/usr.bin/pom/pom.c index db0033373b47..bcfbcadc8238 100644 --- a/usr.bin/pom/pom.c +++ b/usr.bin/pom/pom.c @@ -83,6 +83,7 @@ main(int argc, char **argv) err(1, "unable to limit capabitilities for stdio"); caph_cache_catpages(); + caph_cache_tzdata(); if (caph_enter() < 0) err(1, "unable to enter capability mode"); diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1 index 1e05e235e619..b810abf66da7 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 7, 2022 +.Dd July 16, 2025 .Dt PROCSTAT 1 .Os .Sh NAME @@ -136,7 +136,7 @@ flag is specified the output is generated via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .Pp The following commands are available for @@ -870,7 +870,7 @@ procstat: procstat_getprocs() .Xr libprocstat 3 , .Xr libxo 3 , .Xr signal 3 , -.Xr xo_parse_args 3 , +.Xr xo_options 7 , .Xr ddb 4 , .Xr divert 4 , .Xr icmp 4 , diff --git a/usr.bin/sdiff/Makefile b/usr.bin/sdiff/Makefile index 03587f373098..af9a037e9a58 100644 --- a/usr.bin/sdiff/Makefile +++ b/usr.bin/sdiff/Makefile @@ -3,7 +3,7 @@ PROG= sdiff SRCS= edit.c sdiff.c -MAN1= sdiff.1 +MAN= sdiff.1 HAS_TESTS= SUBDIR.${MK_TESTS}+= tests diff --git a/usr.bin/sed/sed.1 b/usr.bin/sed/sed.1 index 345f673310d8..5fd894eaf78b 100644 --- a/usr.bin/sed/sed.1 +++ b/usr.bin/sed/sed.1 @@ -1,3 +1,6 @@ +.\" +.\" SPDX-License-Identifier: BSD-3-Clause +.\" .\" Copyright (c) 1992, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -28,7 +31,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 17, 2024 +.Dd June 14, 2025 .Dt SED 1 .Os .Sh NAME @@ -597,17 +600,17 @@ with .Ql baz when piped from another command: .Bd -literal -offset indent -echo "An alternate word, like bar, is sometimes used in examples." | sed 's/bar/baz/' +echo "use bar in examples" | sed 's/bar/baz/' .Ed .Pp Using backlashes can sometimes be hard to read and follow: .Bd -literal -offset indent -echo "/home/example" | sed 's/\\/home\\/example/\\/usr\\/local\\/example/' +echo "/bin/bash" | sed 's/\\/bin\\/bash/\\/bin\\/sh/' .Ed .Pp Using a different separator can be handy when working with paths: .Bd -literal -offset indent -echo "/home/example" | sed 's#/home/example#/usr/local/example#' +echo "/bin/bash" | sed 's#/bin/bash#/bin/sh#' .Ed .Pp Replace all occurrences of diff --git a/usr.bin/sockstat/Makefile b/usr.bin/sockstat/Makefile index 188432dfc27e..7254511f21c6 100644 --- a/usr.bin/sockstat/Makefile +++ b/usr.bin/sockstat/Makefile @@ -2,7 +2,7 @@ PROG= sockstat -LIBADD= jail +LIBADD= jail xo .if ${MK_CASPER} != "no" LIBADD+= casper diff --git a/usr.bin/sockstat/sockstat.1 b/usr.bin/sockstat/sockstat.1 index da658e33e542..091911cd0879 100644 --- a/usr.bin/sockstat/sockstat.1 +++ b/usr.bin/sockstat/sockstat.1 @@ -25,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 27, 2025 +.Dd July 17, 2025 .Dt SOCKSTAT 1 .Os .Sh NAME @@ -33,7 +33,8 @@ .Nd list open sockets .Sh SYNOPSIS .Nm -.Op Fl 46ACcfIiLlnqSsUuv +.Op Fl -libxo +.Op Fl 46ACcfIiLlnqSsUuvw .Op Fl j Ar jail .Op Fl p Ar ports .Op Fl P Ar protocols @@ -46,6 +47,13 @@ domain sockets. .Pp The following options are available: .Bl -tag -width Fl +.It Fl -libxo +Generate output via +.Xr libxo 3 +in a selection of different human and machine readable formats. +See +.Xr xo_options 7 +for details on command line arguments. .It Fl 4 Show .Dv AF_INET @@ -119,6 +127,8 @@ Show sockets. .It Fl v Verbose mode. +.It Fl w +Automatically size the columns. .El .Pp If neither @@ -227,6 +237,11 @@ Show TCP IPv6 sockets which are listening and connected (default): .Bd -literal -offset indent $ sockstat -6 -P tcp .Ed +.Pp +Show all sockets in JSON format with neat alignment: +.Bd -literal -offset indent +$ sockstat --libxo json,pretty +.Ed .Sh SEE ALSO .Xr fstat 1 , .Xr netstat 1 , @@ -235,6 +250,8 @@ $ sockstat -6 -P tcp .Xr inet 4 , .Xr inet6 4 , .Xr protocols 5 +.Xr libxo 3 , +.Xr xo_options 7 .Sh HISTORY The .Nm diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c index 1a24ff67c321..7355eaa272a0 100644 --- a/usr.bin/sockstat/sockstat.c +++ b/usr.bin/sockstat/sockstat.c @@ -55,7 +55,6 @@ #include <capsicum_helpers.h> #include <ctype.h> -#include <err.h> #include <errno.h> #include <inttypes.h> #include <jail.h> @@ -67,6 +66,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <libxo/xo.h> #include <libcasper.h> #include <casper/cap_net.h> @@ -74,6 +74,7 @@ #include <casper/cap_pwd.h> #include <casper/cap_sysctl.h> +#define SOCKSTAT_XO_VERSION "1" #define sstosin(ss) ((struct sockaddr_in *)(ss)) #define sstosin6(ss) ((struct sockaddr_in6 *)(ss)) #define sstosun(ss) ((struct sockaddr_un *)(ss)) @@ -97,6 +98,7 @@ static bool opt_s; /* Show protocol state if applicable */ static bool opt_U; /* Show remote UDP encapsulation port number */ static bool opt_u; /* Show Unix domain sockets */ static u_int opt_v; /* Verbose mode */ +static bool opt_w; /* Automatically size the columns */ /* * Default protocols to use if no -P was defined. @@ -196,7 +198,7 @@ static bool _check_ksize(size_t received_size, size_t expected_size, const char *struct_name) { if (received_size != expected_size) { - warnx("%s size mismatch: expected %zd, received %zd", + xo_warnx("%s size mismatch: expected %zd, received %zd", struct_name, expected_size, received_size); return false; } @@ -208,7 +210,7 @@ static void _enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name) { if (received_size != expected_size) { - errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd", + xo_errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd", struct_name, expected_size, received_size); } } @@ -226,7 +228,7 @@ get_proto_type(const char *proto) else pent = getprotobyname(proto); if (pent == NULL) { - warn("cap_getprotobyname"); + xo_warn("cap_getprotobyname"); return (-1); } return (pent->p_proto); @@ -247,7 +249,7 @@ init_protos(int num) } if ((protos = malloc(sizeof(int) * proto_count)) == NULL) - err(1, "malloc"); + xo_err(1, "malloc"); numprotos = proto_count; } @@ -281,17 +283,17 @@ parse_ports(const char *portspec) if (ports == NULL) if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL) - err(1, "calloc()"); + xo_err(1, "calloc()"); p = portspec; while (*p != '\0') { if (!isdigit(*p)) - errx(1, "syntax error in port range"); + xo_errx(1, "syntax error in port range"); for (q = p; *q != '\0' && isdigit(*q); ++q) /* nothing */ ; for (port = 0; p < q; ++p) port = port * 10 + digittoint(*p); if (port < 0 || port > 65535) - errx(1, "invalid port number"); + xo_errx(1, "invalid port number"); SET_PORT(port); switch (*p) { case '-': @@ -309,7 +311,7 @@ parse_ports(const char *portspec) for (end = 0; p < q; ++p) end = end * 10 + digittoint(*p); if (end < port || end > 65535) - errx(1, "invalid port number"); + xo_errx(1, "invalid port number"); while (port++ < end) SET_PORT(port); if (*p == ',') @@ -394,15 +396,15 @@ gather_sctp(void) varname = "net.inet.sctp.assoclist"; if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) { if (errno != ENOENT) - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); return; } if ((buf = (char *)malloc(len)) == NULL) { - err(1, "malloc()"); + xo_err(1, "malloc()"); return; } if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) { - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); free(buf); return; } @@ -410,7 +412,7 @@ gather_sctp(void) offset = sizeof(struct xsctp_inpcb); while ((offset < len) && (xinpcb->last == 0)) { if ((sock = calloc(1, sizeof *sock)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->socket = xinpcb->socket; sock->proto = IPPROTO_SCTP; sock->protoname = "sctp"; @@ -438,7 +440,7 @@ gather_sctp(void) if (xladdr->last == 1) break; if ((laddr = calloc(1, sizeof(struct addr))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); switch (xladdr->address.sa.sa_family) { case AF_INET: #define __IN_IS_ADDR_LOOPBACK(pina) \ @@ -460,7 +462,7 @@ gather_sctp(void) htons(xinpcb->local_port)); break; default: - errx(1, "address family %d not supported", + xo_errx(1, "address family %d not supported", xladdr->address.sa.sa_family); } laddr->next = NULL; @@ -473,7 +475,7 @@ gather_sctp(void) if (sock->laddr == NULL) { if ((sock->laddr = calloc(1, sizeof(struct addr))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->laddr->address.ss_family = sock->family; if (sock->family == AF_INET) sock->laddr->address.ss_len = @@ -484,7 +486,7 @@ gather_sctp(void) local_all_loopback = 0; } if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->faddr->address.ss_family = sock->family; if (sock->family == AF_INET) sock->faddr->address.ss_len = @@ -511,7 +513,7 @@ gather_sctp(void) no_stcb = 0; if (opt_c) { if ((sock = calloc(1, sizeof *sock)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->socket = xinpcb->socket; sock->proto = IPPROTO_SCTP; sock->protoname = "sctp"; @@ -541,7 +543,7 @@ gather_sctp(void) continue; laddr = calloc(1, sizeof(struct addr)); if (laddr == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); switch (xladdr->address.sa.sa_family) { case AF_INET: #define __IN_IS_ADDR_LOOPBACK(pina) \ @@ -563,7 +565,7 @@ gather_sctp(void) htons(xstcb->local_port)); break; default: - errx(1, + xo_errx(1, "address family %d not supported", xladdr->address.sa.sa_family); } @@ -586,7 +588,7 @@ gather_sctp(void) continue; faddr = calloc(1, sizeof(struct addr)); if (faddr == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); switch (xraddr->address.sa.sa_family) { case AF_INET: #define __IN_IS_ADDR_LOOPBACK(pina) \ @@ -608,7 +610,7 @@ gather_sctp(void) htons(xstcb->remote_port)); break; default: - errx(1, + xo_errx(1, "address family %d not supported", xraddr->address.sa.sa_family); } @@ -672,7 +674,7 @@ gather_inet(int proto) protoname = "div"; break; default: - errx(1, "protocol %d not supported", proto); + xo_errx(1, "protocol %d not supported", proto); } buf = NULL; @@ -681,7 +683,7 @@ gather_inet(int proto) do { for (;;) { if ((buf = realloc(buf, bufsize)) == NULL) - err(1, "realloc()"); + xo_err(1, "realloc()"); len = bufsize; if (cap_sysctlbyname(capsysctl, varname, buf, &len, NULL, 0) == 0) @@ -689,7 +691,7 @@ gather_inet(int proto) if (errno == ENOENT) goto out; if (errno != ENOMEM || len != bufsize) - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); bufsize *= 2; } xig = (struct xinpgen *)buf; @@ -700,7 +702,7 @@ gather_inet(int proto) } while (xig->xig_gen != exig->xig_gen && retry--); if (xig->xig_gen != exig->xig_gen && opt_v) - warnx("warning: data may be inconsistent"); + xo_warnx("warning: data may be inconsistent"); for (;;) { xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); @@ -721,7 +723,7 @@ gather_inet(int proto) goto out; break; default: - errx(1, "protocol %d not supported", proto); + xo_errx(1, "protocol %d not supported", proto); } so = &xip->xi_socket; if ((xip->inp_vflag & vflag) == 0) @@ -747,15 +749,15 @@ gather_inet(int proto) continue; } else { if (opt_v) - warnx("invalid vflag 0x%x", xip->inp_vflag); + xo_warnx("invalid vflag 0x%x", xip->inp_vflag); continue; } if ((sock = calloc(1, sizeof(*sock))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); if ((laddr = calloc(1, sizeof *laddr)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); if ((faddr = calloc(1, sizeof *faddr)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->socket = so->xso_so; sock->pcb = so->so_pcb; sock->splice_socket = so->so_splice_so; @@ -821,7 +823,9 @@ gather_unix(int proto) break; case SOCK_SEQPACKET: varname = "net.local.seqpacket.pcblist"; - protoname = "seqpac"; + protoname = (xo_get_style(NULL) == XO_STYLE_TEXT) + ? "seqpac" + : "seqpacket"; break; default: abort(); @@ -832,13 +836,13 @@ gather_unix(int proto) do { for (;;) { if ((buf = realloc(buf, bufsize)) == NULL) - err(1, "realloc()"); + xo_err(1, "realloc()"); len = bufsize; if (cap_sysctlbyname(capsysctl, varname, buf, &len, NULL, 0) == 0) break; if (errno != ENOMEM || len != bufsize) - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); bufsize *= 2; } xug = (struct xunpgen *)buf; @@ -850,7 +854,7 @@ gather_unix(int proto) } while (xug->xug_gen != exug->xug_gen && retry--); if (xug->xug_gen != exug->xug_gen && opt_v) - warnx("warning: data may be inconsistent"); + xo_warnx("warning: data may be inconsistent"); for (;;) { xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len); @@ -863,11 +867,11 @@ gather_unix(int proto) (xup->unp_conn != 0 && !opt_c)) continue; if ((sock = calloc(1, sizeof(*sock))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); if ((laddr = calloc(1, sizeof *laddr)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); if ((faddr = calloc(1, sizeof *faddr)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->socket = xup->xu_socket.xso_so; sock->pcb = xup->xu_unpp; sock->proto = proto; @@ -898,21 +902,21 @@ getfiles(void) olen = len = sizeof(*xfiles); if ((xfiles = malloc(len)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0) == -1) { if (errno != ENOMEM || len != olen) - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); olen = len *= 2; if ((xfiles = realloc(xfiles, len)) == NULL) - err(1, "realloc()"); + xo_err(1, "realloc()"); } if (len > 0) enforce_ksize(xfiles->xf_size, struct xfile); nfiles = len / sizeof(*xfiles); if ((files = malloc(nfiles * sizeof(struct file))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); for (int i = 0; i < nfiles; i++) { files[i].xf_data = xfiles[i].xf_data; @@ -931,6 +935,7 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize) struct sockaddr_un *sun; char addrstr[NI_MAXHOST] = { '\0', '\0' }; int error, off, port = 0; + const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT); switch (ss->ss_family) { case AF_INET: @@ -946,6 +951,11 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize) case AF_UNIX: sun = sstosun(ss); off = (int)((char *)&sun->sun_path - (char *)sun); + if (!is_text_style) { + xo_emit("{:path/%.*s}", sun->sun_len - off, + sun->sun_path); + return 0; + } return snprintf(buf, bufsize, "%.*s", sun->sun_len - off, sun->sun_path); } @@ -953,7 +963,12 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize) error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len, addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST); if (error) - errx(1, "cap_getnameinfo()"); + xo_errx(1, "cap_getnameinfo()"); + } + if (!is_text_style) { + xo_emit("{:address/%s}", addrstr); + xo_emit("{:port/%d}", port); + return 0; } if (port == 0) return snprintf(buf, bufsize, "%s:*", addrstr); @@ -976,7 +991,7 @@ getprocname(pid_t pid) == -1) { /* Do not warn if the process exits before we get its name. */ if (errno != ESRCH) - warn("cap_sysctl()"); + xo_warn("cap_sysctl()"); return ("??"); } return (proc.ki_comm); @@ -998,7 +1013,7 @@ getprocjid(pid_t pid) == -1) { /* Do not warn if the process exits before we get its jid. */ if (errno != ESRCH) - warn("cap_sysctl()"); + xo_warn("cap_sysctl()"); return (-1); } return (proc.ki_jid); @@ -1098,13 +1113,15 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) { #define SAFESIZE (buf == NULL ? 0 : bufsize - pos) size_t pos = 0; - /* Remote peer we connect(2) to, if any. */ + const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT); if (faddr->conn != 0) { + /* Remote peer we connect(2) to, if any. */ struct sock *p; - pos += strlcpy(buf, "-> ", bufsize); + if (is_text_style) + pos += strlcpy(SAFEBUF, "-> ", SAFESIZE); p = RB_FIND(pcbs_t, &pcbs, &(struct sock){ .pcb = faddr->conn }); - if (__predict_false(p == NULL)) { + if (__predict_false(p == NULL) && is_text_style) { /* XXGL: can this happen at all? */ pos += snprintf(SAFEBUF, SAFESIZE, "??"); } else if (p->laddr->address.ss_len == 0) { @@ -1113,35 +1130,52 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) { &(struct file){ .xf_data = p->socket }); if (f != NULL) { - pos += snprintf(SAFEBUF, SAFESIZE, "[%lu %d]", - (u_long)f->xf_pid, f->xf_fd); + if (is_text_style) { + pos += snprintf(SAFEBUF, SAFESIZE, + "[%lu %d]", (u_long)f->xf_pid, + f->xf_fd); + } else { + xo_open_list("connections"); + xo_open_instance("connections"); + xo_emit("{:pid/%lu}", (u_long)f->xf_pid); + xo_emit("{:fd/%d}", f->xf_fd); + xo_close_instance("connections"); + xo_close_list("connections"); + } } } else pos += formataddr(&p->laddr->address, SAFEBUF, SAFESIZE); - } - /* Remote peer(s) connect(2)ed to us, if any. */ - if (faddr->firstref != 0) { + } else if (faddr->firstref != 0) { + /* Remote peer(s) connect(2)ed to us, if any. */ struct sock *p; struct file *f; kvaddr_t ref = faddr->firstref; bool fref = true; - pos += snprintf(SAFEBUF, SAFESIZE, " <- "); - + if (is_text_style) + pos += snprintf(SAFEBUF, SAFESIZE, " <- "); + xo_open_list("connections"); while ((p = RB_FIND(pcbs_t, &pcbs, &(struct sock){ .pcb = ref })) != 0) { f = RB_FIND(files_t, &ftree, - &(struct file){ .xf_data = - p->socket }); + &(struct file){ .xf_data = p->socket }); if (f != NULL) { - pos += snprintf(SAFEBUF, SAFESIZE, - "%s[%lu %d]", fref ? "" : ",", - (u_long)f->xf_pid, f->xf_fd); + if (is_text_style) { + pos += snprintf(SAFEBUF, SAFESIZE, + "%s[%lu %d]", fref ? "" : ",", + (u_long)f->xf_pid, f->xf_fd); + } else { + xo_open_instance("connections"); + xo_emit("{:pid/%lu}", (u_long)f->xf_pid); + xo_emit("{:fd/%d}", f->xf_fd); + xo_close_instance("connections"); + } } ref = p->faddr->nextref; fref = false; } + xo_close_list("connections"); } return pos; } @@ -1178,22 +1212,19 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s) len = strlen(s->protoname); if (s->vflag & (INP_IPV4 | INP_IPV6)) len += 1; - if (laddr != NULL && faddr != NULL && s->family == AF_UNIX && - laddr->address.ss_len == 0 && faddr->conn == 0) - len += strlen(" (not connected)"); cw->proto = MAX(cw->proto, len); while (laddr != NULL || faddr != NULL) { - if (s->family == AF_UNIX) { + if (opt_w && s->family == AF_UNIX) { if ((laddr == NULL) || (faddr == NULL)) - errx(1, "laddr = %p or faddr = %p is NULL", + xo_errx(1, "laddr = %p or faddr = %p is NULL", (void *)laddr, (void *)faddr); if (laddr->address.ss_len > 0) len = formataddr(&laddr->address, NULL, 0); cw->local_addr = MAX(cw->local_addr, len); len = format_unix_faddr(faddr, NULL, 0); cw->foreign_addr = MAX(cw->foreign_addr, len); - } else { + } else if (opt_w) { if (laddr != NULL) { len = formataddr(&laddr->address, NULL, 0); cw->local_addr = MAX(cw->local_addr, len); @@ -1296,28 +1327,12 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s) static void calculate_column_widths(struct col_widths *cw) { - cw->user = 4; - cw->command = 10; - cw->pid = 3; - cw->fd = 2; - cw->proto = 5; - cw->local_addr = 13; - cw->foreign_addr = 15; - cw->pcb_kva = 18; - cw->fib = 3; - cw->splice_address = 14; - cw->inp_gencnt = 2; - cw->encaps = 6; - cw->path_state = 10; - cw->conn_state = 10; - cw->stack = 5; - cw->cc = 2; - int n, len; struct file *xf; struct sock *s; struct passwd *pwd; + cap_setpassent(cappwd, 1); for (xf = files, n = 0; n < nfiles; ++n, ++xf) { if (xf->xf_data == 0) continue; @@ -1365,62 +1380,104 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize) laddr = s->laddr; faddr = s->faddr; first = true; + const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT); - snprintf(buf, bufsize, "%s%s%s%s", + snprintf(buf, bufsize, "%s%s%s", s->protoname, s->vflag & INP_IPV4 ? "4" : "", - s->vflag & INP_IPV6 ? "6" : "", - (laddr != NULL && faddr != NULL && - s->family == AF_UNIX && laddr->address.ss_len == 0 && - faddr->conn == 0) ? " (not connected)" : ""); - printf(" %-*s", cw->proto, buf); + s->vflag & INP_IPV6 ? "6" : ""); + xo_emit(" {:proto/%-*s}", cw->proto, buf); while (laddr != NULL || faddr != NULL) { if (s->family == AF_UNIX) { if ((laddr == NULL) || (faddr == NULL)) - errx(1, "laddr = %p or faddr = %p is NULL", + xo_errx(1, "laddr = %p or faddr = %p is NULL", (void *)laddr, (void *)faddr); - if (laddr->address.ss_len > 0) + if (laddr->address.ss_len > 0) { + xo_open_container("local"); formataddr(&laddr->address, buf, bufsize); - else - strlcpy(buf, "??", bufsize); - printf(" %-*s", cw->local_addr, buf); - if (format_unix_faddr(faddr, buf, bufsize) == 0) - strlcpy(buf, "??", bufsize); - printf(" %-*s", cw->foreign_addr, buf); + if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, buf); + } + xo_close_container("local"); + } else if (laddr->address.ss_len == 0 && + faddr->conn == 0 && is_text_style) { + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, "(not connected)"); + } else if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, "??"); + } + if (faddr->conn != 0 || faddr->firstref != 0) { + xo_open_container("foreign"); + int len = format_unix_faddr(faddr, buf, + bufsize); + if (len == 0 && is_text_style) + xo_emit(" {:/%-*s}", + cw->foreign_addr, "??"); + else if (is_text_style) + xo_emit(" {:/%-*.*s}", cw->foreign_addr, + cw->foreign_addr, buf); + xo_close_container("foreign"); + } else if (is_text_style) + xo_emit(" {:/%-*s}", cw->foreign_addr, "??"); } else { - if (laddr != NULL) + if (laddr != NULL) { + xo_open_container("local"); formataddr(&laddr->address, buf, bufsize); - else - strlcpy(buf, "??", bufsize); - printf(" %-*s", cw->local_addr, buf); - if (faddr != NULL) + if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, buf); + } + xo_close_container("local"); + } else if (is_text_style) + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, "??"); + if (faddr != NULL) { + xo_open_container("foreign"); formataddr(&faddr->address, buf, bufsize); - else - strlcpy(buf, "??", bufsize); - printf(" %-*s", cw->foreign_addr, buf); + if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->foreign_addr, + cw->foreign_addr, buf); + } + xo_close_container("foreign"); + } else if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->foreign_addr, + cw->foreign_addr, "??"); + } + } + if (opt_A) { + snprintf(buf, bufsize, "%#*" PRIx64, + cw->pcb_kva, s->pcb); + xo_emit(" {:pcb-kva/%s}", buf); } - if (opt_A) - printf(" %#*" PRIx64, cw->pcb_kva, s->pcb); if (opt_f) - printf(" %*d", cw->fib, s->fibnum); + xo_emit(" {:fib/%*d}", cw->fib, s->fibnum); if (opt_I) { if (s->splice_socket != 0) { struct sock *sp; sp = RB_FIND(socks_t, &socks, &(struct sock) { .socket = s->splice_socket }); - if (sp != NULL) + if (sp != NULL) { + xo_open_container("splice"); formataddr(&sp->laddr->address, buf, bufsize); - } else + xo_close_container("splice"); + } else if (is_text_style) + strlcpy(buf, "??", bufsize); + } else if (is_text_style) strlcpy(buf, "??", bufsize); - printf(" %-*s", cw->splice_address, buf); + if (is_text_style) + xo_emit(" {:/%-*s}", cw->splice_address, buf); } if (opt_i) { if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP) - printf(" %*" PRIu64, cw->inp_gencnt, + { + snprintf(buf, bufsize, "%" PRIu64, s->inp_gencnt); - else - printf(" %*s", cw->inp_gencnt, "??"); + xo_emit(" {:id/%*s}", cw->inp_gencnt, buf); + } else if (is_text_style) + xo_emit(" {:/%*s}", cw->inp_gencnt, "??"); } if (opt_U) { if (faddr != NULL && @@ -1431,10 +1488,10 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize) (s->proto == IPPROTO_TCP && s->state != TCPS_CLOSED && s->state != TCPS_LISTEN))) { - printf(" %*u", cw->encaps, + xo_emit(" {:encaps/%*u}", cw->encaps, ntohs(faddr->encaps_port)); - } else - printf(" %*s", cw->encaps, "??"); + } else if (is_text_style) + xo_emit(" {:/%*s}", cw->encaps, "??"); } if (opt_s) { if (faddr != NULL && @@ -1442,10 +1499,10 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize) s->state != SCTP_CLOSED && s->state != SCTP_BOUND && s->state != SCTP_LISTEN) { - printf(" %-*s", cw->path_state, + xo_emit(" {:path-state/%-*s}", cw->path_state, sctp_path_state(faddr->state)); - } else - printf(" %-*s", cw->path_state, "??"); + } else if (is_text_style) + xo_emit(" {:/%-*s}", cw->path_state, "??"); } if (first) { if (opt_s) { @@ -1453,47 +1510,52 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize) s->proto == IPPROTO_TCP) { switch (s->proto) { case IPPROTO_SCTP: - printf(" %-*s", cw->conn_state, - sctp_conn_state(s->state)); + xo_emit(" {:path-state/%-*s}", + cw->path_state, + sctp_path_state( + faddr->state)); break; case IPPROTO_TCP: if (s->state >= 0 && s->state < TCP_NSTATES) - printf(" %-*s", - cw->conn_state, - tcpstates[s->state]); - else - printf(" %-*s", - cw->conn_state, "??"); + xo_emit(" {:conn-state/%-*s}", + cw->conn_state, + tcpstates[s->state]); + else if (is_text_style) + xo_emit(" {:/%-*s}", + cw->conn_state, "??"); break; } - } else - printf(" %-*s", cw->conn_state, "??"); + } else if (is_text_style) + xo_emit(" {:/%-*s}", + cw->conn_state, "??"); } if (opt_S) { if (s->proto == IPPROTO_TCP) - printf(" %-*s", cw->stack, s->stack); - else - printf(" %-*s", cw->stack, "??"); + xo_emit(" {:stack/%-*s}", + cw->stack, s->stack); + else if (is_text_style) + xo_emit(" {:/%-*s}", + cw->stack, "??"); } if (opt_C) { if (s->proto == IPPROTO_TCP) - printf(" %-*s", cw->cc, s->cc); - else - printf(" %-*s", cw->cc, "??"); + xo_emit(" {:cc/%-*s}", cw->cc, s->cc); + else if (is_text_style) + xo_emit(" {:/%-*s}", cw->cc, "??"); } } if (laddr != NULL) laddr = laddr->next; if (faddr != NULL) faddr = faddr->next; - if (laddr != NULL || faddr != NULL) - printf("%-*s %-*s %-*s %-*s %-*s", cw->user, "", - cw->command, "", cw->pid, "", cw->fd, "", - cw->proto, ""); + if (is_text_style && (laddr != NULL || faddr != NULL)) + xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}", + cw->user, "??", cw->command, "??", + cw->pid, "??", cw->fd, "??"); first = false; } - printf("\n"); + xo_emit("\n"); } static void @@ -1507,37 +1569,63 @@ display(void) const size_t bufsize = 512; void *buf; if ((buf = (char *)malloc(bufsize)) == NULL) { - err(1, "malloc()"); + xo_err(1, "malloc()"); return; } - calculate_column_widths(&cw); + if (xo_get_style(NULL) == XO_STYLE_TEXT) { + cw = (struct col_widths) { + .user = strlen("USER"), + .command = 10, + .pid = strlen("PID"), + .fd = strlen("FD"), + .proto = strlen("PROTO"), + .local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21, + .foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21, + .pcb_kva = 18, + .fib = strlen("FIB"), + .splice_address = strlen("SPLICE ADDRESS"), + .inp_gencnt = strlen("ID"), + .encaps = strlen("ENCAPS"), + .path_state = strlen("PATH STATE"), + .conn_state = strlen("CONN STATE"), + .stack = strlen("STACK"), + .cc = strlen("CC"), + }; + calculate_column_widths(&cw); + } else + memset(&cw, 0, sizeof(cw)); + + xo_set_version(SOCKSTAT_XO_VERSION); + xo_open_container("sockstat"); + xo_open_list("socket"); if (!opt_q) { - printf("%-*s %-*s %*s %*s %-*s %-*s %-*s", - cw.user, "USER", cw.command, "COMMAND", - cw.pid, "PID", cw.fd, "FD", cw.proto, "PROTO", - cw.local_addr, "LOCAL ADDRESS", - cw.foreign_addr,"FOREIGN ADDRESS"); + xo_emit("{T:/%-*s} {T:/%-*s} {T:/%*s} {T:/%*s} {T:/%-*s} " + "{T:/%-*s} {T:/%-*s}", cw.user, "USER", cw.command, + "COMMAND", cw.pid, "PID", cw.fd, "FD", cw.proto, + "PROTO", cw.local_addr, "LOCAL ADDRESS", + cw.foreign_addr, "FOREIGN ADDRESS"); if (opt_A) - printf(" %-*s", cw.pcb_kva, "PCB KVA"); + xo_emit(" {T:/%-*s}", cw.pcb_kva, "PCB KVA"); if (opt_f) /* RT_MAXFIBS is 65535. */ - printf(" %*s", cw.fib, "FIB"); + xo_emit(" {T:/%*s}", cw.fib, "FIB"); if (opt_I) - printf(" %-*s", cw.splice_address, "SPLICE ADDRESS"); + xo_emit(" {T:/%-*s}", cw.splice_address, + "SPLICE ADDRESS"); if (opt_i) - printf(" %*s", cw.inp_gencnt, "ID"); + xo_emit(" {T:/%*s}", cw.inp_gencnt, "ID"); if (opt_U) - printf(" %*s", cw.encaps, "ENCAPS"); + xo_emit(" {T:/%*s}", cw.encaps, "ENCAPS"); if (opt_s) { - printf(" %-*s", cw.path_state, "PATH STATE"); - printf(" %-*s", cw.conn_state, "CONN STATE"); + xo_emit(" {T:/%-*s}", cw.path_state, "PATH STATE"); + xo_emit(" {T:/%-*s}", cw.conn_state, "CONN STATE"); } if (opt_S) - printf(" %-*s", cw.stack, "STACK"); + xo_emit(" {T:/%-*s}", cw.stack, "STACK"); if (opt_C) - printf(" %-*s", cw.cc, "CC"); - printf("\n"); + xo_emit(" {T:/%-*s}", cw.cc, "CC"); + xo_emit("\n"); } cap_setpassent(cappwd, 1); for (xf = files, n = 0; n < nfiles; ++n, ++xf) { @@ -1548,17 +1636,24 @@ display(void) s = RB_FIND(socks_t, &socks, &(struct sock){ .socket = xf->xf_data}); if (s != NULL && check_ports(s)) { + xo_open_instance("socket"); s->shown = 1; if (opt_n || (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL) - printf("%-*lu", cw.user, (u_long)xf->xf_uid); + xo_emit("{:user/%-*lu}", cw.user, + (u_long)xf->xf_uid); + else + xo_emit("{:user/%-*s}", cw.user, pwd->pw_name); + if (xo_get_style(NULL) == XO_STYLE_TEXT) + xo_emit(" {:/%-*.10s}", cw.command, + getprocname(xf->xf_pid)); else - printf("%-*s", cw.user, pwd->pw_name); - printf(" %-*.*s", cw.command, cw.command, - getprocname(xf->xf_pid)); - printf(" %*lu", cw.pid, (u_long)xf->xf_pid); - printf(" %*d", cw.fd, xf->xf_fd); + xo_emit(" {:command/%-*s}", cw.command, + getprocname(xf->xf_pid)); + xo_emit(" {:pid/%*lu}", cw.pid, (u_long)xf->xf_pid); + xo_emit(" {:fd/%*d}", cw.fd, xf->xf_fd); display_sock(s, &cw, buf, bufsize); + xo_close_instance("socket"); } } if (opt_j >= 0) @@ -1566,20 +1661,33 @@ display(void) SLIST_FOREACH(s, &nosocks, socket_list) { if (!check_ports(s)) continue; - printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??", - cw.pid, "??", cw.fd, "??"); + xo_open_instance("socket"); + if (xo_get_style(NULL) == XO_STYLE_TEXT) + xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}", + cw.user, "??", cw.command, "??", + cw.pid, "??", cw.fd, "??"); display_sock(s, &cw, buf, bufsize); + xo_close_instance("socket"); } RB_FOREACH(s, socks_t, &socks) { if (s->shown) continue; if (!check_ports(s)) continue; - printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??", - cw.pid, "??", cw.fd, "??"); + xo_open_instance("socket"); + if (xo_get_style(NULL) == XO_STYLE_TEXT) + xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}", + cw.user, "??", cw.command, "??", + cw.pid, "??", cw.fd, "??"); display_sock(s, &cw, buf, bufsize); + xo_close_instance("socket"); } + xo_close_list("socket"); + xo_close_container("sockstat"); + if (xo_finish() < 0) + xo_err(1, "stdout"); free(buf); + cap_endpwent(cappwd); } static int @@ -1595,7 +1703,7 @@ set_default_protos(void) pname = default_protos[pindex]; prot = cap_getprotobyname(capnetdb, pname); if (prot == NULL) - err(1, "cap_getprotobyname: %s", pname); + xo_err(1, "cap_getprotobyname: %s", pname); protos[pindex] = prot->p_proto; } numprotos = pindex; @@ -1641,8 +1749,10 @@ jail_getvnet(int jid) static void usage(void) { - errx(1, - "usage: sockstat [-46ACcfIiLlnqSsUuv] [-j jid] [-p ports] [-P protocols]"); + xo_error( +"usage: sockstat [--libxo] [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports]\n" +" [-P protocols]\n"); + exit(1); } int @@ -1655,6 +1765,9 @@ main(int argc, char *argv[]) int protos_defined = -1; int o, i; + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(1); opt_j = -1; while ((o = getopt(argc, argv, "46ACcfIij:Llnp:P:qSsUuvw")) != -1) switch (o) { @@ -1685,7 +1798,7 @@ main(int argc, char *argv[]) case 'j': opt_j = jail_getid(optarg); if (opt_j < 0) - errx(1, "jail_getid: %s", jail_errmsg); + xo_errx(1, "jail_getid: %s", jail_errmsg); break; case 'L': opt_L = true; @@ -1721,7 +1834,7 @@ main(int argc, char *argv[]) ++opt_v; break; case 'w': - /* left for backward compatibility. */ + opt_w = true; break; default: usage(); @@ -1736,10 +1849,10 @@ main(int argc, char *argv[]) if (opt_j > 0) { switch (jail_getvnet(opt_j)) { case -1: - errx(2, "jail_getvnet: %s", jail_errmsg); + xo_errx(2, "jail_getvnet: %s", jail_errmsg); case JAIL_SYS_NEW: if (jail_attach(opt_j) < 0) - err(3, "jail_attach()"); + xo_err(3, "jail_attach()"); /* Set back to -1 for normal output in vnet jail. */ opt_j = -1; break; @@ -1750,31 +1863,31 @@ main(int argc, char *argv[]) capcas = cap_init(); if (capcas == NULL) - err(1, "Unable to contact Casper"); + xo_err(1, "Unable to contact Casper"); if (caph_enter_casper() < 0) - err(1, "Unable to enter capability mode"); + xo_err(1, "Unable to enter capability mode"); capnet = cap_service_open(capcas, "system.net"); if (capnet == NULL) - err(1, "Unable to open system.net service"); + xo_err(1, "Unable to open system.net service"); capnetdb = cap_service_open(capcas, "system.netdb"); if (capnetdb == NULL) - err(1, "Unable to open system.netdb service"); + xo_err(1, "Unable to open system.netdb service"); capsysctl = cap_service_open(capcas, "system.sysctl"); if (capsysctl == NULL) - err(1, "Unable to open system.sysctl service"); + xo_err(1, "Unable to open system.sysctl service"); cappwd = cap_service_open(capcas, "system.pwd"); if (cappwd == NULL) - err(1, "Unable to open system.pwd service"); + xo_err(1, "Unable to open system.pwd service"); cap_close(capcas); limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME); if (limit == NULL) - err(1, "Unable to init cap_net limits"); + xo_err(1, "Unable to init cap_net limits"); if (cap_net_limit(limit) < 0) - err(1, "Unable to apply limits"); + xo_err(1, "Unable to apply limits"); if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0) - err(1, "Unable to apply pwd commands limits"); + xo_err(1, "Unable to apply pwd commands limits"); if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0) - err(1, "Unable to apply pwd commands limits"); + xo_err(1, "Unable to apply pwd commands limits"); if ((!opt_4 && !opt_6) && protos_defined != -1) opt_4 = opt_6 = true; diff --git a/usr.bin/strings/Makefile b/usr.bin/strings/Makefile index 8e2572810947..c01e775b0b89 100644 --- a/usr.bin/strings/Makefile +++ b/usr.bin/strings/Makefile @@ -1,5 +1,7 @@ .include <src.opts.mk> +PACKAGE= toolchain + ELFTCDIR= ${SRCTOP}/contrib/elftoolchain .PATH: ${ELFTCDIR}/strings diff --git a/usr.bin/top/top.1 b/usr.bin/top/top.1 index d8ef763e7a34..9b1860246de9 100644 --- a/usr.bin/top/top.1 +++ b/usr.bin/top/top.1 @@ -1,4 +1,4 @@ -.Dd April 1, 2025 +.Dd June 9, 2025 .Dt TOP 1 .Os .Sh NAME @@ -189,7 +189,7 @@ This option makes them visible. Set the delay between screen updates to .Ar time seconds, which may be fractional. -The default delay between updates is 1 second. +The default delay between updates is 2 seconds. .It Fl T Toggle displaying thread ID (tid) instead of process id (pid). .It Fl t @@ -398,6 +398,7 @@ ID corresponding to the process, USERNAME is the name of the process's owner (if .Fl u is specified, a UID column will be substituted for USERNAME), +THR is the thread count, showing the number of threads a process has, PRI is the current priority of the process, NICE is the .Xr nice 1 diff --git a/usr.bin/vmstat/vmstat.8 b/usr.bin/vmstat/vmstat.8 index de4176c9361c..80facb05cc35 100644 --- a/usr.bin/vmstat/vmstat.8 +++ b/usr.bin/vmstat/vmstat.8 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 21, 2021 +.Dd July 16, 2025 .Dt VMSTAT 8 .Os .Sh NAME @@ -71,7 +71,7 @@ Generate output via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .It Fl a When used with @@ -371,7 +371,7 @@ statistics every second. .Xr systat 1 , .Xr libmemstat 3 , .Xr libxo 3 , -.Xr xo_parse_args 3 , +.Xr xo_options 7 , .Xr gstat 8 , .Xr iostat 8 , .Xr pstat 8 , diff --git a/usr.bin/vtfontcvt/Makefile b/usr.bin/vtfontcvt/Makefile index de011660ca28..13e60c406b26 100644 --- a/usr.bin/vtfontcvt/Makefile +++ b/usr.bin/vtfontcvt/Makefile @@ -1,6 +1,6 @@ PROG= vtfontcvt SRCS= vtfontcvt.c lz4.c -MAN8= vtfontcvt.8 +MAN= vtfontcvt.8 # lz4 compression functionality .PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4 diff --git a/usr.bin/w/w.1 b/usr.bin/w/w.1 index a92edc6f0059..159eb3370c8c 100644 --- a/usr.bin/w/w.1 +++ b/usr.bin/w/w.1 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 24, 2020 +.Dd July 16, 2025 .Dt W 1 .Os .Sh NAME @@ -61,7 +61,7 @@ Generate output via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .It Fl d dumps out the entire process list on a per controlling @@ -145,7 +145,7 @@ flags are no longer supported. .Xr uptime 1 , .Xr who 1 , .Xr libxo 3 , -.Xr xo_parse_args 3 +.Xr xo_options 7 .Sh HISTORY The .Nm diff --git a/usr.bin/wc/wc.1 b/usr.bin/wc/wc.1 index 482145c8f01f..656408794950 100644 --- a/usr.bin/wc/wc.1 +++ b/usr.bin/wc/wc.1 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 11, 2020 +.Dd July 16, 2025 .Dt WC 1 .Os .Sh NAME @@ -70,7 +70,7 @@ Generate output via .Xr libxo 3 in a selection of different human and machine readable formats. See -.Xr xo_parse_args 3 +.Xr xo_options 7 for details on command line arguments. .It Fl L Write the length of the line containing the most bytes (default) or characters @@ -196,7 +196,7 @@ utility. .Sh SEE ALSO .Xr iswspace 3 , .Xr libxo 3 , -.Xr xo_parse_args 3 +.Xr xo_options 7 .Sh STANDARDS The .Nm diff --git a/usr.bin/xargs/tests/Makefile b/usr.bin/xargs/tests/Makefile index b1e6782069de..9fa8ff11fac2 100644 --- a/usr.bin/xargs/tests/Makefile +++ b/usr.bin/xargs/tests/Makefile @@ -1,6 +1,6 @@ PACKAGE= tests -TAP_TESTS_SH= legacy_test +ATF_TESTS_SH= xargs_test ${PACKAGE}FILES+= regress.0.in ${PACKAGE}FILES+= regress.0.out @@ -17,12 +17,11 @@ ${PACKAGE}FILES+= regress.R-1.out ${PACKAGE}FILES+= regress.in ${PACKAGE}FILES+= regress.n1.out ${PACKAGE}FILES+= regress.n2.out -${PACKAGE}FILES+= regress.n2147483647.out +${PACKAGE}FILES+= regress.nargmax.out ${PACKAGE}FILES+= regress.n2P0.out ${PACKAGE}FILES+= regress.n3.out ${PACKAGE}FILES+= regress.normal.out ${PACKAGE}FILES+= regress.quotes.in ${PACKAGE}FILES+= regress.quotes.out -${PACKAGE}FILES+= regress.sh .include <bsd.test.mk> diff --git a/usr.bin/xargs/tests/legacy_test.sh b/usr.bin/xargs/tests/legacy_test.sh deleted file mode 100644 index 3c7842d07bf0..000000000000 --- a/usr.bin/xargs/tests/legacy_test.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -SRCDIR="$(dirname "${0}")"; export SRCDIR - -m4 "${SRCDIR}/../regress.m4" "${SRCDIR}/regress.sh" | sh diff --git a/usr.bin/xargs/tests/regress.n2147483647.out b/usr.bin/xargs/tests/regress.nargmax.out index cc32a92a2199..cc32a92a2199 100644 --- a/usr.bin/xargs/tests/regress.n2147483647.out +++ b/usr.bin/xargs/tests/regress.nargmax.out diff --git a/usr.bin/xargs/tests/regress.sh b/usr.bin/xargs/tests/regress.sh deleted file mode 100644 index 9b4839d2a8ec..000000000000 --- a/usr.bin/xargs/tests/regress.sh +++ /dev/null @@ -1,32 +0,0 @@ - -echo 1..21 - -REGRESSION_START($1) - -REGRESSION_TEST(`normal', `xargs echo The <${SRCDIR}/regress.in') -REGRESSION_TEST(`I', `xargs -I% echo The % % % %% % % <${SRCDIR}/regress.in') -REGRESSION_TEST(`J', `xargs -J% echo The % again. <${SRCDIR}/regress.in') -REGRESSION_TEST(`L', `xargs -L3 echo <${SRCDIR}/regress.in') -REGRESSION_TEST(`P1', `xargs -P1 echo <${SRCDIR}/regress.in') -REGRESSION_TEST(`R', `xargs -I% -R1 echo The % % % %% % % <${SRCDIR}/regress.in') -REGRESSION_TEST(`R-1', `xargs -I% -R-1 echo The % % % %% % % <${SRCDIR}/regress.in') -REGRESSION_TEST(`n1', `xargs -n1 echo <${SRCDIR}/regress.in') -REGRESSION_TEST(`n2', `xargs -n2 echo <${SRCDIR}/regress.in') -# This test may consume a large amount of memory, making it unsuited to CI -# environments. Disable it for now. -#REGRESSION_TEST(`n2147483647', `xargs -n2147483647 <${SRCDIR}/regress.in') -REGRESSION_TEST(`n2P0',`xargs -n2 -P0 echo <${SRCDIR}/regress.in | sort') -REGRESSION_TEST(`n3', `xargs -n3 echo <${SRCDIR}/regress.in') -REGRESSION_TEST(`0', `xargs -0 -n1 echo <${SRCDIR}/regress.0.in') -REGRESSION_TEST(`0I', `xargs -0 -I% echo The % %% % <${SRCDIR}/regress.0.in') -REGRESSION_TEST(`0J', `xargs -0 -J% echo The % again. <${SRCDIR}/regress.0.in') -REGRESSION_TEST(`0L', `xargs -0 -L2 echo <${SRCDIR}/regress.0.in') -REGRESSION_TEST(`0P1', `xargs -0 -P1 echo <${SRCDIR}/regress.0.in') -REGRESSION_TEST(`quotes', `xargs -n1 echo <${SRCDIR}/regress.quotes.in') - -REGRESSION_TEST_FREEFORM(`parallel1', `echo /var/empty /var/empty | xargs -n1 -P2 test -d; [ $? = 0 ]') -REGRESSION_TEST_FREEFORM(`parallel2', `echo /var/empty /var/empty/nodir | xargs -n1 -P2 test -d; [ $? = 1 ]') -REGRESSION_TEST_FREEFORM(`parallel3', `echo /var/empty/nodir /var/empty | xargs -n1 -P2 test -d; [ $? = 1 ]') -REGRESSION_TEST_FREEFORM(`parallel4', `echo /var/empty/nodir /var/empty/nodir | xargs -n1 -P2 test -d; [ $? = 1 ]') - -REGRESSION_END() diff --git a/usr.bin/xargs/tests/xargs_test.sh b/usr.bin/xargs/tests/xargs_test.sh new file mode 100755 index 000000000000..12c9407a7e45 --- /dev/null +++ b/usr.bin/xargs/tests/xargs_test.sh @@ -0,0 +1,193 @@ +# +# Copyright (c) 2002 Juli Mallett <jmallett@FreeBSD.org> +# Copyright (c) 2025 Dag-Erling Smørgrav <des@FreeBSD.org> +# +# SPDX-License-Identifier: BSD-2-Clause +# + +SRCDIR=$(atf_get_srcdir) + +atf_test_case xargs_normal +xargs_normal_body() +{ + atf_check -o file:${SRCDIR}/regress.normal.out \ + xargs echo The <${SRCDIR}/regress.in +} + +atf_test_case xargs_I +xargs_I_body() +{ + atf_check -o file:${SRCDIR}/regress.I.out \ + xargs -I% echo The % % % %% % % <${SRCDIR}/regress.in +} + +atf_test_case xargs_J +xargs_J_body() +{ + atf_check -o file:${SRCDIR}/regress.J.out \ + xargs -J% echo The % again. <${SRCDIR}/regress.in +} + +atf_test_case xargs_L +xargs_L_body() +{ + atf_check -o file:${SRCDIR}/regress.L.out \ + xargs -L3 echo <${SRCDIR}/regress.in +} + +atf_test_case xargs_P1 +xargs_P1_body() +{ + atf_check -o file:${SRCDIR}/regress.P1.out \ + xargs -P1 echo <${SRCDIR}/regress.in +} + +atf_test_case xargs_R +xargs_R_body() +{ + atf_check -o file:${SRCDIR}/regress.R.out \ + xargs -I% -R1 echo The % % % %% % % <${SRCDIR}/regress.in +} + +atf_test_case xargs_R_1 +xargs_R_1_body() +{ + atf_check -o file:${SRCDIR}/regress.R-1.out \ + xargs -I% -R-1 echo The % % % %% % % <${SRCDIR}/regress.in +} + +atf_test_case xargs_n1 +xargs_n1_body() +{ + atf_check -o file:${SRCDIR}/regress.n1.out \ + xargs -n1 echo <${SRCDIR}/regress.in +} + +atf_test_case xargs_n2 +xargs_n2_body() +{ + atf_check -o file:${SRCDIR}/regress.n2.out \ + xargs -n2 echo <${SRCDIR}/regress.in +} + +atf_test_case xargs_nargmax +xargs_nargmax_body() +{ + argmax=$(sysctl -n kern.argmax) + atf_check -o file:${SRCDIR}/regress.nargmax.out \ + xargs -n$((argmax)) <${SRCDIR}/regress.in + atf_check -s exit:1 -e match:"too large" \ + xargs -n$((argmax+1)) <${SRCDIR}/regress.in +} + +atf_test_case xargs_n2P0 +xargs_n2P0_body() +{ + atf_check -o save:regress.out \ + xargs -n2 -P0 echo <${SRCDIR}/regress.in + atf_check -o file:${SRCDIR}/regress.n2P0.out \ + sort regress.out +} + +atf_test_case xargs_n3 +xargs_n3_body() +{ + atf_check -o file:${SRCDIR}/regress.n3.out \ + xargs -n3 echo <${SRCDIR}/regress.in +} + +atf_test_case xargs_0 +xargs_0_body() +{ + atf_check -o file:${SRCDIR}/regress.0.out \ + xargs -0 -n1 echo <${SRCDIR}/regress.0.in +} + +atf_test_case xargs_0I +xargs_0I_body() +{ + atf_check -o file:${SRCDIR}/regress.0I.out \ + xargs -0 -I% echo The % %% % <${SRCDIR}/regress.0.in +} + +atf_test_case xargs_0J +xargs_0J_body() +{ + atf_check -o file:${SRCDIR}/regress.0J.out \ + xargs -0 -J% echo The % again. <${SRCDIR}/regress.0.in +} + +atf_test_case xargs_0L +xargs_0L_body() +{ + atf_check -o file:${SRCDIR}/regress.0L.out \ + xargs -0 -L2 echo <${SRCDIR}/regress.0.in +} + +atf_test_case xargs_0P1 +xargs_0P1_body() +{ + atf_check -o file:${SRCDIR}/regress.0P1.out \ + xargs -0 -P1 echo <${SRCDIR}/regress.0.in +} + +atf_test_case xargs_quotes +xargs_quotes_body() +{ + atf_check -o file:${SRCDIR}/regress.quotes.out \ + xargs -n1 echo <${SRCDIR}/regress.quotes.in +} + +atf_test_case xargs_parallel1 +xargs_parallel1_body() +{ + echo /var/empty /var/empty >input + atf_check xargs -n1 -P2 test -d <input +} + +atf_test_case xargs_parallel2 +xargs_parallel2_body() +{ + echo /var/empty /var/empty/nodir >input + atf_check -s exit:1 xargs -n1 -P2 test -d <input +} + +atf_test_case xargs_parallel3 +xargs_parallel3_body() +{ + echo /var/empty/nodir /var/empty >input + atf_check -s exit:1 xargs -n1 -P2 test -d <input +} + +atf_test_case xargs_parallel4 +xargs_parallel4_body() +{ + echo /var/empty/nodir /var/empty/nodir >input + atf_check -s exit:1 xargs -n1 -P2 test -d <input +} + +atf_init_test_cases() +{ + atf_add_test_case xargs_normal + atf_add_test_case xargs_I + atf_add_test_case xargs_J + atf_add_test_case xargs_L + atf_add_test_case xargs_P1 + atf_add_test_case xargs_R + atf_add_test_case xargs_R_1 + atf_add_test_case xargs_n1 + atf_add_test_case xargs_n2 + atf_add_test_case xargs_nargmax + atf_add_test_case xargs_n2P0 + atf_add_test_case xargs_n3 + atf_add_test_case xargs_0 + atf_add_test_case xargs_0I + atf_add_test_case xargs_0J + atf_add_test_case xargs_0L + atf_add_test_case xargs_0P1 + atf_add_test_case xargs_quotes + atf_add_test_case xargs_parallel1 + atf_add_test_case xargs_parallel2 + atf_add_test_case xargs_parallel3 + atf_add_test_case xargs_parallel4 +} diff --git a/usr.bin/xargs/xargs.c b/usr.bin/xargs/xargs.c index 237beff26504..2a7f026e5066 100644 --- a/usr.bin/xargs/xargs.c +++ b/usr.bin/xargs/xargs.c @@ -166,7 +166,7 @@ main(int argc, char *argv[]) break; case 'n': nflag = 1; - nargs = (int)strtonum(optarg, 1, INT_MAX, &errstr); + nargs = (int)strtonum(optarg, 1, arg_max, &errstr); if (errstr) errx(1, "-%c %s: %s", ch, optarg, errstr); break; |