Bash-5.3 distribution sources and documentation

This commit is contained in:
Chet Ramey
2025-07-03 16:15:36 -04:00
parent 6794b5478f
commit b8c60bc9ca
896 changed files with 174241 additions and 103591 deletions
+36 -5
View File
@@ -100,13 +100,14 @@ INC = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(topdir)/builtins -I${srcdir} \
.c.o:
$(SHOBJ_CC) $(SHOBJ_CFLAGS) $(CCFLAGS) $(INC) -c -o $@ $<
ALLPROG = print truefalse sleep finfo logname basename dirname fdflags \
tty pathchk tee head mkdir rmdir mkfifo mktemp printenv id whoami \
uname sync push ln unlink realpath strftime mypid setpgid seq rm \
accept csv dsv cut stat getconf
accept csv dsv cut stat getconf kv strptime chmod fltexpr
OTHERPROG = necho hello cat pushd asort
SUBDIRS = perl
all: $(SHOBJ_STATUS)
supported: $(ALLPROG)
@@ -225,12 +226,21 @@ csv: csv.o
dsv: dsv.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ dsv.o $(SHOBJ_LIBS)
kv: kv.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ kv.o $(SHOBJ_LIBS)
cut: cut.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ cut.o $(SHOBJ_LIBS)
strftime: strftime.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ strftime.o $(SHOBJ_LIBS)
strptime: strptime.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ strptime.o $(SHOBJ_LIBS)
chmod: chmod.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ chmod.o $(SHOBJ_LIBS)
mypid: mypid.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ mypid.o $(SHOBJ_LIBS)
@@ -243,6 +253,10 @@ stat: stat.o
asort: asort.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ asort.o $(SHOBJ_LIBS)
fltexpr: fltexpr.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ fltexpr.o $(SHOBJ_LIBS) -lm
# pushd is a special case. We use the same source that the builtin version
# uses, with special compilation options.
#
@@ -259,14 +273,20 @@ pushd: pushd.o
clean:
$(RM) $(ALLPROG) $(OTHERPROG) *.o
-( cd perl && ${MAKE} ${MFLAGS} $@ )
-for subdir in $(SUBDIRS); do \
( cd $$subdir && test -f Makefile && ${MAKE} ${MFLAGS} $@ ) ; \
done
mostlyclean: clean
-( cd perl && ${MAKE} ${MFLAGS} $@ )
-for subdir in $(SUBDIRS); do \
( cd $$subdir && test -f Makefile && ${MAKE} ${MFLAGS} $@ ) ; \
done
distclean maintainer-clean: clean
$(RM) Makefile Makefile.inc Makefile.sample pushd.c
-( cd perl && ${MAKE} ${MFLAGS} $@ )
-for subdir in $(SUBDIRS); do \
( cd $$subdir && test -f Makefile && ${MAKE} ${MFLAGS} $@ ) ; \
done
installdirs:
@${SHELL} $(SUPPORT_SRC)mkinstalldirs $(DESTDIR)$(loadablesdir)
@@ -298,6 +318,14 @@ uninstall-unsupported:
install: install-$(SHOBJ_STATUS)
uninstall: uninstall-$(SHOBJ_STATUS)
OBJS = print.o truefalse.o accept.o sleep.o finfo.o getconf.o logname.o \
basename.o dirname.o tty.o pathchk.o tee.o head.o rmdir.o necho.o \
hello.o cat.o csv.o dsv.o kv.o cut.o printenv.o id.o whoami.o uname.o \
sync.o push.o mkdir.o mktemp.o realpath.o strftime.o setpgid.o stat.o \
fdflags.o seq.o asort.o strptime.o chmod.o
${OBJS}: ${BUILD_DIR}/config.h
print.o: print.c
truefalse.o: truefalse.c
accept.o: accept.c
@@ -315,8 +343,10 @@ rmdir.o: rmdir.c
necho.o: necho.c
hello.o: hello.c
cat.o: cat.c
chmod.o: chmod.c
csv.o: csv.c
dsv.o: dsv.c
kv.o: kv.c
cut.o: cut.c
printenv.o: printenv.c
id.o: id.c
@@ -333,3 +363,4 @@ stat.o: stat.c
fdflags.o: fdflags.c
seq.o: seq.c
asort.o: asort.c
strptime.o: strptime.c
+4 -8
View File
@@ -1,7 +1,6 @@
/* accept - listen for and accept a remote network connection on a given port */
/*
Copyright (C) 2020 Free Software Foundation, Inc.
Copyright (C) 2020,2022,2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -42,8 +41,7 @@
static int accept_bind_variable (char *, int);
int
accept_builtin (list)
WORD_LIST *list;
accept_builtin (WORD_LIST *list)
{
SHELL_VAR *v;
intmax_t iport;
@@ -105,7 +103,7 @@ accept_builtin (list)
return (EX_USAGE);
}
if (legal_number (list->word->word, &iport) == 0 || iport < 0 || iport > TYPE_MAXIMUM (unsigned short))
if (valid_number (list->word->word, &iport) == 0 || iport < 0 || iport > TYPE_MAXIMUM (unsigned short))
{
builtin_error ("%s: invalid port number", list->word->word);
return (EXECUTION_FAILURE);
@@ -194,9 +192,7 @@ accept_builtin (list)
}
static int
accept_bind_variable (varname, intval)
char *varname;
int intval;
accept_bind_variable (char *varname, int intval)
{
SHELL_VAR *v;
char ibuf[INT_STRLEN_BOUND (int) + 1], *p;
+25 -15
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 2020 Free Software Foundation, Inc.
Copyright (C) 2020,2022-2024 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,6 +14,10 @@
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* Contributed by Geir Hauge <geir.hauge@gmail.com> */
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
@@ -36,7 +40,8 @@ static int reverse_flag;
static int numeric_flag;
static int
compare(const void *p1, const void *p2) {
compare(const void *p1, const void *p2)
{
const sort_element e1 = *(sort_element *) p1;
const sort_element e2 = *(sort_element *) p2;
@@ -55,7 +60,8 @@ compare(const void *p1, const void *p2) {
}
static int
sort_index(SHELL_VAR *dest, SHELL_VAR *source) {
sort_index(SHELL_VAR *dest, SHELL_VAR *source)
{
HASH_TABLE *hash;
BUCKET_CONTENTS *bucket;
sort_element *sa;
@@ -70,7 +76,7 @@ sort_index(SHELL_VAR *dest, SHELL_VAR *source) {
if (assoc_p(source)) {
hash = assoc_cell(source);
n = hash->nentries;
sa = xmalloc(n * sizeof(sort_element));
sa = n ? xmalloc(n * sizeof(sort_element)) : 0;
i = 0;
for ( j = 0; j < hash->nbuckets; ++j ) {
bucket = hash->bucket_array[j];
@@ -89,7 +95,7 @@ sort_index(SHELL_VAR *dest, SHELL_VAR *source) {
else {
array = array_cell(source);
n = array_num_elements(array);
sa = xmalloc(n * sizeof(sort_element));
sa = n ? xmalloc(n * sizeof(sort_element)) : 0;
i = 0;
for (ae = element_forw(array->head); ae != array->head; ae = element_forw(ae)) {
@@ -105,12 +111,12 @@ sort_index(SHELL_VAR *dest, SHELL_VAR *source) {
// sanity check
if ( i != n ) {
builtin_error("%s: corrupt array", source->name);
xfree (sa);
return EXECUTION_FAILURE;
}
qsort(sa, n, sizeof(sort_element), compare);
array_flush(dest_array);
if (n)
qsort(sa, n, sizeof(sort_element), compare);
for ( i = 0; i < n; ++i ) {
if ( assoc_p(source) )
@@ -121,11 +127,13 @@ sort_index(SHELL_VAR *dest, SHELL_VAR *source) {
array_insert(dest_array, i, key);
}
xfree (sa);
return EXECUTION_SUCCESS;
}
static int
sort_inplace(SHELL_VAR *var) {
sort_inplace(SHELL_VAR *var)
{
size_t i, n;
ARRAY *a;
ARRAY_ELEMENT *ae;
@@ -152,6 +160,7 @@ sort_inplace(SHELL_VAR *var) {
// sanity check
if ( i != n ) {
builtin_error("%s: corrupt array", var->name);
xfree (sa);
return EXECUTION_FAILURE;
}
@@ -174,7 +183,8 @@ sort_inplace(SHELL_VAR *var) {
}
int
asort_builtin(WORD_LIST *list) {
asort_builtin(WORD_LIST *list)
{
SHELL_VAR *var, *var2;
char *word;
int opt, ret;
@@ -202,7 +212,7 @@ asort_builtin(WORD_LIST *list) {
return EX_USAGE;
}
if (legal_identifier (list->word->word) == 0) {
if (valid_identifier (list->word->word) == 0) {
sh_invalidid (list->word->word);
return EXECUTION_FAILURE;
}
@@ -212,18 +222,18 @@ asort_builtin(WORD_LIST *list) {
builtin_usage();
return EX_USAGE;
}
if (legal_identifier (list->next->word->word) == 0) {
if (valid_identifier (list->next->word->word) == 0) {
sh_invalidid (list->next->word->word);
return EXECUTION_FAILURE;
}
var = find_or_make_array_variable(list->word->word, 1);
if (var == 0)
return EXECUTION_FAILURE;
var2 = find_variable(list->next->word->word);
if ( !var2 || ( !array_p(var2) && !assoc_p(var2) ) ) {
builtin_error("%s: Not an array", list->next->word->word);
return EXECUTION_FAILURE;
}
var = builtin_find_indexed_array(list->word->word, 1);
if (var == 0)
return EXECUTION_FAILURE;
return sort_index(var, var2);
}
+2 -3
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2020 Free Software Foundation, Inc.
Copyright (C) 1999-2020,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -33,8 +33,7 @@
#include "bashgetopt.h"
int
basename_builtin (list)
WORD_LIST *list;
basename_builtin (WORD_LIST *list)
{
int slen, sufflen, off;
char *string, *suffix, *fn;
+17 -17
View File
@@ -22,6 +22,8 @@
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <fcntl.h>
#include <errno.h>
@@ -32,13 +34,11 @@
extern int errno;
#endif
extern char *strerror ();
extern char **make_builtin_argv ();
extern char *strerror (int);
extern char **make_builtin_argv (WORD_LIST *, int *);
static int
fcopy(fd, fn)
int fd;
char *fn;
fcopy(int fd, char *fn)
{
char buf[4096], *s;
int n, w, e;
@@ -70,21 +70,20 @@ char *fn;
}
int
cat_main (argc, argv)
int argc;
char **argv;
cat_main (int argc, char **argv)
{
int i, fd, r;
int i, fd, r, closefd;
char *s;
if (argc == 1)
return (fcopy(0, "standard input"));
for (i = r = 1; i < argc; i++) {
for (i = 1, r = 0; i < argc; i++) {
QUIT;
if (argv[i][0] == '-' && argv[i][1] == '\0')
if (argv[i][0] == '-' && argv[i][1] == '\0') {
fd = 0;
else {
closefd = 0;
} else {
fd = open(argv[i], O_RDONLY, 0666);
if (fd < 0) {
s = strerror(errno);
@@ -93,11 +92,13 @@ char **argv;
write(2, ": ", 2);
write(2, s, strlen(s));
write(2, "\n", 1);
r++;
continue;
}
closefd = 1;
}
r = fcopy(fd, argv[i]);
if (fd != 0)
r += fcopy(fd, argv[i]);
if (closefd)
close(fd);
}
QUIT;
@@ -105,8 +106,7 @@ char **argv;
}
int
cat_builtin(list)
WORD_LIST *list;
cat_builtin(WORD_LIST *list)
{
char **v;
int c, r;
@@ -116,7 +116,7 @@ WORD_LIST *list;
r = cat_main(c, v);
free(v);
return r;
return r; /* relies on EXECUTION_SUCCESS being 0 */
}
char *cat_doc[] = {
+156
View File
@@ -0,0 +1,156 @@
/* chmod - change file mode bits */
/* See Makefile for compilation details. */
/*
Copyright (C) 2024-2025 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "bashtypes.h"
#include "posixstat.h"
#include <errno.h>
#include <stdio.h>
#include "bashansi.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#if !defined (errno)
extern int errno;
#endif
#define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
extern int parse_symbolic_mode (char *, mode_t);
#define STANDARD_BITS (S_IRWXU | S_IRWXG | S_IRWXO)
#define ALLBITS (STANDARD_BITS | S_ISUID| S_ISGID | S_ISVTX)
int
chmod_builtin (WORD_LIST *list)
{
int opt, nmode, lmode, rval;
char *mode;
struct stat st;
WORD_LIST *l;
reset_internal_getopt ();
mode = (char *)NULL;
while ((opt = internal_getopt(list, "fhvRHLP")) != -1)
switch (opt)
{
CASE_HELPOPT;
default:
return (EX_DISKFALLBACK);
}
list = loptend;
if (list == 0)
{
builtin_usage ();
return (EX_USAGE);
}
mode = list->word->word;
list = list->next;
if (list == 0)
{
builtin_usage ();
return (EX_USAGE);
}
nmode = -1;
if (ISOCTAL (*mode)) /* octal number */
{
nmode = read_octal (mode);
if (nmode < 0)
{
builtin_error ("invalid file mode: %s", mode);
return (EXECUTION_FAILURE);
}
}
else /* test for valid symbolic mode */
{
/* initial bits are a=rwx; the mode argument modifies them */
lmode = parse_symbolic_mode (mode, ALLBITS);
if (lmode < 0)
{
builtin_error ("invalid file mode: %s", mode);
return (EXECUTION_FAILURE);
}
}
for (rval = EXECUTION_SUCCESS, l = list; l; l = l->next)
{
lmode = nmode;
if (stat (l->word->word, &st) < 0)
{
builtin_error ("`%s': cannot stat: %s", l->word->word, strerror (errno));
rval = EXECUTION_FAILURE;
continue;
}
if (lmode == -1)
{
lmode = parse_symbolic_mode (mode, st.st_mode & ALLBITS);
if (lmode < 0)
{
builtin_error ("`%s': invalid file mode: %s", l->word->word, mode);
rval = EXECUTION_FAILURE;
continue;
}
}
if (chmod (l->word->word, lmode))
{
builtin_error ("`%s': cannot change mode: %s", l->word->word, strerror (errno));
rval = EXECUTION_FAILURE;
continue;
}
}
return rval;
}
char *chmod_doc[] = {
"Change file mode bits.",
"",
"Change file mode bits. Change the mode bits of files named as",
"arguments, in the order specified, as specified by MODE."
"The MODE argument may be an octal number or a symbolic mode like",
"that described in chmod(1). If a symbolic mode is used, the",
"operations are interpreted relative to an initial mode of \"a=rwx\".",
"",
"The return value is 0 unless an error occurs.",
(char *)NULL
};
struct builtin chmod_struct = {
"chmod",
chmod_builtin,
BUILTIN_ENABLED,
chmod_doc,
"chmod [-R] mode file [file...]",
0
};
+14 -11
View File
@@ -2,7 +2,7 @@
fields */
/*
Copyright (C) 2020 Free Software Foundation, Inc.
Copyright (C) 2020,2022 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +30,8 @@
#include "loadables.h"
#if defined (ARRAY_VARS)
#define CSV_ARRAY_DEFAULT "CSV"
#define NQUOTE 0
@@ -39,9 +41,7 @@
element of array variable CSV, starting at index 0. The format of LINE is
as described in RFC 4180. */
static int
csvsplit (csv, line, dstring)
SHELL_VAR *csv;
char *line, *dstring;
csvsplit (SHELL_VAR *csv, char *line, char *dstring)
{
arrayind_t ind;
char *field, *prev, *buf, *xbuf;
@@ -101,12 +101,13 @@ csvsplit (csv, line, dstring)
return (rval = ind); /* number of fields */
}
#endif
int
csv_builtin (list)
WORD_LIST *list;
csv_builtin (WORD_LIST *list)
{
int opt, rval;
#if defined (ARRAY_VARS)
char *array_name, *csvstring;
SHELL_VAR *v;
@@ -132,7 +133,7 @@ csv_builtin (list)
if (array_name == 0)
array_name = CSV_ARRAY_DEFAULT;
if (legal_identifier (array_name) == 0)
if (valid_identifier (array_name) == 0)
{
sh_invalidid (array_name);
return (EXECUTION_FAILURE);
@@ -167,6 +168,10 @@ csv_builtin (list)
opt = csvsplit (v, csvstring, ",");
/* Maybe do something with OPT here, it's the number of fields */
#else
builtin_error ("arrays not available");
rval = EXECUTION_FAILURE;
#endif
return (rval);
}
@@ -174,16 +179,14 @@ csv_builtin (list)
/* Called when builtin is enabled and loaded from the shared object. If this
function returns 0, the load fails. */
int
csv_builtin_load (name)
char *name;
csv_builtin_load (char *name)
{
return (1);
}
/* Called when builtin is disabled. */
void
csv_builtin_unload (name)
char *name;
csv_builtin_unload (char *name)
{
}
+90 -101
View File
@@ -2,7 +2,7 @@
or print them to the standard output */
/*
Copyright (C) 2020 Free Software Foundation, Inc.
Copyright (C) 2020,2022,2023 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -61,8 +61,7 @@ struct cutop
};
static int
poscmp (a, b)
void *a, *b;
poscmp (const void *a, const void *b)
{
struct cutpos *p1, *p2;
@@ -72,9 +71,7 @@ poscmp (a, b)
}
static int
getlist (arg, opp)
char *arg;
struct cutpos **opp;
getlist (char *arg, struct cutpos **opp)
{
char *ntok, *ltok, *larg;
int s, e;
@@ -96,7 +93,7 @@ getlist (arg, opp)
s = BOL;
else
{
if (legal_number (ntok, &num) == 0 || (int)num != num || num <= 0)
if (valid_number (ntok, &num) == 0 || (int)num != num || num <= 0)
{
builtin_error ("%s: invalid list value", ntok);
*opp = poslist;
@@ -111,7 +108,7 @@ getlist (arg, opp)
e = EOL;
else
{
if (legal_number (ltok, &num) == 0 || (int)num != num || num <= 0)
if (valid_number (ltok, &num) == 0 || (int)num != num || num <= 0)
{
builtin_error ("%s: invalid list value", ltok);
*opp = poslist;
@@ -146,12 +143,8 @@ getlist (arg, opp)
}
static int
cutbytes (v, line, ops)
SHELL_VAR *v;
char *line;
struct cutop *ops;
cutbytes (SHELL_VAR *v, arrayind_t ind, char *line, struct cutop *ops)
{
arrayind_t ind;
char *buf, *bmap;
size_t llen;
int i, b, n, s, e;
@@ -181,37 +174,31 @@ cutbytes (v, line, ops)
buf[b++] = line[i];
buf[b] = 0;
#if defined (ARRAY_VARS)
if (v)
{
ind = 0;
bind_array_element (v, ind, buf, 0);
ind++;
}
bind_array_element (v, ind, buf, 0);
else
#endif
printf ("%s\n", buf);
free (buf);
free (bmap);
return ind;
return 1;
}
static int
cutchars (v, line, ops)
SHELL_VAR *v;
char *line;
struct cutop *ops;
cutchars (SHELL_VAR *v, arrayind_t ind, char *line, struct cutop *ops)
{
arrayind_t ind;
char *buf, *bmap;
wchar_t *wbuf, *wb2;
size_t llen, wlen;
int i, b, n, s, e;
if (MB_CUR_MAX == 1)
return (cutbytes (v, line, ops));
return (cutbytes (v, ind, line, ops));
if (locale_utf8locale && utf8_mbsmbchar (line) == 0)
return (cutbytes (v, line, ops));
return (cutbytes (v, ind, line, ops));
llen = strlen (line);
wbuf = (wchar_t *)xmalloc ((llen + 1) * sizeof (wchar_t));
@@ -220,7 +207,7 @@ cutchars (v, line, ops)
if (MB_INVALIDCH (wlen))
{
free (wbuf);
return (cutbytes (v, line, ops));
return (cutbytes (v, ind, line, ops));
}
bmap = xmalloc (llen + 1);
@@ -252,19 +239,17 @@ cutchars (v, line, ops)
buf = bmap;
n = wcstombs (buf, wb2, llen);
#if defined (ARRAY_VARS)
if (v)
{
ind = 0;
bind_array_element (v, ind, buf, 0);
ind++;
}
bind_array_element (v, ind, buf, 0);
else
#endif
printf ("%s\n", buf);
free (buf);
free (wb2);
return ind;
return 1;
}
/* The basic strategy is to cut the line into fields using strsep, populate
@@ -272,18 +257,12 @@ cutchars (v, line, ops)
bitmap approach as cut{bytes,chars} and assign them to the array variable
V or print them on stdout. This function obeys SFLAG. */
static int
cutfields (v, line, ops)
SHELL_VAR *v;
char *line;
struct cutop *ops;
cutfields (SHELL_VAR *v, arrayind_t ind, char *line, struct cutop *ops)
{
arrayind_t ind;
char *buf, *bmap, *field, **fields, delim[2];
size_t llen, fsize;
int i, b, n, s, e, nf;
ind = 0;
delim[0] = ops->delim;
delim[1] = '\0';
@@ -310,15 +289,15 @@ cutfields (v, line, ops)
{
free (fields);
if (ops->flags & SFLAG)
return ind;
return 0;
#if defined (ARRAY_VARS)
if (v)
{
bind_array_element (v, ind, line, 0);
ind++;
}
bind_array_element (v, ind, line, 0);
else
#endif
printf ("%s\n", line);
return ind;
return 1;
}
bmap = xmalloc (nf + 1);
@@ -338,61 +317,61 @@ cutfields (v, line, ops)
bmap[i] = 1;
}
for (i = 1, b = 0; b < nf; b++)
/* build the string and assign or print it all at once */
buf = xmalloc (strlen (line) + 1);
for (i = 1, n = b = 0; b < nf; b++)
{
if (bmap[b] == 0)
continue;
if (v)
{
bind_array_element (v, ind, fields[b], 0);
ind++;
}
else
{
if (i == 0)
putchar (ops->delim);
printf ("%s", fields[b]);
}
if (i == 0)
buf[n++] = ops->delim;
strcpy (buf + n, fields[b]);
n += STRLEN (fields[b]);
i = 0;
}
if (v == 0)
putchar ('\n');
return nf;
#if defined (ARRAY_VARS)
if (v)
bind_array_element (v, ind, buf, 0);
else
#endif
printf ("%s\n", buf);
free (bmap);
free (buf);
return 1;
}
static int
cutline (v, line, ops)
SHELL_VAR *v;
char *line;
struct cutop *ops;
cutline (SHELL_VAR *v, arrayind_t ind, char *line, struct cutop *ops)
{
int rval;
if (ops->flags & BFLAG)
rval = cutbytes (v, line, ops);
rval = cutbytes (v, ind, line, ops);
else if (ops->flags & CFLAG)
rval = cutchars (v, line, ops);
rval = cutchars (v, ind, line, ops);
else
rval = cutfields (v, line, ops);
rval = cutfields (v, ind, line, ops);
return (rval >= 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
return (rval);
}
static int
cutfile (v, list, ops)
SHELL_VAR *v;
WORD_LIST *list;
struct cutop *ops;
cutfile (SHELL_VAR *v, WORD_LIST *list, struct cutop *ops)
{
int fd, unbuffered_read;
int fd, unbuffered_read, r;
char *line, *b;
size_t llen;
WORD_LIST *l;
ssize_t n;
arrayind_t ind;
line = 0;
llen = 0;
ind = 0;
l = list;
do
@@ -419,7 +398,8 @@ cutfile (v, list, ops)
QUIT;
if (line[n] == '\n')
line[n] = '\0'; /* cutline expects no newline terminator */
cutline (v, line, ops); /* can modify line */
r = cutline (v, ind, line, ops); /* can modify line */
ind += r;
}
if (fd > 0)
close (fd);
@@ -437,9 +417,7 @@ cutfile (v, list, ops)
#define OPTSET(x) ((cutflags & (x)) ? 1 : 0)
static int
cut_internal (which, list)
int which; /* not used yet */
WORD_LIST *list;
cut_internal (int which, WORD_LIST *list)
{
int opt, rval, cutflags, delim, npos;
char *array_name, *cutstring, *list_arg;
@@ -461,8 +439,13 @@ cut_internal (which, list)
switch (opt)
{
case 'a':
#if defined (ARRAY_VARS)
array_name = list_optarg;
break;
#else
builtin_error ("arrays not available");
return (EX_USAGE);
#endif
case 'b':
cutflags |= BFLAG;
list_arg = list_optarg;
@@ -497,7 +480,7 @@ cut_internal (which, list)
}
list = loptend;
if (array_name && (legal_identifier (array_name) == 0))
if (array_name && (valid_identifier (array_name) == 0))
{
sh_invalidid (array_name);
return (EXECUTION_FAILURE);
@@ -522,24 +505,17 @@ cut_internal (which, list)
return (EXECUTION_FAILURE);
}
#if defined (ARRAY_VARS)
if (array_name)
{
v = find_or_make_array_variable (array_name, 1);
if (v == 0 || readonly_p (v) || noassign_p (v))
{
v = builtin_find_indexed_array (array_name, 1);
if (v == 0)
{
if (v && readonly_p (v))
err_readonly (array_name);
free (poslist);
return (EXECUTION_FAILURE);
}
else if (array_p (v) == 0)
{
builtin_error ("%s: not an indexed array", array_name);
return (EXECUTION_FAILURE);
}
if (invisible_p (v))
VUNSETATTR (v, att_invisible);
array_flush (array_cell (v));
}
#endif
op.flags = cutflags;
op.delim = delim;
@@ -548,7 +524,8 @@ cut_internal (which, list)
/* we implement cut as a builtin with a cutfile() function that opens each
filename in LIST as a filename (or `-' for stdin) and runs cutline on
every line in the file. */
every line in the file. lcut just runs cutline on the first string in
LIST. */
if (which == 0)
{
cutstring = list->word->word;
@@ -557,24 +534,25 @@ cut_internal (which, list)
free (poslist);
return (EXECUTION_SUCCESS);
}
rval = cutline (v, cutstring, &op);
rval = cutline (v, 0, cutstring, &op);
/* Normalize rval, because cutline returns an increment for ind */
rval = (rval >= 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
else
rval = cutfile (v, list, &op);
free (poslist);
return (rval);
}
int
lcut_builtin (list)
WORD_LIST *list;
lcut_builtin (WORD_LIST *list)
{
return (cut_internal (0, list));
}
int
cut_builtin (list)
WORD_LIST *list;
cut_builtin (WORD_LIST *list)
{
return (cut_internal (1, list));
}
@@ -583,8 +561,8 @@ char *lcut_doc[] = {
"Extract selected fields from a string.",
"",
"Select portions of LINE (as specified by LIST) and assign them to",
"elements of the indexed array ARRAY starting at index 0, or write",
"them to the standard output if -a is not specified.",
"element 0 of the indexed array ARRAY, or write them to the standard",
"output if -a is not specified.",
"",
"Items specified by LIST are either column positions or fields delimited",
"by a special character, and are described more completely in cut(1).",
@@ -592,6 +570,11 @@ char *lcut_doc[] = {
"Columns correspond to bytes (-b), characters (-c), or fields (-f). The",
"field delimiter is specified by -d (default TAB). Column numbering",
"starts at 1.",
"",
"When -a is specified, lcut assigns the selected portions of LINE",
"to index 0 of ARRAY. The string lcut assigns to ARRAY is identical",
"to the string it would write to the standard output if -a were not",
"supplied.",
(char *)NULL
};
@@ -608,7 +591,8 @@ char *cut_doc[] = {
"Extract selected fields from each line of a file.",
"",
"Select portions of each line (as specified by LIST) from each FILE",
"and write them to the standard output. cut reads from the standard",
"and write them to the standard output, or assign them to the indexed",
"array ARRAY starting at index 0. cut reads from the standard",
"input if no FILE arguments are specified or if a FILE argument is a",
"single hyphen.",
"",
@@ -618,6 +602,11 @@ char *cut_doc[] = {
"Columns correspond to bytes (-b), characters (-c), or fields (-f). The",
"field delimiter is specified by -d (default TAB). Column numbering",
"starts at 1.",
"",
"When -a is specified, cut assigns the output from each line it",
"processes to successive elements of ARRAY, beginning at 0. The",
"strings cut assigns to ARRAY are identical to the strings it would",
"write to the standard output if -a were not supplied.",
(char *)NULL
};
+2 -3
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -33,8 +33,7 @@
#include "bashgetopt.h"
int
dirname_builtin (list)
WORD_LIST *list;
dirname_builtin (WORD_LIST *list)
{
int slen;
char *string;
+14 -12
View File
@@ -2,7 +2,7 @@
array with the fields */
/*
Copyright (C) 2022 Free Software Foundation, Inc.
Copyright (C) 2022,2023 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +30,8 @@
#include "loadables.h"
#if defined (ARRAY_VARS)
#define DSV_ARRAY_DEFAULT "DSV"
#define NQUOTE 0
@@ -52,10 +54,7 @@
null fields. If you want to preserve the quote characters in the generated
fields, pass F_PRESERVE; by default, this removes them. */
static int
dsvsplit (dsv, line, dstring, flags)
SHELL_VAR *dsv;
char *line, *dstring;
int flags;
dsvsplit (SHELL_VAR *dsv, char *line, char *dstring, int flags)
{
arrayind_t ind;
char *field, *prev, *buf, *xbuf;
@@ -161,12 +160,13 @@ dsvsplit (dsv, line, dstring, flags)
return (rval = ind); /* number of fields */
}
#endif
int
dsv_builtin (list)
WORD_LIST *list;
dsv_builtin (WORD_LIST *list)
{
int opt, rval, flags;
#if defined (ARRAY_VARS)
char *array_name, *dsvstring, *delims;
SHELL_VAR *v;
@@ -207,7 +207,7 @@ dsv_builtin (list)
if (array_name == 0)
array_name = DSV_ARRAY_DEFAULT;
if (legal_identifier (array_name) == 0)
if (valid_identifier (array_name) == 0)
{
sh_invalidid (array_name);
return (EXECUTION_FAILURE);
@@ -242,6 +242,10 @@ dsv_builtin (list)
opt = dsvsplit (v, dsvstring, delims, flags);
/* Maybe do something with OPT here, it's the number of fields */
#else
builtin_error ("arrays not available");
rval = EXECUTION_FAILURE;
#endif
return (rval);
}
@@ -249,16 +253,14 @@ dsv_builtin (list)
/* Called when builtin is enabled and loaded from the shared object. If this
function returns 0, the load fails. */
int
dsv_builtin_load (name)
char *name;
dsv_builtin_load (char *name)
{
return (1);
}
/* Called when builtin is disabled. */
void
dsv_builtin_unload (name)
char *name;
dsv_builtin_unload (char *name)
{
}
+26 -11
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 2017-2022 Free Software Foundation, Inc.
Copyright (C) 2017-2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -98,9 +98,21 @@ static const struct
# define O_NOSIGPIPE 0
#endif
#ifndef O_NDELAY
/* Solaris has this */
# define O_NDELAY 0
#endif
#ifndef O_LARGEFILE
/* HP-UX has this */
# define O_LARGEFILE 0
#endif
#ifndef O_CLOEXEC
# define IGNOREFLAGS (O_RDONLY|O_WRONLY|O_RDWR)
# define ALLFLAGS (O_APPEND|O_ASYNC|O_SYNC|O_NONBLOCK|O_FSYNC|O_DSYNC|\
O_RSYNC|O_ALT_IO|O_DIRECT|O_NOATIME|O_NOSIGPIPE)
O_RSYNC|O_ALT_IO|O_DIRECT|O_NOATIME|O_NOSIGPIPE|O_NDELAY|O_LARGEFILE|\
IGNOREFLAGS)
/* An unused bit in the file status flags word we can use to pass around the
state of close-on-exec. */
@@ -120,7 +132,7 @@ extern int errno;
/* FIX THIS */
static int
getallflags ()
getallflags (void)
{
int i, allflags;
@@ -164,6 +176,7 @@ printone(int fd, int p, int verbose)
if ((f = getflags(fd, p)) == -1)
return;
/* maybe make the file descriptor printing optional if only one argument */
printf ("%d:", fd);
for (i = 0; i < N_FLAGS; i++)
@@ -224,16 +237,14 @@ parseflags(char *s, int *p, int *n)
}
static void
setone(int fd, char *v, int verbose)
setone(int fd, int pos, int neg, int verbose)
{
int f, n, pos, neg, cloexec;
int f, n, cloexec;
f = getflags(fd, 1);
if (f == -1)
return;
parseflags(v, &pos, &neg);
cloexec = -1;
if ((pos & O_CLOEXEC) && (f & O_CLOEXEC) == 0)
@@ -257,7 +268,7 @@ setone(int fd, char *v, int verbose)
}
static int
getmaxfd ()
getmaxfd (void)
{
int maxfd, ignore;
@@ -281,6 +292,7 @@ int
fdflags_builtin (WORD_LIST *list)
{
int opt, maxfd, i, num, verbose, setflag;
int pos, neg;
char *setspec;
WORD_LIST *l;
intmax_t inum;
@@ -311,6 +323,9 @@ fdflags_builtin (WORD_LIST *list)
if (list == 0 && setflag)
return (EXECUTION_SUCCESS);
if (setflag)
parseflags (setspec, &pos, &neg);
if (list == 0)
{
maxfd = getmaxfd ();
@@ -327,7 +342,7 @@ fdflags_builtin (WORD_LIST *list)
opt = EXECUTION_SUCCESS;
for (l = list; l; l = l->next)
{
if (legal_number (l->word->word, &inum) == 0 || inum < 0)
if (valid_number (l->word->word, &inum) == 0 || inum < 0)
{
builtin_error ("%s: invalid file descriptor", l->word->word);
opt = EXECUTION_FAILURE;
@@ -335,12 +350,12 @@ fdflags_builtin (WORD_LIST *list)
}
num = inum; /* truncate to int */
if (setflag)
setone (num, setspec, verbose);
setone (num, pos, neg, verbose);
else
printone (num, 1, verbose);
}
return (opt);
return (sh_chkwrite (opt));
}
char *fdflags_doc[] =
+48 -96
View File
@@ -6,7 +6,7 @@
*/
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022,2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -51,14 +51,18 @@
extern int errno;
#endif
extern char **make_builtin_argv ();
extern char **make_builtin_argv (WORD_LIST *, int *);
static void perms();
static int printst();
static int printsome();
static void printmode();
static int printfinfo();
static int finfo_main();
static struct stat *getstat(char *);
static int printinfo(char *);
static int getperm(int);
static void perms(int);
static int printst(struct stat *);
static int printsome(char *, int);
static void printmode(int);
static int printfinfo(char *);
static int finfo_main(int, char **);
extern int sh_optind;
extern char *sh_optarg;
@@ -91,21 +95,7 @@ static int pmask;
#define OPTIONS "acdgiflmnopsuACGMP:U"
static int
octal(s)
char *s;
{
int r;
r = *s - '0';
while (*++s >= '0' && *s <= '7')
r = (r * 8) + (*s - '0');
return r;
}
static int
finfo_main(argc, argv)
int argc;
char **argv;
finfo_main(int argc, char **argv)
{
register int i;
int mode, flags, opt;
@@ -134,7 +124,14 @@ char **argv;
case 'n': flags |= OPT_NLINK; break;
case 'o': flags |= OPT_OPERM; break;
case 'p': flags |= OPT_PERM; break;
case 'P': flags |= OPT_PMASK; pmask = octal(sh_optarg); break;
case 'P':
flags |= OPT_PMASK;
pmask = read_octal(sh_optarg);
if (pmask < 0) {
builtin_error ("invalid mode: %s", sh_optarg);
return(1);
}
break;
case 's': flags |= OPT_SIZE; break;
case 'u': flags |= OPT_UID; break;
case 'U': flags |= OPT_UID|OPT_ASCII; break;
@@ -157,15 +154,14 @@ char **argv;
}
static struct stat *
getstat(f)
char *f;
getstat(char *f)
{
static struct stat st;
int fd, r;
intmax_t lfd;
if (strncmp(f, "/dev/fd/", 8) == 0) {
if ((legal_number(f + 8, &lfd) == 0) || (int)lfd != lfd) {
if ((valid_number(f + 8, &lfd) == 0) || (int)lfd != lfd) {
builtin_error("%s: invalid fd", f + 8);
return ((struct stat *)0);
}
@@ -185,8 +181,7 @@ char *f;
}
static int
printfinfo(f)
char *f;
printfinfo(char *f)
{
struct stat *st;
@@ -195,15 +190,13 @@ char *f;
}
static int
getperm(m)
int m;
getperm(int m)
{
return (m & (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID));
}
static void
perms(m)
int m;
perms(int m)
{
char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */
int i;
@@ -246,8 +239,7 @@ int m;
}
static void
printmode(mode)
int mode;
printmode(int mode)
{
if (S_ISBLK(mode))
printf("S_IFBLK ");
@@ -272,8 +264,7 @@ int mode;
}
static int
printst(st)
struct stat *st;
printst(struct stat *st)
{
struct passwd *pw;
struct group *gr;
@@ -309,15 +300,14 @@ struct stat *st;
}
static int
printsome(f, flags)
char *f;
int flags;
printsome(char *f, int flags)
{
struct stat *st;
struct passwd *pw;
struct group *gr;
int p;
char *b;
intmax_t xtime;
st = getstat(f);
if (st == NULL)
@@ -325,20 +315,23 @@ int flags;
/* Print requested info */
if (flags & OPT_ATIME) {
xtime = st->st_atime;
if (flags & OPT_ASCII)
printf("%s", ctime(&st->st_atime));
else
printf("%ld\n", st->st_atime);
printf("%jd\n", xtime);
} else if (flags & OPT_MTIME) {
xtime = st->st_mtime;
if (flags & OPT_ASCII)
printf("%s", ctime(&st->st_mtime));
else
printf("%ld\n", st->st_mtime);
printf("%jd\n", xtime);
} else if (flags & OPT_CTIME) {
xtime = st->st_ctime;
if (flags & OPT_ASCII)
printf("%s", ctime(&st->st_ctime));
else
printf("%ld\n", st->st_ctime);
printf("%jd\n", xtime);
} else if (flags & OPT_DEV)
printf("%lu\n", (unsigned long)st->st_dev);
else if (flags & OPT_INO)
@@ -391,8 +384,7 @@ int flags;
#ifndef NOBUILTIN
int
finfo_builtin(list)
WORD_LIST *list;
finfo_builtin(WORD_LIST *list)
{
int c, r;
char **v;
@@ -447,34 +439,26 @@ struct builtin finfo_struct = {
#endif
#ifdef NOBUILTIN
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
# if defined (PREFER_VARARGS)
# include <varargs.h>
# endif
#endif
#include <stdarg.h>
char *this_command_name;
main(argc, argv)
int argc;
char **argv;
int
main(int argc, char **argv)
{
this_command_name = argv[0];
exit(finfo_main(argc, argv));
}
void
builtin_usage()
builtin_usage(void)
{
fprintf(stderr, "%s: usage: %s [-%s] [file ...]\n", prog, prog, OPTIONS);
}
#ifndef HAVE_STRERROR
char *
strerror(e)
int e;
strerror(int e)
{
static char ebuf[40];
extern int sys_nerr;
@@ -488,23 +472,20 @@ int e;
}
#endif
char *
xmalloc(s)
size_t s;
PTR_T
xmalloc(size_t s)
{
char *ret;
extern char *malloc();
ret = malloc(s);
if (ret)
return (ret);
fprintf(stderr, "%s: cannot malloc %d bytes\n", prog, s);
fprintf(stderr, "%s: cannot malloc %zu bytes\n", prog, s);
exit(1);
}
char *
base_pathname(p)
char *p;
base_pathname(char *p)
{
char *t;
@@ -514,9 +495,7 @@ char *p;
}
int
legal_number (string, result)
char *string;
long *result;
valid_number (char *string, long result)
{
int sign;
long value;
@@ -575,9 +554,7 @@ extern int optind;
extern char *optarg;
int
sh_getopt(c, v, o)
int c;
char **v, *o;
sh_getopt(int c, char **v, char *o)
{
int r;
@@ -587,43 +564,18 @@ char **v, *o;
return r;
}
#if defined (USE_VARARGS)
void
#if defined (PREFER_STDARG)
builtin_error (const char *format, ...)
#else
builtin_error (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
#endif
vfprintf (stderr, format, args);
va_end (args);
fprintf (stderr, "\n");
}
#else
void
builtin_error (format, arg1, arg2, arg3, arg4, arg5)
char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
{
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
fprintf (stderr, "\n");
fflush (stderr);
}
#endif /* !USE_VARARGS */
#endif
File diff suppressed because it is too large Load Diff
+78 -13
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
/* Copyright (C) 1991-2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
@@ -21,8 +21,6 @@
#include <unistd.h>
#include <errno.h>
#include <error.h>
#include <libintl.h>
#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -43,6 +41,11 @@ extern int errno;
#define VAL_SSIZE_MAX -1004
#define VAL_SIZE_MAX -1005
/* We don't want to collide with anything else. */
#ifndef _CS_PATH
#define _CS_PATH -1001
#endif
struct conf
{
const char *name;
@@ -120,7 +123,7 @@ static const struct conf vars[] =
#ifdef _SC_CHAR_MAX
{ "CHAR_MAX", _SC_CHAR_MAX, SYSCONF },
#else
{ "CHAR_BIT", CHAR_MAX, CONSTANT },
{ "CHAR_MAX", CHAR_MAX, CONSTANT },
#endif
#ifdef _SC_CHAR_MIN
{ "CHAR_MIN", _SC_CHAR_MIN, SYSCONF },
@@ -269,9 +272,15 @@ static const struct conf vars[] =
#ifdef _SC_AVPHYS_PAGES
{ "_AVPHYS_PAGES", _SC_AVPHYS_PAGES, SYSCONF },
#endif
#ifdef _SC_NPROCESSORS_CONF
{ "_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF, SYSCONF },
#endif
#ifdef _SC_NPROCESSORS_ONLN
{ "_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN, SYSCONF },
#endif
#ifdef _SC_PHYS_PAGES
{ "_PHYS_PAGES", _SC_PHYS_PAGES, SYSCONF },
#endif
#ifdef _SC_ARG_MAX
{ "_POSIX_ARG_MAX", _SC_ARG_MAX, SYSCONF },
#else
@@ -329,7 +338,9 @@ static const struct conf vars[] =
{ "_POSIX_PRIORITIZED_IO", _SC_PRIORITIZED_IO, SYSCONF },
#endif
{ "_POSIX_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING, SYSCONF },
#ifdef _SC_REALTIME_SIGNALS
{ "_POSIX_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS, SYSCONF },
#endif
{ "_POSIX_SAVED_IDS", _SC_SAVED_IDS, SYSCONF },
#ifdef _SC_SELECT
{ "_POSIX_SELECT", _SC_SELECT, SYSCONF },
@@ -366,7 +377,9 @@ static const struct conf vars[] =
{ "_POSIX_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED, SYSCONF },
{ "_POSIX_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS, SYSCONF },
{ "_POSIX_TIMERS", _SC_TIMERS, SYSCONF },
#ifdef _SC_TIMER_MAX
{ "TIMER_MAX", _SC_TIMER_MAX, SYSCONF },
#endif
#ifdef _POSIX_TZNAME_MAX
{ "_POSIX_TZNAME_MAX", _SC_TZNAME_MAX, SYSCONF },
#else
@@ -743,8 +756,12 @@ static const struct conf vars[] =
{ "_POSIX_C_LANG_SUPPORT_R", _SC_C_LANG_SUPPORT_R, SYSCONF },
#endif
{ "_POSIX_CLOCK_SELECTION", _SC_CLOCK_SELECTION, SYSCONF },
#ifdef _SC_CPUTIME
{ "_POSIX_CPUTIME", _SC_CPUTIME, SYSCONF },
#endif
#ifdef _SC_THREAD_CPUTIME
{ "_POSIX_THREAD_CPUTIME", _SC_THREAD_CPUTIME, SYSCONF },
#endif
#ifdef _SC_DEVICE_SPECIFIC
{ "_POSIX_DEVICE_SPECIFIC", _SC_DEVICE_SPECIFIC, SYSCONF },
#endif
@@ -826,7 +843,9 @@ static const struct conf vars[] =
#ifdef _SC_AIO_PRIO_DELTA_MAX
{ "AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX, SYSCONF },
#endif
#ifdef _SC_DELAYTIMER_MAX
{ "DELAYTIMER_MAX", _SC_DELAYTIMER_MAX, SYSCONF },
#endif
{ "HOST_NAME_MAX", _SC_HOST_NAME_MAX, SYSCONF },
{ "LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX, SYSCONF },
{ "MQ_OPEN_MAX", _SC_MQ_OPEN_MAX, SYSCONF },
@@ -846,15 +865,21 @@ static const struct conf vars[] =
#ifdef _SC_TRACE_LOG
{ "_POSIX_TRACE_LOG", _SC_TRACE_LOG, SYSCONF },
#endif
#ifdef _SC_RTSIG_MAX
{ "RTSIG_MAX", _SC_RTSIG_MAX, SYSCONF },
#endif
#ifdef _SC_SEM_NSEMS_MAX
{ "SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX, SYSCONF },
#endif
#ifdef _SC_SEM_VALUE_MAX
{ "SEM_VALUE_MAX", _SC_SEM_VALUE_MAX, SYSCONF },
#endif
#ifdef _SC_SIGQUEUE_MAX
{ "SIGQUEUE_MAX", _SC_SIGQUEUE_MAX, SYSCONF },
#endif
#ifdef _PC_FILESIZEBITS
{ "FILESIZEBITS", _PC_FILESIZEBITS, PATHCONF },
#endif
#ifdef _PC_ALLOC_SIZE_MIN
{ "POSIX_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN, PATHCONF },
#endif
@@ -870,7 +895,9 @@ static const struct conf vars[] =
#ifdef _PC_REC_XFER_ALIGN
{ "POSIX_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN, PATHCONF },
#endif
#ifdef _PC_SYMLINK_MAX
{ "SYMLINK_MAX", _PC_SYMLINK_MAX, PATHCONF },
#endif
#ifdef _PC_2_SYMLINKS
{ "POSIX2_SYMLINKS", _PC_2_SYMLINKS, PATHCONF },
#endif
@@ -912,10 +939,35 @@ static const struct conf vars[] =
};
static int getconf_print (const struct conf *, const char *, int);
static int getconf_all (void);
static int getconf_all (WORD_LIST *);
static int getconf_one (WORD_LIST *);
static int getconf_internal (const struct conf *, int);
#ifndef HAVE_CONFSTR
/* If we don't have confstr, this will only support `getconf PATH'. */
static size_t
confstr (int name, char *buf, size_t len)
{
char *p;
size_t n;
switch (name)
{
case _CS_PATH:
p = conf_standard_path ();
n = STRLEN (p) + 1;
if (len != 0 && buf != 0)
strlcpy (buf, p, len);
free (p);
return n;
default:
errno = EINVAL;
return 0;
}
}
#endif /* !HAVE_CONFSTR */
static int
getconf_internal (const struct conf *c, int all)
{
@@ -981,17 +1033,24 @@ getconf_internal (const struct conf *c, int all)
}
static int
getconf_all (void)
getconf_all (WORD_LIST *list)
{
const struct conf *c;
char *path;
int r;
r = EXECUTION_SUCCESS;
path = list ? list->word->word : "/";
for (c = vars; c->name != NULL; ++c)
{
printf("%-35s", c->name);
path = "/"; /* XXX for now */
#if 0
if (c->call == PATHCONF && path == 0)
continue; /* Don't print pathconf vars if no path supplied */
if (c->call != PATHCONF && path)
continue; /* Only print pathconf vars if path supplied */
#endif
/* The output format for getconf -a is required by POSIX interp 1808 */
printf("%s: ", c->name);
if (getconf_print (c, path, 1) == EXECUTION_FAILURE)
r = EXECUTION_FAILURE;
}
@@ -1019,12 +1078,12 @@ getconf_one (WORD_LIST *list)
return (EXECUTION_FAILURE);
}
if (c->call_name == PATHCONF && list->next == 0)
if (c->call == PATHCONF && list->next == 0)
{
builtin_usage ();
return (EX_USAGE);
}
else if (c->call_name != PATHCONF && list->next)
else if (c->call != PATHCONF && list->next)
{
builtin_usage ();
return (EX_USAGE);
@@ -1135,13 +1194,19 @@ getconf_builtin (WORD_LIST *list)
}
list = loptend;
if ((aflag == 0 && list == 0) || (aflag && list) || list_length(list) > 2)
if ((aflag == 0 && list == 0) || (list && list_length((GENERIC_LIST *)list) > 2))
{
builtin_usage();
return (EX_USAGE);
}
else if (aflag && list && (list->word == 0 || list->word->word == 0 || *list->word->word == 0))
{
/* No null pathnames with -a */
builtin_usage();
return (EX_USAGE);
}
r = aflag ? getconf_all () : getconf_one (list);
r = aflag ? getconf_all (list) : getconf_one (list);
return r;
}
@@ -1158,6 +1223,6 @@ struct builtin getconf_struct = {
getconf_builtin,
BUILTIN_ENABLED,
getconf_doc,
"getconf -[ah] or getconf [-v spec] sysvar or getconf [-v spec] pathvar pathname",
"getconf -[ah] [file] or getconf [-v spec] sysvar or getconf [-v spec] pathvar pathname",
0
};
-8
View File
@@ -125,12 +125,4 @@
# define WORD_BIT (sizeof (int) * CHAR_BIT)
#endif
#if !defined (PRIdMAX)
# if HAVE_LONG_LONG
# define PRIdMAX "lld"
# else
# define PRIdMAX "ld"
# endif
#endif
#endif /* _GETCONF_H */
+3 -7
View File
@@ -46,8 +46,7 @@ extern int errno;
#endif
static void
munge_list (list)
WORD_LIST *list;
munge_list (WORD_LIST *list)
{
WORD_LIST *l, *nl;
WORD_DESC *wd;
@@ -69,9 +68,7 @@ munge_list (list)
}
static int
file_head (fp, cnt)
FILE *fp;
int cnt;
file_head (FILE *fp, int cnt)
{
int ch;
@@ -94,8 +91,7 @@ file_head (fp, cnt)
}
int
head_builtin (list)
WORD_LIST *list;
head_builtin (WORD_LIST *list)
{
int nline, opt, rval;
WORD_LIST *l;
+4 -7
View File
@@ -4,7 +4,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -48,8 +48,7 @@
A builtin command returns EXECUTION_SUCCESS for success and
EXECUTION_FAILURE to indicate failure. */
int
hello_builtin (list)
WORD_LIST *list;
hello_builtin (WORD_LIST *list)
{
printf("hello world\n");
fflush (stdout);
@@ -57,8 +56,7 @@ hello_builtin (list)
}
int
hello_builtin_load (s)
char *s;
hello_builtin_load (char *s)
{
printf ("hello builtin loaded\n");
fflush (stdout);
@@ -66,8 +64,7 @@ hello_builtin_load (s)
}
void
hello_builtin_unload (s)
char *s;
hello_builtin_unload (char *s)
{
printf ("hello builtin unloaded\n");
fflush (stdout);
+14 -20
View File
@@ -10,7 +10,7 @@
*/
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -41,9 +41,9 @@
#endif
#if !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid ();
extern struct passwd *getpwuid (uid_t);
#endif
extern struct group *getgrgid ();
extern struct group *getgrgid (gid_t);
#include "shell.h"
#include "builtins.h"
@@ -66,16 +66,15 @@ static gid_t rgid, egid;
static char *id_user;
static int inituser ();
static int inituser (char *);
static int id_pruser ();
static int id_prgrp ();
static int id_prgroups ();
static int id_prall ();
static int id_pruser (int);
static int id_prgrp (int);
static int id_prgroups (char *);
static int id_prall (char *);
int
id_builtin (list)
WORD_LIST *list;
id_builtin (WORD_LIST *list)
{
int opt;
char *user;
@@ -134,8 +133,7 @@ id_builtin (list)
}
static int
inituser (uname)
char *uname;
inituser (char *uname)
{
struct passwd *pwd;
@@ -162,8 +160,7 @@ inituser (uname)
/* Print the name or value of user ID UID. */
static int
id_pruser (uid)
int uid;
id_pruser (int uid)
{
struct passwd *pwd = NULL;
int r;
@@ -186,8 +183,7 @@ id_pruser (uid)
/* Print the name or value of group ID GID. */
static int
id_prgrp (gid)
int gid;
id_prgrp (int gid)
{
struct group *grp = NULL;
int r;
@@ -209,8 +205,7 @@ id_prgrp (gid)
}
static int
id_prgroups (uname)
char *uname;
id_prgroups (char *uname)
{
int *glist, ng, i, r;
@@ -243,8 +238,7 @@ id_prgroups (uname)
}
static int
id_prall (uname)
char *uname;
id_prall (char *uname)
{
int r, i, ng, *glist;
struct passwd *pwd;
+244
View File
@@ -0,0 +1,244 @@
/* kv - process a series of lines containing key-value pairs and assign them
to an associative array. */
/*
Copyright (C) 2023 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* See Makefile for compilation details. */
#include <config.h>
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include "posixstat.h"
#include <stdio.h>
#include <errno.h>
#include "loadables.h"
#ifndef errno
extern int errno;
#endif
#if defined (ARRAY_VARS)
#define KV_ARRAY_DEFAULT "KV"
/* Split LINE into a key and value, with the delimiter between the key and
value being a member of DSTRING. A sequence of one or more delimiters
separates the key and value. Assign to associative array KV as if
KV[key]=value without expansion. This does not treat single or double
quotes specially, nor does it remove whitespace at the beginning or end
of LINE. */
static int
kvsplit (SHELL_VAR *v, char *line, char *dstring)
{
char *key, *value;
size_t ind;
key = line;
value = 0;
ind = (line && *line) ? strcspn (key, dstring) : 0;
/* blank line or line starting with delimiter */
if (ind == 0 || *key == 0)
return 0;
if (key[ind])
{
key[ind++] = '\0';
value = key + ind;
/* skip until non-delim; this allows things like key1 = value1 where delims = " =" */
ind = strspn (value, dstring);
value += ind;
}
else
value = "";
return (bind_assoc_variable (v, name_cell (v), savestring (key), value, 0) != 0);
}
int
kvfile (SHELL_VAR *v, int fd, char *delims, char *rs)
{
ssize_t n;
char *line;
size_t llen;
int unbuffered_read, nr;
struct stat sb;
nr = 0;
#ifndef __CYGWIN__
/* We probably don't need to worry about setting this at all; we're not
seeking back and forth yet. */
if (*rs == '\n')
unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
else
unbuffered_read = (fstat (fd, &sb) != 0) || (S_ISREG (sb.st_mode) == 0);
#else
unbuffered_read = 1;
#endif
line = 0;
llen = 0;
zreset ();
while ((n = zgetline (fd, &line, &llen, *rs, unbuffered_read)) != -1)
{
QUIT;
if (line[n] == *rs)
line[n] = '\0'; /* value doesn't include the record separator */
nr += kvsplit (v, line, delims);
free (line);
line = 0;
llen = 0;
}
QUIT;
return nr;
}
#endif
int
kv_builtin (WORD_LIST *list)
{
#if defined (ARRAY_VARS)
int opt, rval, free_delims;
char *array_name, *delims, *rs;
SHELL_VAR *v;
array_name = delims = rs = 0;
rval = EXECUTION_SUCCESS;
free_delims = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "A:s:d:")) != -1)
{
switch (opt)
{
case 'A':
array_name = list_optarg;
break;
case 's':
delims = list_optarg;
break;
case 'd':
rs = list_optarg;
break;
CASE_HELPOPT;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list)
{
builtin_error ("too many arguments");
builtin_usage ();
return (EX_USAGE);
}
if (array_name == 0)
array_name = KV_ARRAY_DEFAULT;
if (valid_identifier (array_name) == 0)
{
sh_invalidid (array_name);
return (EXECUTION_FAILURE);
}
if (delims == 0)
{
delims = getifs ();
free_delims = 1;
}
if (rs == 0)
rs = "\n";
v = find_or_make_array_variable (array_name, 3);
if (v == 0 || readonly_p (v) || noassign_p (v))
{
if (v && readonly_p (v))
err_readonly (array_name);
return (EXECUTION_FAILURE);
}
else if (assoc_p (v) == 0)
{
builtin_error ("%s: not an associative array", array_name);
return (EXECUTION_FAILURE);
}
if (invisible_p (v))
VUNSETATTR (v, att_invisible);
assoc_flush (assoc_cell (v));
rval = kvfile (v, 0, delims, rs);
if (free_delims)
free (delims); /* getifs returns allocated memory */
return (rval > 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
#else
builtin_error ("arrays not available");
return (EXECUTION_FAILURE);
#endif
}
/* Called when builtin is enabled and loaded from the shared object. If this
function returns 0, the load fails. */
int
kv_builtin_load (char *name)
{
return (1);
}
/* Called when builtin is disabled. */
void
kv_builtin_unload (char *name)
{
}
char *kv_doc[] = {
"Read key-value pairs into an associative array.",
"",
"Read delimiter-terminated records composed of a single key-value pair",
"from the standard input and add the key and corresponding value",
"to the associative array ARRAYNAME. The key and value are separated",
"by a sequence of one or more characters in SEPARATORS. Records are",
"terminated by the first character of RS, similar to the read and",
"mapfile builtins.",
"",
"If SEPARATORS is not supplied, $IFS is used to separate the keys",
"and values. If RS is not supplied, newlines terminate records.",
"If ARRAYNAME is not supplied, \"KV\" is the default array name.",
"",
"Returns success if at least one key-value pair is stored in ARRAYNAME.",
(char *)NULL
};
struct builtin kv_struct = {
"kv", /* builtin name */
kv_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
kv_doc, /* array of long documentation strings. */
"kv [-A ARRAYNAME] [-s SEPARATORS] [-d RS]", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
+8 -10
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2020 Free Software Foundation, Inc.
Copyright (C) 1999-2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -42,18 +42,19 @@
extern int errno;
#endif
typedef int unix_link_syscall_t PARAMS((const char *, const char *));
typedef int unix_link_syscall_t (const char *, const char *);
#define LN_SYMLINK 0x01
#define LN_UNLINK 0x02
#define LN_NOFOLLOW 0x04
static unix_link_syscall_t *linkfn;
static int dolink ();
static char *mkdirpath (char *, char *);
static int dolink (char *, char *, int);
int
ln_builtin (list)
WORD_LIST *list;
ln_builtin (WORD_LIST *list)
{
int rval, opt, flags;
WORD_LIST *l;
@@ -125,8 +126,7 @@ ln_builtin (list)
}
static char *
mkdirpath (dir, file)
char *dir, *file;
mkdirpath (char *dir, char *file)
{
int dlen, flen;
char *ret;
@@ -152,9 +152,7 @@ mkdirpath (dir, file)
#endif
static int
dolink (src, dst, flags)
char *src, *dst;
int flags;
dolink (char *src, char *dst, int flags)
{
struct stat ssb, dsb;
int exists;
+2 -3
View File
@@ -1,7 +1,7 @@
/* logname - print login name of current user */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -36,8 +36,7 @@ extern int errno;
#endif
int
logname_builtin (list)
WORD_LIST *list;
logname_builtin (WORD_LIST *list)
{
char *np;
+54 -40
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022-2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -42,15 +42,14 @@ extern int errno;
#define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
extern int parse_symbolic_mode ();
extern int parse_symbolic_mode (char *, mode_t);
static int make_path ();
static int make_path (char *, int, int, int);
static int original_umask;
int
mkdir_builtin (list)
WORD_LIST *list;
mkdir_builtin (WORD_LIST *list)
{
int opt, pflag, mflag, omode, rval, nmode, parent_mode;
char *mode;
@@ -134,15 +133,14 @@ mkdir_builtin (list)
this changes the process's umask; make sure that all paths leading to a
return reset it to ORIGINAL_UMASK */
static int
make_path (path, user_mode, nmode, parent_mode)
char *path;
int user_mode;
int nmode, parent_mode;
make_path (char *path, int user_mode, int nmode, int parent_mode)
{
int oumask;
mode_t oumask;
struct stat sb;
char *p, *npath;
int tail;
/* If we don't have to do any work, don't do any work. */
if (stat (path, &sb) == 0)
{
if (S_ISDIR (sb.st_mode) == 0)
@@ -170,48 +168,64 @@ make_path (path, user_mode, nmode, parent_mode)
while (*p == '/')
p++;
while (p = strchr (p, '/'))
tail = 0;
while (tail == 0)
{
*p = '\0';
if (stat (npath, &sb) != 0)
if (*p == '\0')
tail = 1;
else
p = strchr (p, '/');
if (p)
*p = '\0';
else
tail = 1;
if (mkdir (npath, 0) < 0)
{
if (mkdir (npath, 0))
/* "Each dir operand that names an existing directory shall be
ignored without error." */
if (errno == EEXIST || errno == EISDIR)
{
int e = errno;
int fail = 0;
if (stat (npath, &sb) != 0)
{
fail = 1;
builtin_error ("cannot create directory `%s': %s", npath, strerror (e));
}
else if (e == EEXIST && S_ISDIR (sb.st_mode) == 0)
{
fail = 1;
builtin_error ("`%s': file exists but is not a directory", npath);
}
if (fail)
{
umask (original_umask);
free (npath);
return 1;
}
}
else
{
builtin_error ("cannot create directory `%s': %s", npath, strerror (errno));
umask (original_umask);
free (npath);
return 1;
}
if (chmod (npath, parent_mode) != 0)
{
builtin_error ("cannot chmod directory `%s': %s", npath, strerror (errno));
umask (original_umask);
free (npath);
return 1;
}
}
else if (S_ISDIR (sb.st_mode) == 0)
{
builtin_error ("`%s': file exists but is not a directory", npath);
umask (original_umask);
free (npath);
return 1;
}
*p++ = '/'; /* restore slash */
while (*p == '/')
if (chmod (npath, (tail == 0) ? parent_mode : nmode) != 0)
{
builtin_error ("cannot chmod directory `%s': %s", npath, strerror (errno));
umask (original_umask);
free (npath);
return 1;
}
if (tail == 0)
*p++ = '/'; /* restore slash */
while (p && *p == '/') /* skip consecutive slashes or trailing slash */
p++;
}
/* Create the final directory component. */
if (stat (npath, &sb) && mkdir (npath, nmode))
{
builtin_error ("cannot create directory `%s': %s", npath, strerror (errno));
umask (original_umask);
free (npath);
return 1;
}
umask (original_umask);
free (npath);
return 0;
+3 -4
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2020 Free Software Foundation, Inc.
Copyright (C) 1999-2020,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -42,13 +42,12 @@ extern int errno;
#define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
extern int parse_symbolic_mode ();
extern int parse_symbolic_mode (char *, mode_t);
static int original_umask;
int
mkfifo_builtin (list)
WORD_LIST *list;
mkfifo_builtin (WORD_LIST *list)
{
int opt, mflag, omode, rval, nmode, basemode;
char *mode;
+3 -4
View File
@@ -1,7 +1,7 @@
/* mktemp - create temporary file or directory */
/*
Copyright (C) 2019 Free Software Foundation, Inc.
Copyright (C) 2019,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -32,8 +32,7 @@
#define DEFAULT_PREFIX "shtmp"
int
mktemp_builtin (list)
WORD_LIST *list;
mktemp_builtin (WORD_LIST *list)
{
WORD_LIST *l;
int rval, opt, fd, mflags, base_mflags;
@@ -76,7 +75,7 @@ mktemp_builtin (list)
if (varname) /* check for validity, not readonly */
{
if (legal_identifier (varname) == 0)
if (valid_identifier (varname) == 0)
{
if (qflag == 0)
sh_invalidid (varname);
+1 -5
View File
@@ -32,11 +32,7 @@
while (0)
static SHELL_VAR *
assign_mypid (
SHELL_VAR *self,
char *value,
arrayind_t unused,
char *key )
assign_mypid (SHELL_VAR *self, char *value, arrayind_t unused, char *key)
{
return (self);
}
+4 -4
View File
@@ -4,7 +4,7 @@
existing builtin. */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -20,14 +20,14 @@
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include "builtins.h"
#include "shell.h"
#include <stdio.h>
int
necho_builtin (list)
WORD_LIST *list;
necho_builtin (WORD_LIST *list)
{
print_word_list (list, " ");
printf("\n");
+616
View File
@@ -0,0 +1,616 @@
/* cut,lcut - extract specified fields from a line and assign them to an array
or print them to the standard output */
/*
Copyright (C) 2020,2022,2023 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* See Makefile for compilation details. */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include "loadables.h"
#include "shmbutil.h"
#define CUT_ARRAY_DEFAULT "CUTFIELDS"
#define NOPOS -2 /* sentinel for unset startpos/endpos */
#define BOL 0
#define EOL INT_MAX
#define NORANGE -1 /* just a position, no range */
#define BFLAG (1 << 0)
#define CFLAG (1 << 1)
#define DFLAG (1 << 2)
#define FFLAG (1 << 3)
#define SFLAG (1 << 4)
struct cutpos
{
int startpos, endpos; /* zero-based, correction done in getlist() */
};
struct cutop
{
int flags;
int delim;
int npos;
struct cutpos *poslist;
};
static int
poscmp (const void *a, const void *b)
{
struct cutpos *p1, *p2;
p1 = (struct cutpos *)a;
p2 = (struct cutpos *)b;
return (p1->startpos - p2->startpos);
}
static int
getlist (char *arg, struct cutpos **opp)
{
char *ntok, *ltok, *larg;
int s, e;
intmax_t num;
struct cutpos *poslist;
int npos, nsize;
poslist = 0;
nsize = npos = 0;
s = e = 0;
larg = arg;
while (ltok = strsep (&larg, ","))
{
if (*ltok == 0)
continue;
ntok = strsep (&ltok, "-");
if (*ntok == 0)
s = BOL;
else
{
if (valid_number (ntok, &num) == 0 || (int)num != num || num <= 0)
{
builtin_error ("%s: invalid list value", ntok);
*opp = poslist;
return -1;
}
s = num;
s--; /* fields are 1-based */
}
if (ltok == 0)
e = NORANGE;
else if (*ltok == 0)
e = EOL;
else
{
if (valid_number (ltok, &num) == 0 || (int)num != num || num <= 0)
{
builtin_error ("%s: invalid list value", ltok);
*opp = poslist;
return -1;
}
e = num;
e--;
if (e == s)
e = NORANGE;
}
if (npos == nsize)
{
nsize += 4;
poslist = (struct cutpos *)xrealloc (poslist, nsize * sizeof (struct cutpos));
}
poslist[npos].startpos = s;
poslist[npos].endpos = e;
npos++;
}
if (npos == 0)
{
builtin_error ("missing list of positions");
*opp = poslist;
return -1;
}
qsort (poslist, npos, sizeof(poslist[0]), poscmp);
*opp = poslist;
return npos;
}
static int
cutbytes (SHELL_VAR *v, char *line, struct cutop *ops)
{
arrayind_t ind;
char *buf, *bmap;
size_t llen;
int i, b, n, s, e;
llen = strlen (line);
buf = xmalloc (llen + 1);
bmap = xmalloc (llen + 1);
memset (bmap, 0, llen);
for (n = 0; n < ops->npos; n++)
{
s = ops->poslist[n].startpos; /* no translation needed yet */
e = ops->poslist[n].endpos;
if (e == NORANGE)
e = s;
else if (e == EOL || e >= llen)
e = llen - 1;
/* even if a column is specified multiple times, it will only be printed
once */
for (i = s; i <= e; i++)
bmap[i] = 1;
}
b = 0;
for (i = 0; i < llen; i++)
if (bmap[i])
buf[b++] = line[i];
buf[b] = 0;
if (v)
{
ind = 0;
#if defined (ARRAY_VARS)
bind_array_element (v, ind, buf, 0);
#endif
ind++;
}
else
printf ("%s\n", buf);
free (buf);
free (bmap);
return ind;
}
static int
cutchars (SHELL_VAR *v, char *line, struct cutop *ops)
{
arrayind_t ind;
char *buf, *bmap;
wchar_t *wbuf, *wb2;
size_t llen, wlen;
int i, b, n, s, e;
if (MB_CUR_MAX == 1)
return (cutbytes (v, line, ops));
if (locale_utf8locale && utf8_mbsmbchar (line) == 0)
return (cutbytes (v, line, ops));
llen = strlen (line);
wbuf = (wchar_t *)xmalloc ((llen + 1) * sizeof (wchar_t));
wlen = mbstowcs (wbuf, line, llen);
if (MB_INVALIDCH (wlen))
{
free (wbuf);
return (cutbytes (v, line, ops));
}
bmap = xmalloc (llen + 1);
memset (bmap, 0, llen);
for (n = 0; n < ops->npos; n++)
{
s = ops->poslist[n].startpos; /* no translation needed yet */
e = ops->poslist[n].endpos;
if (e == NORANGE)
e = s;
else if (e == EOL || e >= wlen)
e = wlen - 1;
/* even if a column is specified multiple times, it will only be printed
once */
for (i = s; i <= e; i++)
bmap[i] = 1;
}
wb2 = (wchar_t *)xmalloc ((wlen + 1) * sizeof (wchar_t));
b = 0;
for (i = 0; i < wlen; i++)
if (bmap[i])
wb2[b++] = wbuf[i];
wb2[b] = 0;
free (wbuf);
buf = bmap;
n = wcstombs (buf, wb2, llen);
if (v)
{
ind = 0;
#if defined (ARRAY_VARS)
bind_array_element (v, ind, buf, 0);
#endif
ind++;
}
else
printf ("%s\n", buf);
free (buf);
free (wb2);
return ind;
}
/* The basic strategy is to cut the line into fields using strsep, populate
an array of fields from 0..nf, then select those fields using the same
bitmap approach as cut{bytes,chars} and assign them to the array variable
V or print them on stdout. This function obeys SFLAG. */
static int
cutfields (SHELL_VAR *v, char *line, struct cutop *ops)
{
arrayind_t ind;
char *buf, *bmap, *field, **fields, delim[2];
size_t llen, fsize;
int i, b, n, s, e, nf;
ind = 0;
delim[0] = ops->delim;
delim[1] = '\0';
fields = 0;
nf = 0;
fsize = 0;
field = buf = line;
do
{
field = strsep (&buf, delim); /* destructive */
if (nf == fsize)
{
fsize += 8;
fields = xrealloc (fields, fsize * sizeof (char *));
}
fields[nf] = field;
if (field)
nf++;
}
while (field);
if (nf == 1)
{
free (fields);
if (ops->flags & SFLAG)
return ind;
if (v)
{
#if defined (ARRAY_VARS)
bind_array_element (v, ind, line, 0);
#endif
ind++;
}
else
printf ("%s\n", line);
return ind;
}
bmap = xmalloc (nf + 1);
memset (bmap, 0, nf);
for (n = 0; n < ops->npos; n++)
{
s = ops->poslist[n].startpos; /* no translation needed yet */
e = ops->poslist[n].endpos;
if (e == NORANGE)
e = s;
else if (e == EOL || e >= nf)
e = nf - 1;
/* even if a column is specified multiple times, it will only be printed
once */
for (i = s; i <= e; i++)
bmap[i] = 1;
}
for (i = 1, b = 0; b < nf; b++)
{
if (bmap[b] == 0)
continue;
#if defined (ARRAY_VARS)
if (v)
{
bind_array_element (v, ind, fields[b], 0);
ind++;
}
else
#endif
{
if (i == 0)
putchar (ops->delim);
printf ("%s", fields[b]);
}
i = 0;
}
if (v == 0)
putchar ('\n');
return nf;
}
static int
cutline (SHELL_VAR *v, char *line, struct cutop *ops)
{
int rval;
if (ops->flags & BFLAG)
rval = cutbytes (v, line, ops);
else if (ops->flags & CFLAG)
rval = cutchars (v, line, ops);
else
rval = cutfields (v, line, ops);
return (rval >= 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
static int
cutfile (SHELL_VAR *v, WORD_LIST *list, struct cutop *ops)
{
int fd, unbuffered_read;
char *line, *b;
size_t llen;
WORD_LIST *l;
ssize_t n;
line = 0;
llen = 0;
l = list;
do
{
/* for each file */
if (l == 0 || (l->word->word[0] == '-' && l->word->word[1] == '\0'))
fd = 0;
else
fd = open (l->word->word, O_RDONLY);
if (fd < 0)
{
file_error (l->word->word);
return (EXECUTION_FAILURE);
}
#ifndef __CYGWIN__
unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
#else
unbuffered_read = 1;
#endif
while ((n = zgetline (fd, &line, &llen, '\n', unbuffered_read)) != -1)
{
QUIT;
if (line[n] == '\n')
line[n] = '\0'; /* cutline expects no newline terminator */
cutline (v, line, ops); /* can modify line */
}
if (fd > 0)
close (fd);
QUIT;
if (l)
l = l->next;
}
while (l);
free (line);
return EXECUTION_SUCCESS;
}
#define OPTSET(x) ((cutflags & (x)) ? 1 : 0)
static int
cut_internal (int which, WORD_LIST *list)
{
int opt, rval, cutflags, delim, npos;
char *array_name, *cutstring, *list_arg;
SHELL_VAR *v;
struct cutop op;
struct cutpos *poslist;
v = 0;
rval = EXECUTION_SUCCESS;
cutflags = 0;
array_name = 0;
list_arg = 0;
delim = '\t';
reset_internal_getopt ();
while ((opt = internal_getopt (list, "a:b:c:d:f:sn")) != -1)
{
switch (opt)
{
case 'a':
#if defined (ARRAY_VARS)
array_name = list_optarg;
break;
#else
builtin_error ("arrays not available");
return (EX_USAGE);
#endif
case 'b':
cutflags |= BFLAG;
list_arg = list_optarg;
break;
case 'c':
cutflags |= CFLAG;
list_arg = list_optarg;
break;
case 'd':
cutflags |= DFLAG;
delim = list_optarg[0];
if (delim == 0 || list_optarg[1])
{
builtin_error ("delimiter must be a single non-null character");
return (EX_USAGE);
}
break;
case 'f':
cutflags |= FFLAG;
list_arg = list_optarg;
break;
case 'n':
break;
case 's':
cutflags |= SFLAG;
break;
CASE_HELPOPT;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (array_name && (valid_identifier (array_name) == 0))
{
sh_invalidid (array_name);
return (EXECUTION_FAILURE);
}
if (list == 0 && which == 0)
{
builtin_error ("string argument required");
return (EX_USAGE);
}
/* options are mutually exclusive and one is required */
if ((OPTSET (BFLAG) + OPTSET (CFLAG) + OPTSET (FFLAG)) != 1)
{
builtin_usage ();
return (EX_USAGE);
}
if ((npos = getlist (list_arg, &poslist)) < 0)
{
free (poslist);
return (EXECUTION_FAILURE);
}
#if defined (ARRAY_VARS)
if (array_name)
{
v = builtin_find_indexed_array (array_name, 1);
if (v == 0)
{
free (poslist);
return (EXECUTION_FAILURE);
}
}
#endif
op.flags = cutflags;
op.delim = delim;
op.npos = npos;
op.poslist = poslist;
/* we implement cut as a builtin with a cutfile() function that opens each
filename in LIST as a filename (or `-' for stdin) and runs cutline on
every line in the file. */
if (which == 0)
{
cutstring = list->word->word;
if (cutstring == 0 || *cutstring == 0)
{
free (poslist);
return (EXECUTION_SUCCESS);
}
rval = cutline (v, cutstring, &op);
}
else
rval = cutfile (v, list, &op);
free (poslist);
return (rval);
}
int
lcut_builtin (WORD_LIST *list)
{
return (cut_internal (0, list));
}
int
cut_builtin (WORD_LIST *list)
{
return (cut_internal (1, list));
}
char *lcut_doc[] = {
"Extract selected fields from a string.",
"",
"Select portions of LINE (as specified by LIST) and assign them to",
"elements of the indexed array ARRAY starting at index 0, or write",
"them to the standard output if -a is not specified.",
"",
"Items specified by LIST are either column positions or fields delimited",
"by a special character, and are described more completely in cut(1).",
"",
"Columns correspond to bytes (-b), characters (-c), or fields (-f). The",
"field delimiter is specified by -d (default TAB). Column numbering",
"starts at 1.",
(char *)NULL
};
struct builtin lcut_struct = {
"lcut", /* builtin name */
lcut_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
lcut_doc, /* array of long documentation strings. */
"lcut [-a ARRAY] [-b LIST] [-c LIST] [-f LIST] [-d CHAR] [-sn] line", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
char *cut_doc[] = {
"Extract selected fields from each line of a file.",
"",
"Select portions of each line (as specified by LIST) from each FILE",
"and write them to the standard output. cut reads from the standard",
"input if no FILE arguments are specified or if a FILE argument is a",
"single hyphen.",
"",
"Items specified by LIST are either column positions or fields delimited",
"by a special character, and are described more completely in cut(1).",
"",
"Columns correspond to bytes (-b), characters (-c), or fields (-f). The",
"field delimiter is specified by -d (default TAB). Column numbering",
"starts at 1.",
(char *)NULL
};
struct builtin cut_struct = {
"cut", /* builtin name */
cut_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
cut_doc, /* array of long documentation strings. */
"cut [-a ARRAY] [-b LIST] [-c LIST] [-f LIST] [-d CHAR] [-sn] [file ...]", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
+9 -17
View File
@@ -23,7 +23,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022,2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -94,13 +94,12 @@ extern int errno;
# define NAME_MAX_FOR(p) NAME_MAX
#endif
extern char *strerror ();
extern char *strerror (int);
static int validate_path ();
static int validate_path (char *, int);
int
pathchk_builtin (list)
WORD_LIST *list;
pathchk_builtin (WORD_LIST *list)
{
int retval, pflag, opt;
@@ -185,8 +184,7 @@ static char const portable_chars[256] =
/* If PATH contains only portable characters, return 1, else 0. */
static int
portable_chars_only (path)
const char *path;
portable_chars_only (const char *path)
{
const char *p;
@@ -206,9 +204,7 @@ portable_chars_only (path)
#else
# define SAFE_STAT(name, buf) safe_stat (name, buf)
static inline int
safe_stat (name, buf)
const char *name;
struct stat *buf;
safe_stat (const char *name, struct stat *buf)
{
int ret;
@@ -224,8 +220,7 @@ safe_stat (name, buf)
2 if it doesn't exist. */
static int
dir_ok (path)
const char *path;
dir_ok (const char *path)
{
struct stat stats;
@@ -255,8 +250,7 @@ dir_ok (path)
}
static char *
xstrdup (s)
char *s;
xstrdup (char *s)
{
return (savestring (s));
}
@@ -276,9 +270,7 @@ xstrdup (s)
Return 0 if all of these tests are successful, 1 if any fail. */
static int
validate_path (path, portability)
char *path;
int portability;
validate_path (char *path, int portability)
{
int path_max;
int last_elem; /* Nonzero if checking last element of path. */
+7 -10
View File
@@ -3,7 +3,7 @@
*/
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022,2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -42,8 +42,8 @@
extern int errno;
#endif
int print_builtin ();
static int printargs ();
int print_builtin (WORD_LIST *);
static int printargs (WORD_LIST *, FILE *);
static FILE *ofp;
@@ -72,8 +72,7 @@ struct builtin print_struct = {
#endif
int
print_builtin (list)
WORD_LIST *list;
print_builtin (WORD_LIST *list)
{
int c, r, nflag, raw, ofd, sflag;
intmax_t lfd;
@@ -110,7 +109,7 @@ print_builtin (list)
case 'p':
break; /* NOP */
case 'u':
if (all_digits (list_optarg) && legal_number (list_optarg, &lfd) && lfd == (int)lfd)
if (all_digits (list_optarg) && valid_number (list_optarg, &lfd) && lfd == (int)lfd)
ofd = lfd;
else
{
@@ -170,9 +169,7 @@ opt_end:
}
static int
printargs (list, ofp)
WORD_LIST *list;
FILE *ofp;
printargs (WORD_LIST *list, FILE *ofp)
{
WORD_LIST *l;
char *ostr;
@@ -180,7 +177,7 @@ printargs (list, ofp)
for (sawc = 0, l = list; l; l = l->next)
{
ostr = ansicstr (l->word->word, strlen (l->word->word), 0, &sawc, (int *)0);
ostr = ansicstr (l->word->word, strlen (l->word->word), 0, &sawc, 0);
if (ostr)
fprintf (ofp, "%s", ostr);
free (ostr);
+2 -3
View File
@@ -6,7 +6,7 @@
*/
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009, 2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -34,8 +34,7 @@
extern char **export_env;
int
printenv_builtin (list)
WORD_LIST *list;
printenv_builtin (WORD_LIST *list)
{
register char **envp;
int opt;
+2 -3
View File
@@ -4,7 +4,7 @@
*/
/*
Copyright (C) 1999-2020 Free Software Foundation, Inc.
Copyright (C) 1999-2020,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -39,8 +39,7 @@ extern pid_t dollar_dollar_pid;
extern int last_command_exit_value;
int
push_builtin (list)
WORD_LIST *list;
push_builtin (WORD_LIST *list)
{
pid_t pid;
int xstatus, opt;
+5 -3
View File
@@ -22,7 +22,7 @@
*/
/*
Copyright (C) 1999-2009,2021,2022 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2021,2022,2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -61,7 +61,7 @@
extern int errno;
#endif
extern char *sh_realpath();
extern char *sh_realpath(const char *, char *);
int
realpath_builtin(WORD_LIST *list)
@@ -122,7 +122,7 @@ realpath_builtin(WORD_LIST *list)
}
#if defined (ARRAY_VARS)
if (aflag && legal_identifier (aname) == 0) {
if (aflag && valid_identifier (aname) == 0) {
sh_invalidid(aname);
return (EXECUTION_FAILURE);
}
@@ -165,10 +165,12 @@ realpath_builtin(WORD_LIST *list)
builtin_error("%s: %s", p, strerror(errno));
continue;
}
#if defined (ARRAY_VARS)
if (aflag) {
bind_array_element (v, ind, r, 0);
ind++;
}
#endif
if (qflag == 0) {
if (vflag)
printf ("%s -> ", p);
+2 -3
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 2016 Free Software Foundation, Inc.
Copyright (C) 2016,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -114,8 +114,7 @@ rm_file(const char *fname)
}
int
rm_builtin (list)
WORD_LIST *list;
rm_builtin (WORD_LIST *list)
{
const char *name;
WORD_LIST *l;
+2 -3
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -33,8 +33,7 @@ extern int errno;
#endif
int
rmdir_builtin (list)
WORD_LIST *list;
rmdir_builtin (WORD_LIST *list)
{
int rval;
WORD_LIST *l;
+10 -30
View File
@@ -1,5 +1,5 @@
/* seq - print sequence of numbers to standard output.
Copyright (C) 2018-2020 Free Software Foundation, Inc.
Copyright (C) 2018-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,18 +35,6 @@
extern int errno;
#endif
#if defined (PRI_MACROS_BROKEN)
# undef PRIdMAX
#endif
#if !defined (PRIdMAX)
# if HAVE_LONG_LONG
# define PRIdMAX "lld"
# else
# define PRIdMAX "ld"
# endif
#endif
#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
typedef long double floatmax_t;
# define FLOATMAX_CONV "L"
@@ -61,8 +49,8 @@ typedef double floatmax_t;
# define FLOATMAX_FMT "%g"
# define FLOATMAX_WFMT "%0.f"
#endif
static floatmax_t getfloatmax PARAMS((const char *));
static char *genformat PARAMS((floatmax_t, floatmax_t, floatmax_t));
static floatmax_t getfloatmax (const char *);
static char *genformat (floatmax_t, floatmax_t, floatmax_t);
#define MAX(a, b) (((a) < (b))? (b) : (a))
@@ -81,8 +69,7 @@ static char decimal_point;
/* Pretty much the same as the version in builtins/printf.def */
static floatmax_t
getfloatmax (arg)
const char *arg;
getfloatmax (const char *arg)
{
floatmax_t ret;
char *ep;
@@ -181,8 +168,7 @@ long_double_format (char const *fmt)
/* Return the number of digits following the decimal point in NUMBUF */
static int
getprec (numbuf)
const char *numbuf;
getprec (const char *numbuf)
{
int p;
char *dp;
@@ -196,8 +182,7 @@ getprec (numbuf)
/* Return the default format given FIRST, INCR, and LAST. */
static char *
genformat (first, incr, last)
floatmax_t first, incr, last;
genformat (floatmax_t first, floatmax_t incr, floatmax_t last)
{
static char buf[6 + 2 * INT_STRLEN_BOUND (int)];
int wfirst, wlast, width;
@@ -242,9 +227,7 @@ genformat (first, incr, last)
}
int
print_fltseq (fmt, first, last, incr)
const char *fmt;
floatmax_t first, last, incr;
print_fltseq (const char *fmt, floatmax_t first, floatmax_t last, floatmax_t incr)
{
int n;
floatmax_t next;
@@ -270,8 +253,7 @@ print_fltseq (fmt, first, last, incr)
/* must be <= INT_STRLEN_BOUND(intmax_t) */
int
width_needed (num)
intmax_t num;
width_needed (intmax_t num)
{
int ret;
@@ -285,8 +267,7 @@ width_needed (num)
}
int
print_intseq (ifirst, ilast, iincr)
intmax_t ifirst, ilast, iincr;
print_intseq (intmax_t ifirst, intmax_t ilast, intmax_t iincr)
{
char intwfmt[6 + INT_STRLEN_BOUND(int) + sizeof (PRIdMAX)];
const char *s;
@@ -323,8 +304,7 @@ print_intseq (ifirst, ilast, iincr)
}
int
seq_builtin (list)
WORD_LIST *list;
seq_builtin (WORD_LIST *list)
{
floatmax_t first, last, incr;
intmax_t ifirst, ilast, iincr;
+5 -4
View File
@@ -4,6 +4,8 @@
Originally contributed by Jason Vas Dias <jason.vas.dias@gmail.com>
Copyright (C) 2018-2023 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -42,8 +44,7 @@
#endif
int
setpgid_builtin (list)
WORD_LIST *list;
setpgid_builtin (WORD_LIST *list)
{
register WORD_LIST *wl;
intmax_t pid_arg, pgid_arg;
@@ -68,7 +69,7 @@ setpgid_builtin (list)
return (EX_USAGE);
}
if (legal_number (pidstr, &pid_arg) == 0)
if (valid_number (pidstr, &pid_arg) == 0)
{
builtin_error ("%s: pid argument must be numeric", pidstr);
return (EXECUTION_FAILURE);
@@ -80,7 +81,7 @@ setpgid_builtin (list)
}
pid = pid_arg;
if (legal_number (pgidstr, &pgid_arg) == 0)
if (valid_number (pgidstr, &pgid_arg) == 0)
{
builtin_error ("%s: pgrp argument must be numeric", pgidstr);
return (EXECUTION_FAILURE);
+3 -3
View File
@@ -7,7 +7,7 @@
*/
/*
Copyright (C) 1999-2021 Free Software Foundation, Inc.
Copyright (C) 1999-2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -135,6 +135,7 @@ sleep_builtin (WORD_LIST *list)
if (list->word && ISOPTION (list->word->word, '-'))
list = list->next;
/* Reject options and negative arguments */
if (*list->word->word == '-' || list->next) {
builtin_usage ();
return (EX_USAGE);
@@ -146,8 +147,7 @@ sleep_builtin (WORD_LIST *list)
*
* A heuristic: if the conversion failed, but the argument appears to
* contain a GNU-like interval specifier (e.g. "1m30s"), try to parse
* it. If we can't, return the right exit code to tell
* execute_builtin to try and execute a disk command instead.
* it. If we can't, it's an error.
*/
if (r == 0 && (strchr ("dhms", *ep) || strpbrk (list->word->word, "dhms")))
r = parse_gnutimefmt (list->word->word, &sec, &usec);
+23 -34
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 2016,2022 Free Software Foundation, Inc.
Copyright (C) 2016,2022-2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -46,6 +46,8 @@
extern int errno;
#endif
#if defined (ARRAY_VARS)
#define ST_NAME 0
#define ST_DEV 1
#define ST_INO 2
@@ -80,17 +82,14 @@ static char *arraysubs[] =
static char *stattime (time_t, const char *);
static int
getstat (fname, flags, sp)
const char *fname;
int flags;
struct stat *sp;
getstat (const char *fname, int flags, struct stat *sp)
{
intmax_t lfd;
int fd, r;
if (strncmp (fname, "/dev/fd/", 8) == 0)
{
if ((legal_number(fname + 8, &lfd) == 0) || (int)lfd != lfd)
if ((valid_number(fname + 8, &lfd) == 0) || (int)lfd != lfd)
{
errno = EINVAL;
return -1;
@@ -109,9 +108,7 @@ getstat (fname, flags, sp)
}
static char *
statlink (fname, sp)
char *fname;
struct stat *sp;
statlink (char *fname, struct stat *sp)
{
#if defined (HAVE_READLINK)
char linkbuf[PATH_MAX];
@@ -128,8 +125,7 @@ statlink (fname, sp)
}
static char *
octalperms (m)
int m;
octalperms (int m)
{
int operms;
char *ret;
@@ -170,8 +166,7 @@ octalperms (m)
}
static char *
statperms (m)
int m;
statperms (int m)
{
char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */
int i;
@@ -217,8 +212,7 @@ statperms (m)
}
static char *
statmode(mode)
int mode;
statmode(int mode)
{
char *modestr, *m;
@@ -260,9 +254,7 @@ statmode(mode)
}
static char *
stattime (t, timefmt)
time_t t;
const char *timefmt;
stattime (time_t t, const char *timefmt)
{
char *tbuf, *ret;
const char *fmt;
@@ -271,6 +263,8 @@ stattime (t, timefmt)
fmt = timefmt ? timefmt : DEFTIMEFMT;
tm = localtime (&t);
if (tm == 0)
return (itos (t));
ret = xmalloc (TIMELEN_MAX);
@@ -282,12 +276,7 @@ stattime (t, timefmt)
}
static char *
statval (which, fname, flags, fmt, sp)
int which;
char *fname;
int flags;
char *fmt;
struct stat *sp;
statval (int which, char *fname, int flags, char *fmt, struct stat *sp)
{
int temp;
@@ -332,13 +321,7 @@ statval (which, fname, flags, fmt, sp)
}
static int
loadstat (vname, var, fname, flags, fmt, sp)
char *vname;
SHELL_VAR *var;
char *fname;
int flags;
char *fmt;
struct stat *sp;
loadstat (char *vname, SHELL_VAR *var, char *fname, int flags, char *fmt, struct stat *sp)
{
int i;
char *key, *value;
@@ -349,14 +332,16 @@ loadstat (vname, var, fname, flags, fmt, sp)
key = savestring (arraysubs[i]);
value = statval (i, fname, flags, fmt, sp);
v = bind_assoc_variable (var, vname, key, value, ASS_FORCE);
free (value);
}
return 0;
}
#endif
int
stat_builtin (list)
WORD_LIST *list;
stat_builtin (WORD_LIST *list)
{
#if defined (ARRAY_VARS)
int opt, flags;
char *aname, *fname, *timefmt;
struct stat st;
@@ -390,7 +375,7 @@ stat_builtin (list)
}
}
if (legal_identifier (aname) == 0)
if (valid_identifier (aname) == 0)
{
sh_invalidid (aname);
return (EXECUTION_FAILURE);
@@ -429,6 +414,10 @@ stat_builtin (list)
}
return (EXECUTION_SUCCESS);
#else
builtin_error ("arrays not available");
return (EXECUTION_FAILURE);
#endif
}
/* An array of strings forming the `long' documentation for a builtin xxx,
+9 -4
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022-2023 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -37,8 +37,7 @@
#include "bashgetopt.h"
int
strftime_builtin (list)
WORD_LIST *list;
strftime_builtin (WORD_LIST *list)
{
char *format, *tbuf;
size_t tbsize, tsize;
@@ -68,7 +67,7 @@ strftime_builtin (list)
if (list && list->word->word)
{
n = legal_number (list->word->word, &i);
n = valid_number (list->word->word, &i);
if (n == 0 || i < 0 || i != (time_t)i)
{
sh_invalidnum (list->word->word);
@@ -81,6 +80,12 @@ strftime_builtin (list)
secs = NOW;
t = localtime (&secs);
if (t == 0)
{
builtin_error ("%s: timestamp out of range", list && list->word->word ? list->word->word : "now");
return (EXECUTION_FAILURE);
}
tbsize = strlen (format) * 4;
tbuf = 0;
+294
View File
@@ -0,0 +1,294 @@
/* strptime - take a date-time string and turn it into seconds since the epoch. */
/* See Makefile for compilation details. */
/*
Copyright (C) 2023-2025 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashtypes.h"
#include "posixtime.h"
#include <stdio.h>
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
struct date_modifier
{
char *shorthand;
int incr;
};
static struct date_modifier date_time_modifiers[] =
{
{ "now", 0 },
{ "today", 0 },
{ "tomorrow", 24*60*60 },
{ "yesterday", -24*60*60 },
{ "day after tomorrow", 48*60*60 },
{ "two days ago", -48*60*60 },
{ "next week", 7*24*60*60 },
{ "last week", -7*24*60*60 },
{ "the day after tomorrow", 48*60*60 },
{ 0, 0 }
};
static char * const date_time_formats[] =
{
"%a %b %d %T %Z %Y", /* Unix date */
"%a %b %d %T %Y", /* Wkd Mon DD HH:MM:SS YYYY */
"%FT%T%z", /* ISO8601 time YYYY-mm-ddTHH:MM:SSzone */
"%FT%R%z", /* ISO8601 time YYYY-mm-ddTHH:MMzone */
"%G-%m-%dT%T%z", /* ISO8601 time YYYY-mm-ddTHH:MM:SSzone */
"%G-%m-%dT%R%z", /* ISO8601 time YYYY-mm-ddTHH:MMzone */
"%G-%m-%d", /* ISO8601 time YYYY-mm-dd */
/* Can't do 8601 time zone offset with colon or fractions of a second */
"%a, %d %b %Y %T %Z", /* RFC822/RFC2822 time */
"%a, %d %b %Y %T %z", /* RFC822/RFC2822 time */
"%D %T", /* mm/dd/yy HH:MM:SS */
"%D %R", /* mm/dd/yy HH:MM */
"%D %r", /* mm/dd/yy HH:MM:SS a.m. */
"%D %I:%M %p", /* mm/dd/yy HH:MM p.m. */
"%m/%d/%Y %T", /* mm/dd/YYYY HH:MM:SS */
"%m/%d/%Y %R", /* mm/dd/YYYY HH:MM */
"%m/%d/%Y %r", /* mm/dd/YYYY HH:MM:SS a.m */
"%m/%d/%Y %I:%M %p", /* mm/dd/YYYY HH:MM p.m. */
"%m-%d-%Y %T", /* mm-dd-YYYY HH:MM:SS */
"%m-%d-%Y %R", /* mm-dd-YYYY HH:MM */
"%m-%d-%Y %r", /* mm-dd-YYYY HH:MM:SS a.m. */
"%m-%d-%Y %I:%M %p", /* mm-dd-YYYY HH:MM p.m. */
"%Y/%m/%d %T", /* YYYY/mm/dd HH:MM:SS */
"%Y/%m/%d %R", /* YYYY/mm/dd HH:MM */
"%Y/%m/%d %r", /* YYYY/mm/dd hh:MM:SS a.m. */
"%F %T", /* YYYY-mm-dd HH:MM:SS */
"%F %r", /* YYYY-mm-dd HH:MM:SS p.m. */
"%F %R", /* YYYY-mm-dd HH:MM */
"%F %I:%M %p", /* YYYY-mm-dd HH:MM a.m. */
/* From coreutils-9.2 date */
"%Y-%m-%dT%H:%M:%S%z", /* ISO8601 time */
"%Y-%m-%dT%H%z", /* ISO8601 time */
"%Y-%m-%dT%H:%M%z", /* ISO8601 time */
"%Y-%m-%dT%H:%M:%S%Z", /* ISO8601 time but with timezone name */
"%Y-%m-%dT%H%Z", /* ISO8601 time but with timezone name */
"%Y-%m-%dT%H:%M%Z", /* ISO8601 time but with timezone name */
/* RFC 3339 time */
"%Y-%m-%d %H:%M:%S%z", /* RFC 3339 time */
"%Y-%m-%d %H:%M:%S%Z", /* RFC 3339 time but with timezone name */
#if 0
"%Y-%m-%dT%H:%M:%S%z", /* RFC 3339 time, same as first ISO8601 time */
#endif
/* more oddball formats */
"%m.%d.%Y %T", /* mm.dd.YYYY HH:MM:SS */
"%m.%d.%Y %R", /* mm.dd.YYYY HH:MM */
"%m.%d.%Y %r", /* mm.dd.YYYY HH:MM:SS a.m. */
"%m.%d.%Y %I:%M %p", /* mm.dd.YYYY HH:MM p.m. */
"%m/%d/%Y", /* mm/dd/YYYY */
"%d %B %Y %T", /* dd Month YYYY HH:MM:SS */
"%d %B %Y %R", /* dd Month YYYY HH:MM */
"%d %B %Y %r", /* dd Month YYYY HH:MM:SS a.m. */
"%d %B %Y %I:%M %p", /* dd Month YYYY HH:MM p.m. */
"%d %b %Y %T", /* dd Mon YYYY HH:MM:SS */
"%d %b %Y %R", /* dd Mon YYYY HH:MM */
"%d %b %Y %r", /* dd Mon YYYY HH:MM:SS a.m. */
"%d %b %Y %I:%M %p", /* dd Mon YYYY HH:MM p.m. */
"%b %d, %Y %T", /* Mon dd, YYYY HH:MM:SS */
"%b %d, %Y %R", /* Mon dd, YYYY HH:MM */
"%b %d, %Y %r", /* Mon dd, YYYY HH:MM:SS a.m. */
"%b %d, %Y %I:%M %p", /* Mon dd, YYYY HH:MM p.m. */
"%m-%b-%Y", /* dd-Mon-YYYY */
"%m-%b-%Y %T", /* dd-Mon-YYYY HH:MM:SS */
"%m-%b-%Y %R", /* dd-Mon-YYYY HH:MM */
"%m-%b-%Y %r", /* dd-Mon-YYYY HH:MM:SS a.m. */
"%m-%b-%Y %I:%M %p", /* dd-Mon-YYYY HH:MM p.m. */
"%d/%b/%Y:%T %z", /* NCSA log format dd/Mon/YYYY:HH:MM:SS zone */
"%d/%b/%Y:%T%z", /* NCSA log format dd/Mon/YYYY:HH:MM:SSzone */
/* No delimiters */
"%Y%m%d %T", /* YYYYMMDD HH:MM:SS */
"%Y%m%d %R", /* YYYYMMDD HH:MM */
"%Y%m%d %r", /* YYYYMMDD HH:MM:SS a.m. */
"%Y%m%d %I:%M %p", /* YYYYMMDD HH:MM p.m. */
"%Y%m%d %H:%M:%S%z", /* YYYYMMDD HH:MM:SSzone */
"%Y%m%dT%H:%M:%S%z", /* YYYYMMDDTHH:MM:SSzone */
"%Y%m%dT%T", /* YYYYMMDDTHH:MM:SS */
"%Y%m%dT%R", /* YYYYMMDDTHH:MM */
/* Non-US formats */
"%d-%m-%Y", /* dd-mm-YYYY */
"%d-%m-%Y %T", /* dd-mm-YYYY HH:MM:SS */
"%d-%m-%Y %R", /* dd-mm-YYYY HH:MM */
"%d-%m-%Y %r", /* dd-mm-YYYY HH:MM:SS a.m. */
"%d-%m-%Y %I:%M %p", /* dd-mm-YYYY HH:MM p.m. */
"%d/%m/%Y %T", /* dd/mm/YYYY HH:MM:SS */
"%d/%m/%Y %R", /* dd/mm/YYYY HH:MM */
"%d/%m/%Y %r", /* dd/mm/YYYY HH:MM:SS a.m. */
"%d/%m/%Y %I:%M %p", /* dd/mm/YYYY HH:MM p.m. */
"%Y-%d-%m %T", /* YYYY-dd-mm HH:MM:SS */
"%Y-%d-%m %R", /* YYYY-dd-mm HH:MM */
"%d-%m-%Y %T", /* dd-mm-YYYY HH:MM:SS */
"%d-%m-%Y %R", /* dd-mm-YYYY HH:MM */
"%d-%m-%Y %r", /* dd-mm-YYYY HH:MM:SS a.m. */
"%d-%m-%Y %I:%M %p", /* dd-mm-YYYY HH:MM p.m. */
"%d.%m.%Y %T", /* dd.mm.YYYY HH:MM:SS */
"%d.%m.%Y %R", /* dd.mm.YYYY HH:MM */
"%d.%m.%Y %r", /* dd.mm.YYYY HH:MM:SS a.m. */
"%d.%m.%Y %I:%M %p", /* dd.mm.YYYY HH:MM p.m. */
/* Some fallbacks */
"%F", /* YYYY-mm-dd ISO8601 time */
"%T", /* HH:MM:SS */
"%H.%M.%S", /* HH.MM.SS */
0
};
static void
inittime (time_t *clock, struct tm *timeptr)
{
struct tm *loctime;
/* Initialize to local time */
loctime = localtime (clock);
if (loctime == 0)
{
timeptr->tm_hour = timeptr->tm_min = timeptr->tm_sec = 0;
return;
}
memcpy (timeptr, loctime, sizeof (struct tm));
/* but default to midnight */
timeptr->tm_hour = timeptr->tm_min = timeptr->tm_sec = 0;
/* and let the system figure out the right DST offset */
timeptr->tm_isdst = -1;
}
int
strptime_builtin (WORD_LIST *list)
{
char *s;
struct tm t, *tm;
time_t now, secs;
char *datestr, *format;
int i, opt;
format = NULL;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "f:")) != -1)
{
switch (opt)
{
case 'f':
format = list_optarg;
break;
CASE_HELPOPT;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list == 0)
{
builtin_usage ();
return (EX_USAGE);
}
datestr = string_list (list);
if (datestr == 0 || *datestr == 0)
return (EXECUTION_SUCCESS);
now = getnow ();
secs = -1;
for (i = 0; date_time_modifiers[i].shorthand; i++)
{
if (STREQ (datestr, date_time_modifiers[i].shorthand))
{
secs = now + date_time_modifiers[i].incr;
printf ("%ld\n", secs);
return (EXECUTION_SUCCESS);
}
}
/* init struct tm */
inittime (&now, &t);
if (format)
{
s = strptime (datestr, format, &t);
if (s == 0 || s == datestr)
{
builtin_error ("%s: unrecognized format", datestr);
return (EXECUTION_FAILURE);
}
}
else
{
for (i = 0; date_time_formats[i]; i++)
{
s = strptime (datestr, date_time_formats[i], &t);
if (s == 0 || s == datestr)
continue;
break;
}
if (date_time_formats[i] == 0)
{
builtin_error ("%s: unrecognized format", datestr);
return (EXECUTION_FAILURE);
}
}
/* Found something. */
secs = mktime (&t);
if (s && *s)
builtin_warning("%s: not completely converted (%s)", datestr, s);
printf ("%ld\n", secs);
return (EXECUTION_SUCCESS);
}
char *strptime_doc[] = {
"Convert a date-time string to seconds since the epoch.",
"",
"Take DATE-TIME, a date-time string, and parse it using FORMAT, a",
"date and time format accepted by strptime(3). If FORMAT is not supplied,",
"attempt to parse DATE-TIME against a set of common date-time formats,",
"not all of which may be acceptable to strptime(3).",
"If the string matches one of the formats, convert it into seconds",
"since the epoch and display the result.",
(char *)NULL
};
/* The standard structure describing a builtin command. bash keeps an array
of these structures. The flags must include BUILTIN_ENABLED so the
builtin can be used. */
struct builtin strptime_struct = {
"strptime", /* builtin name */
strptime_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
strptime_doc, /* array of long documentation strings. */
"strptime [-f format] date-time", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
+55 -9
View File
@@ -1,7 +1,7 @@
/* sync - sync the disks by forcing pending filesystem writes to complete */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -23,23 +23,69 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include "builtins.h"
#include "shell.h"
#include "common.h"
#include "bashgetopt.h"
#ifndef errno
extern int errno;
#endif
int
sync_builtin (list)
WORD_LIST *list;
sync_builtin (WORD_LIST *list)
{
sync();
return (EXECUTION_SUCCESS);
int fd, status;
WORD_LIST *l;
char *fn;
if (no_options (list))
return (EX_USAGE);
list = loptend;
if (list == 0)
{
sync();
return (EXECUTION_SUCCESS);
}
status = EXECUTION_SUCCESS;
for (l = list; l; l = l->next)
{
fn = l->word->word;
fd = open (fn, O_WRONLY);
if (fd < 0)
fd = open (fn, O_RDONLY);
if (fd < 0)
{
file_error (fn);
status = EXECUTION_FAILURE;
continue;
}
if (fsync (fd) < 0)
{
builtin_error ("%s: cannot sync: %s", fn, strerror (errno));
status = EXECUTION_FAILURE;
}
close (fd);
}
return (status);
}
char *sync_doc[] = {
"Sync disks.",
""
"Force completion of pending disk writes",
"Sync disks or specified files.",
"",
"If one or more FILEs is supplied, force completion of pending writes",
"to those files. Otherwise, force completion of any pending disk",
"writes.",
"",
"Exit Status: zero unless any FILE could not be synced.",
(char *)NULL
};
@@ -48,6 +94,6 @@ struct builtin sync_struct = {
sync_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
sync_doc, /* array of long documentation strings. */
"sync", /* usage synopsis; becomes short_doc */
"sync [file ...]", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
+3 -4
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2021 Free Software Foundation, Inc.
Copyright (C) 1999-2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -58,11 +58,10 @@ static FLIST *tee_flist;
extern int interrupt_immediately;
extern char *strerror ();
extern char *strerror (int);
int
tee_builtin (list)
WORD_LIST *list;
tee_builtin (WORD_LIST *list)
{
int opt, append, nointr, rval, fd, fflags;
int n, nr, nw;
+4 -7
View File
@@ -17,11 +17,10 @@
extern int errno;
#endif
extern char *strerror ();
extern char *strerror (int);
int
template_builtin (list)
WORD_LIST *list;
template_builtin (WORD_LIST *list)
{
int opt, rval;
@@ -45,16 +44,14 @@ template_builtin (list)
/* Called when `template' is enabled and loaded from the shared object. If this
function returns 0, the load fails. */
int
template_builtin_load (name)
char *name;
template_builtin_load (char *name)
{
return (1);
}
/* Called when `template' is disabled. */
void
template_builtin_unload (name)
char *name;
template_builtin_unload (char *name)
{
}
+3 -5
View File
@@ -1,7 +1,7 @@
/* true and false builtins */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -26,15 +26,13 @@
#include "common.h"
int
true_builtin (list)
WORD_LIST *list;
true_builtin (WORD_LIST *list)
{
return EXECUTION_SUCCESS;
}
int
false_builtin (list)
WORD_LIST *list;
false_builtin (WORD_LIST *list)
{
return EXECUTION_FAILURE;
}
+3 -4
View File
@@ -3,7 +3,7 @@
/* See Makefile for compilation details. */
/*
Copyright (C) 1999-2021 Free Software Foundation, Inc.
Copyright (C) 1999-2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -28,11 +28,10 @@
#include "bashgetopt.h"
#include "common.h"
extern char *ttyname ();
extern char *ttyname (int);
int
tty_builtin (list)
WORD_LIST *list;
tty_builtin (WORD_LIST *list)
{
int opt, sflag;
char *t;
+4 -7
View File
@@ -6,7 +6,7 @@
*/
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -59,13 +59,12 @@ struct utsname {
extern int errno;
#endif
static void uprint();
static void uprint(int, char *);
static int uname_flags;
int
uname_builtin (list)
WORD_LIST *list;
uname_builtin (WORD_LIST *list)
{
int opt, r;
struct utsname uninfo;
@@ -134,9 +133,7 @@ uname_builtin (list)
}
static void
uprint (flag, info)
int flag;
char *info;
uprint (int flag, char *info)
{
if (uname_flags & flag)
{
+2 -3
View File
@@ -4,7 +4,7 @@
fsck clean up the file system. */
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -39,8 +39,7 @@ extern int errno;
#endif
int
unlink_builtin (list)
WORD_LIST *list;
unlink_builtin (WORD_LIST *list)
{
if (list == 0)
{
+2 -3
View File
@@ -3,7 +3,7 @@
*/
/*
Copyright (C) 1999-2009 Free Software Foundation, Inc.
Copyright (C) 1999-2009,2022 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
@@ -29,8 +29,7 @@
#include "common.h"
int
whoami_builtin (list)
WORD_LIST *list;
whoami_builtin (WORD_LIST *list)
{
int opt;