summaryrefslogtreecommitdiff
path: root/lib/sh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sh')
-rw-r--r--lib/sh/Makefile.in17
-rw-r--r--lib/sh/casemod.c4
-rw-r--r--lib/sh/eaccess.c12
-rw-r--r--lib/sh/fnxform.c12
-rw-r--r--lib/sh/fpurge.c4
-rw-r--r--lib/sh/gettimeofday.c35
-rw-r--r--lib/sh/input_avail.c73
-rw-r--r--lib/sh/mailstat.c2
-rw-r--r--lib/sh/makepath.c4
-rw-r--r--lib/sh/mktime.c18
-rw-r--r--lib/sh/netopen.c14
-rw-r--r--lib/sh/pathcanon.c2
-rw-r--r--lib/sh/pathphys.c4
-rw-r--r--lib/sh/random.c240
-rw-r--r--lib/sh/shmatch.c4
-rw-r--r--lib/sh/shquote.c77
-rw-r--r--lib/sh/snprintf.c42
-rw-r--r--lib/sh/spell.c6
-rw-r--r--lib/sh/strftime.c17
-rw-r--r--lib/sh/stringlist.c4
-rw-r--r--lib/sh/stringvec.c32
-rw-r--r--lib/sh/strtod.c8
-rw-r--r--lib/sh/strtoimax.c6
-rw-r--r--lib/sh/strtoumax.c6
-rw-r--r--lib/sh/strtrans.c24
-rw-r--r--lib/sh/times.c6
-rw-r--r--lib/sh/timeval.c27
-rw-r--r--lib/sh/tmpfile.c74
-rw-r--r--lib/sh/uconvert.c34
-rw-r--r--lib/sh/ufuncs.c15
-rw-r--r--lib/sh/unicode.c16
-rw-r--r--lib/sh/utf8.c71
-rw-r--r--lib/sh/winsize.c6
-rw-r--r--lib/sh/zcatfd.c12
-rw-r--r--lib/sh/zgetline.c14
-rw-r--r--lib/sh/zmapfd.c14
-rw-r--r--lib/sh/zread.c25
37 files changed, 797 insertions, 184 deletions
diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in
index 06917ba4..98064de5 100644
--- a/lib/sh/Makefile.in
+++ b/lib/sh/Makefile.in
@@ -2,7 +2,7 @@
# Makefile for the Bash library
#
#
-# Copyright (C) 1998-2010 Free Software Foundation, Inc.
+# Copyright (C) 1998-2020 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
@@ -93,7 +93,7 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \
casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \
strchrnul.c unicode.c wcswidth.c wcsnwidth.c shmbchar.c strdup.c \
- utf8.c
+ utf8.c random.c gettimeofday.c
# The header files for this library.
HSOURCES =
@@ -108,7 +108,7 @@ OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \
fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \
fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \
input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o \
- utf8.o wcsnwidth.o ${LIBOBJS}
+ utf8.o random.o gettimeofday.o wcsnwidth.o ${LIBOBJS}
SUPPORT = Makefile
@@ -155,6 +155,7 @@ fnxform.o: fnxform.c
fpurge.o: fpurge.c
getcwd.o: getcwd.c
getenv.o: getenv.c
+gettimeofday.o: gettimeofday.c
inet_aton.o: inet_aton.c
input_avail.o: input_avail.c
itos.o: itos.c
@@ -170,6 +171,7 @@ netopen.o: netopen.c
oslib.o: oslib.c
pathcanon.o: pathcanon.c
pathphys.o: pathphys.c
+random.o: random.c
rename.o: rename.c
setlinebuf.o: setlinebuf.c
shmatch.o: shmatch.c
@@ -233,6 +235,7 @@ fnxform.o: ${BUILD_DIR}/config.h
fpurge.o: ${BUILD_DIR}/config.h
getcwd.o: ${BUILD_DIR}/config.h
getenv.o: ${BUILD_DIR}/config.h
+gettimeofday.o: ${BUILD_DIR}/config.h
inet_aton.o: ${BUILD_DIR}/config.h
input_avail.o: ${BUILD_DIR}/config.h
itos.o: ${BUILD_DIR}/config.h
@@ -248,6 +251,7 @@ netopen.o: ${BUILD_DIR}/config.h
oslib.o: ${BUILD_DIR}/config.h
pathcanon.o: ${BUILD_DIR}/config.h
pathphys.o: ${BUILD_DIR}/config.h
+random.o: ${BUILD_DIR}/config.h
rename.o: ${BUILD_DIR}/config.h
setlinebuf.o: ${BUILD_DIR}/config.h
shmatch.o: ${BUILD_DIR}/config.h
@@ -275,7 +279,7 @@ strtoumax.o: ${BUILD_DIR}/config.h
strtrans.o: ${BUILD_DIR}/config.h
times.o: ${BUILD_DIR}/config.h
timeval.o: ${BUILD_DIR}/config.h
-tmpfile.o: ${BUILD_DIR}/config.h
+tmpfile.o: ${BUILD_DIR}/config.h ${topdir}/config-top.h
uconvert.o: ${BUILD_DIR}/config.h
ufuncs.o: ${BUILD_DIR}/config.h
unicode.o: ${BUILD_DIR}/config.h
@@ -380,6 +384,10 @@ pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
#pathphys.o: ${BUILD_DIR}/version.h
+random.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h
+random.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
+random.o: ${BASHINCDIR}/filecntl.h
+
rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h
rename.o: ${BASHINCDIR}/posixstat.h
@@ -505,6 +513,7 @@ times.o: ${BASHINCDIR}/systimes.h
times.o: ${BASHINCDIR}/posixtime.h
timeval.o: ${BASHINCDIR}/posixtime.h
+gettimeofday.o: ${BASHINCDIR}/posixtime.h
tmpfile.o: ${topdir}/bashtypes.h
tmpfile.o: ${BASHINCDIR}/chartypes.h
diff --git a/lib/sh/casemod.c b/lib/sh/casemod.c
index 7cdd4178..bdd96f84 100644
--- a/lib/sh/casemod.c
+++ b/lib/sh/casemod.c
@@ -1,6 +1,6 @@
/* casemod.c -- functions to change case of strings */
-/* Copyright (C) 2008,2009,2015 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -67,7 +67,7 @@
#define CASE_USEWORDS 0x1000 /* modify behavior to act on words in passed string */
-extern char *substring __P((char *, int, int));
+extern char *substring PARAMS((char *, int, int));
#ifndef UCHAR_MAX
# define UCHAR_MAX TYPE_MAXIMUM(unsigned char)
diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c
index 3d8ae4e8..c3043ec1 100644
--- a/lib/sh/eaccess.c
+++ b/lib/sh/eaccess.c
@@ -1,6 +1,6 @@
/* eaccess.c - eaccess replacement for the shell, plus other access functions. */
-/* Copyright (C) 2006-2010 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -52,10 +52,10 @@ extern int errno;
#define F_OK 0
#endif /* R_OK */
-static int path_is_devfd __P((const char *));
-static int sh_stataccess __P((const char *, int));
+static int path_is_devfd PARAMS((const char *));
+static int sh_stataccess PARAMS((const char *, int));
#if HAVE_DECL_SETREGID
-static int sh_euidaccess __P((const char *, int));
+static int sh_euidaccess PARAMS((const char *, int));
#endif
static int
@@ -213,10 +213,10 @@ sh_eaccess (path, mode)
# else /* HAVE_EACCESS */ /* FreeBSD */
ret = eaccess (path, mode); /* XXX -- not always correct for X_OK */
# endif /* HAVE_EACCESS */
-# if defined (__FreeBSD__) || defined (SOLARIS)
+# if defined (__FreeBSD__) || defined (SOLARIS) || defined (_AIX)
if (ret == 0 && current_user.euid == 0 && mode == X_OK)
return (sh_stataccess (path, mode));
-# endif /* __FreeBSD__ || SOLARIS */
+# endif /* __FreeBSD__ || SOLARIS || _AIX */
return ret;
#elif defined (EFF_ONLY_OK) /* SVR4(?), SVR4.2 */
return access (path, mode|EFF_ONLY_OK);
diff --git a/lib/sh/fnxform.c b/lib/sh/fnxform.c
index d7e1b5ad..35d7e737 100644
--- a/lib/sh/fnxform.c
+++ b/lib/sh/fnxform.c
@@ -1,6 +1,6 @@
/* fnxform - use iconv(3) to transform strings to and from "filename" format */
-/* Copyright (C) 2009-2010 Free Software Foundation, Inc.
+/* Copyright (C) 2009-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -35,9 +35,9 @@
#endif
#if defined (HAVE_LOCALE_CHARSET)
-extern const char *locale_charset __P((void));
+extern const char *locale_charset PARAMS((void));
#else
-extern char *get_locale_var __P((char *));
+extern char *get_locale_var PARAMS((char *));
#endif
#if defined (HAVE_ICONV)
@@ -49,9 +49,9 @@ static iconv_t conv_tofs = (iconv_t)-1;
static char *outbuf = 0;
static size_t outlen = 0;
-static char *curencoding __P((void));
-static void init_tofs __P((void));
-static void init_fromfs __P((void));
+static char *curencoding PARAMS((void));
+static void init_tofs PARAMS((void));
+static void init_fromfs PARAMS((void));
static char *
curencoding ()
diff --git a/lib/sh/fpurge.c b/lib/sh/fpurge.c
index 13e8c78e..8cd4e368 100644
--- a/lib/sh/fpurge.c
+++ b/lib/sh/fpurge.c
@@ -1,6 +1,6 @@
/* fpurge - Flushing buffers of a FILE stream. */
-/* Copyright (C) 2007-2010 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -29,7 +29,7 @@
#if HAVE_FPURGE
# define fpurge _bash_fpurge
#endif
-extern int fpurge __P((FILE *stream));
+extern int fpurge PARAMS((FILE *stream));
#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7 */
# include <stdio_ext.h>
diff --git a/lib/sh/gettimeofday.c b/lib/sh/gettimeofday.c
new file mode 100644
index 00000000..b654c154
--- /dev/null
+++ b/lib/sh/gettimeofday.c
@@ -0,0 +1,35 @@
+/* gettimeofday.c - gettimeofday replacement using time() */
+
+/* Copyright (C) 2020 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ 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_GETTIMEOFDAY)
+
+#include "posixtime.h"
+
+/* A version of gettimeofday that just sets tv_sec from time(3) */
+int
+gettimeofday (struct timeval *tv, void *tz)
+{
+ tv->tv_sec = (time_t) time ((time_t *)0);
+ tv->tv_usec = 0;
+ return 0;
+}
+#endif
diff --git a/lib/sh/input_avail.c b/lib/sh/input_avail.c
index ac157a9f..695165fd 100644
--- a/lib/sh/input_avail.c
+++ b/lib/sh/input_avail.c
@@ -1,7 +1,7 @@
/* input_avail.c -- check whether or not data is available for reading on a
specified file descriptor. */
-/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008,2009-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -33,6 +33,10 @@
# include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
+#if defined (HAVE_PSELECT)
+# include <signal.h>
+#endif
+
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
@@ -82,10 +86,8 @@ input_avail (fd)
timeout.tv_usec = 0;
result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
return ((result <= 0) ? 0 : 1);
-
#endif
- result = -1;
#if defined (FIONREAD)
errno = 0;
result = ioctl (fd, FIONREAD, &chars_avail);
@@ -96,3 +98,68 @@ input_avail (fd)
return 0;
}
+
+/* Wait until NCHARS are available for reading on file descriptor FD.
+ This can wait indefinitely. Return -1 on error. */
+int
+nchars_avail (fd, nchars)
+ int fd;
+ int nchars;
+{
+ int result, chars_avail;
+#if defined(HAVE_SELECT)
+ fd_set readfds, exceptfds;
+#endif
+#if defined (HAVE_PSELECT)
+ sigset_t set, oset;
+#endif
+
+ if (fd < 0 || nchars < 0)
+ return -1;
+ if (nchars == 0)
+ return (input_avail (fd));
+
+ chars_avail = 0;
+
+#if defined (HAVE_SELECT)
+ FD_ZERO (&readfds);
+ FD_ZERO (&exceptfds);
+ FD_SET (fd, &readfds);
+ FD_SET (fd, &exceptfds);
+#endif
+#if defined (HAVE_SELECT) || defined (HAVE_PSELECT)
+ sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
+# ifdef SIGCHLD
+ sigaddset (&set, SIGCHLD);
+# endif
+ sigemptyset (&oset);
+#endif
+
+ while (1)
+ {
+ result = 0;
+#if defined (HAVE_PSELECT)
+ /* XXX - use pselect(2) to block SIGCHLD atomically */
+ result = pselect (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timespec *)NULL, &set);
+#elif defined (HAVE_SELECT)
+ sigprocmask (SIG_BLOCK, &set, &oset);
+ result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timeval *)NULL);
+ sigprocmask (SIG_BLOCK, &oset, (sigset_t *)NULL);
+#endif
+ if (result < 0)
+ return -1;
+
+#if defined (FIONREAD)
+ errno = 0;
+ result = ioctl (fd, FIONREAD, &chars_avail);
+ if (result == -1 && errno == EIO)
+ return -1;
+ if (chars_avail >= nchars)
+ break;
+#else
+ break;
+#endif
+ }
+
+ return 0;
+}
diff --git a/lib/sh/mailstat.c b/lib/sh/mailstat.c
index 79b431ae..bd5c25fb 100644
--- a/lib/sh/mailstat.c
+++ b/lib/sh/mailstat.c
@@ -60,7 +60,7 @@ mailstat(path, st)
struct stat st_ret, st_tmp;
DIR *dd;
struct dirent *fn;
- char dir[PATH_MAX * 2], file[PATH_MAX * 2];
+ char dir[PATH_MAX * 2], file[PATH_MAX * 2 + 1];
int i, l;
time_t atime, mtime;
diff --git a/lib/sh/makepath.c b/lib/sh/makepath.c
index ef01718b..ab46c967 100644
--- a/lib/sh/makepath.c
+++ b/lib/sh/makepath.c
@@ -1,6 +1,6 @@
/* makepath.c - glue PATH and DIR together into a full pathname. */
-/* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -45,7 +45,7 @@
# define MP_IGNDOT 0x08
#endif
-extern char *get_working_directory __P((char *));
+extern char *get_working_directory PARAMS((char *));
static char *nullpath = "";
diff --git a/lib/sh/mktime.c b/lib/sh/mktime.c
index b2b0d3f2..9ee675be 100644
--- a/lib/sh/mktime.c
+++ b/lib/sh/mktime.c
@@ -1,6 +1,6 @@
/* mktime - convert struct tm to a time_t value */
-/* Copyright (C) 1993-2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Contributed by Paul Eggert (eggert@twinsun.com).
@@ -56,13 +56,13 @@
#define mktime my_mktime
#endif /* DEBUG_MKTIME */
-#ifndef __P
+#ifndef PARAMS
#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
-#define __P(args) args
+#define PARAMS(args) args
#else
-#define __P(args) ()
+#define PARAMS(args) ()
#endif /* GCC. */
-#endif /* Not __P. */
+#endif /* Not PARAMS. */
#ifndef CHAR_BIT
#define CHAR_BIT 8
@@ -117,13 +117,13 @@ const unsigned short int __mon_yday[2][13] =
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
-static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
-time_t __mktime_internal __P ((struct tm *,
+static time_t ydhms_tm_diff PARAMS ((int, int, int, int, int, const struct tm *));
+time_t __mktime_internal PARAMS ((struct tm *,
struct tm *(*) (const time_t *, struct tm *),
time_t *));
-static struct tm *my_localtime_r __P ((const time_t *, struct tm *));
+static struct tm *my_localtime_r PARAMS ((const time_t *, struct tm *));
static struct tm *
my_localtime_r (t, tp)
const time_t *t;
@@ -193,7 +193,7 @@ mktime (tp)
time_t
__mktime_internal (tp, convert, offset)
struct tm *tp;
- struct tm *(*convert) __P ((const time_t *, struct tm *));
+ struct tm *(*convert) PARAMS ((const time_t *, struct tm *));
time_t *offset;
{
time_t t, dt, t0;
diff --git a/lib/sh/netopen.c b/lib/sh/netopen.c
index bc3d8f8a..ee0baf66 100644
--- a/lib/sh/netopen.c
+++ b/lib/sh/netopen.c
@@ -5,7 +5,7 @@
* chet@ins.CWRU.Edu
*/
-/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -63,18 +63,18 @@ extern int errno;
#endif
#if !defined (HAVE_INET_ATON)
-extern int inet_aton __P((const char *, struct in_addr *));
+extern int inet_aton PARAMS((const char *, struct in_addr *));
#endif
#ifndef HAVE_GETADDRINFO
-static int _getaddr __P((char *, struct in_addr *));
-static int _getserv __P((char *, int, unsigned short *));
-static int _netopen4 __P((char *, char *, int));
+static int _getaddr PARAMS((char *, struct in_addr *));
+static int _getserv PARAMS((char *, int, unsigned short *));
+static int _netopen4 PARAMS((char *, char *, int));
#else /* HAVE_GETADDRINFO */
-static int _netopen6 __P((char *, char *, int));
+static int _netopen6 PARAMS((char *, char *, int));
#endif
-static int _netopen __P((char *, char *, int));
+static int _netopen PARAMS((char *, char *, int));
#ifndef HAVE_GETADDRINFO
/* Stuff the internet address corresponding to HOST into AP, in network
diff --git a/lib/sh/pathcanon.c b/lib/sh/pathcanon.c
index f9506dff..7d0df9f9 100644
--- a/lib/sh/pathcanon.c
+++ b/lib/sh/pathcanon.c
@@ -90,7 +90,7 @@ _path_isdir (path)
/* Canonicalize PATH, and return a new path. The new path differs from PATH
in that:
- Multple `/'s are collapsed to a single `/'.
+ Multiple `/'s are collapsed to a single `/'.
Leading `./'s and trailing `/.'s are removed.
Trailing `/'s are removed.
Non-leading `../'s and trailing `..'s are handled by removing
diff --git a/lib/sh/pathphys.c b/lib/sh/pathphys.c
index 99390cef..95b72f19 100644
--- a/lib/sh/pathphys.c
+++ b/lib/sh/pathphys.c
@@ -1,6 +1,6 @@
/* pathphys.c -- return pathname with all symlinks expanded. */
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -46,7 +46,7 @@
extern int errno;
#endif /* !errno */
-extern char *get_working_directory __P((char *));
+extern char *get_working_directory PARAMS((char *));
static int
_path_readlink (path, buf, bufsiz)
diff --git a/lib/sh/random.c b/lib/sh/random.c
new file mode 100644
index 00000000..1eaa71aa
--- /dev/null
+++ b/lib/sh/random.c
@@ -0,0 +1,240 @@
+/* random.c -- Functions for managing 16-bit and 32-bit random numbers. */
+
+/* Copyright (C) 2020 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ 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"
+
+#if defined (HAVE_SYS_RANDOM_H)
+# include <sys/random.h>
+#endif
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+#include "filecntl.h"
+
+#include <stdio.h>
+#include "bashansi.h"
+
+#include "shell.h"
+
+extern time_t shell_start_time;
+
+extern int last_random_value;
+
+static u_bits32_t intrand32 PARAMS((u_bits32_t));
+static u_bits32_t genseed PARAMS((void));
+
+static u_bits32_t brand32 PARAMS((void));
+static void sbrand32 PARAMS((u_bits32_t));
+static void perturb_rand32 PARAMS((void));
+
+/* The random number seed. You can change this by setting RANDOM. */
+static u_bits32_t rseed = 1;
+
+/* Returns a 32-bit pseudo-random number. */
+static u_bits32_t
+intrand32 (last)
+ u_bits32_t last;
+{
+ /* Minimal Standard generator from
+ "Random number generators: good ones are hard to find",
+ Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ October 1988, p. 1195. Filtered through FreeBSD.
+
+ x(n+1) = 16807 * x(n) mod (m).
+
+ We split up the calculations to avoid overflow.
+
+ h = last / q; l = x - h * q; t = a * l - h * r
+ m = 2147483647, a = 16807, q = 127773, r = 2836
+
+ There are lots of other combinations of constants to use; look at
+ https://www.gnu.org/software/gsl/manual/html_node/Other-random-number-generators.html#Other-random-number-generators */
+
+ bits32_t h, l, t;
+ u_bits32_t ret;
+
+ /* Can't seed with 0. */
+ ret = (last == 0) ? 123459876 : last;
+ h = ret / 127773;
+ l = ret - (127773 * h);
+ t = 16807 * l - 2836 * h;
+ ret = (t < 0) ? t + 0x7fffffff : t;
+
+ return (ret);
+}
+
+static u_bits32_t
+genseed ()
+{
+ struct timeval tv;
+ u_bits32_t iv;
+
+ gettimeofday (&tv, NULL);
+ iv = (u_bits32_t)seedrand; /* let the compiler truncate */
+ iv = tv.tv_sec ^ tv.tv_usec ^ getpid () ^ getppid () ^ current_user.uid ^ iv;
+ return (iv);
+}
+
+#define BASH_RAND_MAX 32767 /* 0x7fff - 16 bits */
+
+/* Returns a pseudo-random number between 0 and 32767. */
+int
+brand ()
+{
+ unsigned int ret;
+
+ rseed = intrand32 (rseed);
+ if (shell_compatibility_level > 50)
+ ret = (rseed >> 16) ^ (rseed & 65535);
+ else
+ ret = rseed;
+ return (ret & BASH_RAND_MAX);
+}
+
+/* Set the random number generator seed to SEED. */
+void
+sbrand (seed)
+ unsigned long seed;
+{
+ rseed = seed;
+ last_random_value = 0;
+}
+
+void
+seedrand ()
+{
+ u_bits32_t iv;
+
+ iv = genseed ();
+ sbrand (iv);
+}
+
+static u_bits32_t rseed32 = 1073741823;
+static int last_rand32;
+
+static int urandfd = -1;
+
+#define BASH_RAND32_MAX 0x7fffffff /* 32 bits */
+
+/* Returns a 32-bit pseudo-random number between 0 and 4294967295. */
+static u_bits32_t
+brand32 ()
+{
+ u_bits32_t ret;
+
+ rseed32 = intrand32 (rseed32);
+ return (rseed32 & BASH_RAND32_MAX);
+}
+
+static void
+sbrand32 (seed)
+ u_bits32_t seed;
+{
+ last_rand32 = rseed32 = seed;
+}
+
+void
+seedrand32 ()
+{
+ u_bits32_t iv;
+
+ iv = genseed ();
+ sbrand32 (iv);
+}
+
+static void
+perturb_rand32 ()
+{
+ rseed32 ^= genseed ();
+}
+
+/* Force another attempt to open /dev/urandom on the next call to get_urandom32 */
+void
+urandom_close ()
+{
+ if (urandfd >= 0)
+ close (urandfd);
+ urandfd = -1;
+}
+
+#if !defined (HAVE_GETRANDOM)
+/* Imperfect emulation of getrandom(2). */
+#ifndef GRND_NONBLOCK
+# define GRND_NONBLOCK 1
+# define GRND_RANDOM 2
+#endif
+
+static ssize_t
+getrandom (buf, len, flags)
+ void *buf;
+ size_t len;
+ unsigned int flags;
+{
+ int oflags;
+ ssize_t r;
+ static int urand_unavail = 0;
+
+#if HAVE_GETENTROPY
+ r = getentropy (buf, len);
+ return (r == 0) ? len : -1;
+#endif
+
+ if (urandfd == -1 && urand_unavail == 0)
+ {
+ oflags = O_RDONLY;
+ if (flags & GRND_NONBLOCK)
+ oflags |= O_NONBLOCK;
+ urandfd = open ("/dev/urandom", oflags, 0);
+ if (urandfd >= 0)
+ SET_CLOSE_ON_EXEC (urandfd);
+ else
+ {
+ urand_unavail = 1;
+ return -1;
+ }
+ }
+ if (urandfd >= 0 && (r = read (urandfd, buf, len)) == len)
+ return (r);
+ return -1;
+}
+#endif
+
+u_bits32_t
+get_urandom32 ()
+{
+ u_bits32_t ret;
+
+ if (getrandom ((void *)&ret, sizeof (ret), GRND_NONBLOCK) == sizeof (ret))
+ return (last_rand32 = ret);
+
+#if defined (HAVE_ARC4RANDOM)
+ ret = arc4random ();
+#else
+ if (subshell_environment)
+ perturb_rand32 ();
+ do
+ ret = brand32 ();
+ while (ret == last_rand32);
+#endif
+ return (last_rand32 = ret);
+}
diff --git a/lib/sh/shmatch.c b/lib/sh/shmatch.c
index da05211e..d6e7f904 100644
--- a/lib/sh/shmatch.c
+++ b/lib/sh/shmatch.c
@@ -64,7 +64,7 @@ sh_regmatch (string, pattern, flags)
#endif
rflags = REG_EXTENDED;
- if (glob_ignore_case || match_ignore_case)
+ if (match_ignore_case)
rflags |= REG_ICASE;
#if !defined (ARRAY_VARS)
rflags |= REG_NOSUB;
@@ -107,7 +107,9 @@ sh_regmatch (string, pattern, flags)
}
}
+#if 0
VSETATTR (rematch, att_readonly);
+#endif
free (subexp_str);
free (matches);
diff --git a/lib/sh/shquote.c b/lib/sh/shquote.c
index 97e2bc53..680f84ed 100644
--- a/lib/sh/shquote.c
+++ b/lib/sh/shquote.c
@@ -1,6 +1,6 @@
/* shquote - functions to quote and dequote strings */
-/* Copyright (C) 1999-2015 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -36,8 +36,8 @@
#include "shmbchar.h"
#include "shmbutil.h"
-extern char *ansic_quote __P((char *, int, int *));
-extern int ansic_shouldquote __P((const char *));
+extern char *ansic_quote PARAMS((char *, int, int *));
+extern int ansic_shouldquote PARAMS((const char *));
/* Default set of characters that should be backslash-quoted in strings */
static const char bstab[256] =
@@ -136,8 +136,15 @@ sh_double_quote (string)
const char *string;
{
register unsigned char c;
+ int mb_cur_max;
char *result, *r;
- const char *s;
+ size_t slen;
+ const char *s, *send;
+ DECLARE_MBSTATE;
+
+ slen = strlen (string);
+ send = string + slen;
+ mb_cur_max = MB_CUR_MAX;
result = (char *)xmalloc (3 + (2 * strlen (string)));
r = result;
@@ -148,12 +155,19 @@ sh_double_quote (string)
/* Backslash-newline disappears within double quotes, so don't add one. */
if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
*r++ = '\\';
-#if 0
- /* Assume that the string will not be further expanded. */
- else if (c == CTLESC || c == CTLNUL)
- *r++ = CTLESC; /* could be '\\'? */
+
+#if defined (HANDLE_MULTIBYTE)
+ if ((locale_utf8locale && (c & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
+ {
+ COPY_CHAR_P (r, s, send);
+ s--; /* compensate for auto-increment in loop above */
+ continue;
+ }
#endif
+ /* Assume that the string will not be further expanded, so no need to
+ add CTLESC to protect CTLESC or CTLNUL. */
*r++ = c;
}
@@ -171,16 +185,29 @@ sh_mkdoublequoted (s, slen, flags)
int slen, flags;
{
char *r, *ret;
- int rlen;
+ const char *send;
+ int rlen, mb_cur_max;
+ DECLARE_MBSTATE;
+ send = s + slen;
+ mb_cur_max = flags ? MB_CUR_MAX : 1;
rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1;
ret = r = (char *)xmalloc (rlen);
-
+
*r++ = '"';
while (*s)
{
if (flags && *s == '"')
*r++ = '\\';
+
+#if defined (HANDLE_MULTIBYTE)
+ if (flags && ((locale_utf8locale && (*s & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (*s) == 0)))
+ {
+ COPY_CHAR_P (r, s, send);
+ continue;
+ }
+#endif
*r++ = *s++;
}
*r++ = '"';
@@ -259,7 +286,8 @@ sh_backslash_quote (string, table, flags)
*r++ = c;
continue;
}
- if (mb_cur_max > 1 && is_basic (c) == 0)
+ if ((locale_utf8locale && (c & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
{
COPY_CHAR_P (r, s, send);
s--; /* compensate for auto-increment in loop above */
@@ -291,18 +319,35 @@ sh_backslash_quote_for_double_quotes (string)
char *string;
{
unsigned char c;
- char *result, *r, *s;
-
- result = (char *)xmalloc (2 * strlen (string) + 1);
+ char *result, *r, *s, *send;
+ size_t slen;
+ int mb_cur_max;
+ DECLARE_MBSTATE;
+
+ slen = strlen (string);
+ send = string + slen;
+ mb_cur_max = MB_CUR_MAX;
+ result = (char *)xmalloc (2 * slen + 1);
for (r = result, s = string; s && (c = *s); s++)
{
- if (sh_syntaxtab[c] & CBSDQUOTE)
+ /* Backslash-newline disappears within double quotes, so don't add one. */
+ if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
*r++ = '\\';
- /* I should probably add flags for these to sh_syntaxtab[] */
+ /* I should probably use the CSPECL flag for these in sh_syntaxtab[] */
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
+#if defined (HANDLE_MULTIBYTE)
+ if ((locale_utf8locale && (c & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
+ {
+ COPY_CHAR_P (r, s, send);
+ s--; /* compensate for auto-increment in loop above */
+ continue;
+ }
+#endif
+
*r++ = c;
}
diff --git a/lib/sh/snprintf.c b/lib/sh/snprintf.c
index 6e5892ee..406a3a50 100644
--- a/lib/sh/snprintf.c
+++ b/lib/sh/snprintf.c
@@ -9,7 +9,7 @@
Unix snprintf implementation.
derived from inetutils/libinetutils/snprintf.c Version 1.1
- Copyright (C) 2001,2006,2010,2012 Free Software Foundation, Inc.
+ Copyright (C) 2001-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -129,8 +129,8 @@
# define FL_ADDBASE 0x02 /* add base# prefix to converted value */
# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
# define FL_UNSIGNED 0x08 /* don't add any sign */
-extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
-extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
+extern char *fmtulong PARAMS((unsigned long int, int, char *, size_t, int));
+extern char *fmtullong PARAMS((unsigned long long int, int, char *, size_t, int));
#endif
#ifndef FREE
@@ -271,38 +271,38 @@ struct DATA
/* the floating point stuff */
#ifdef FLOATING_POINT
-static double pow_10 __P((int));
-static int log_10 __P((double));
-static double integral __P((double, double *));
-static char *numtoa __P((double, int, int, char **));
+static double pow_10 PARAMS((int));
+static int log_10 PARAMS((double));
+static double integral PARAMS((double, double *));
+static char *numtoa PARAMS((double, int, int, char **));
#endif
-static void init_data __P((struct DATA *, char *, size_t, const char *, int));
-static void init_conv_flag __P((struct DATA *));
+static void init_data PARAMS((struct DATA *, char *, size_t, const char *, int));
+static void init_conv_flag PARAMS((struct DATA *));
/* for the format */
#ifdef FLOATING_POINT
-static void floating __P((struct DATA *, double));
-static void exponent __P((struct DATA *, double));
+static void floating PARAMS((struct DATA *, double));
+static void exponent PARAMS((struct DATA *, double));
#endif
-static void number __P((struct DATA *, unsigned long, int));
+static void number PARAMS((struct DATA *, unsigned long, int));
#ifdef HAVE_LONG_LONG
-static void lnumber __P((struct DATA *, unsigned long long, int));
+static void lnumber PARAMS((struct DATA *, unsigned long long, int));
#endif
-static void pointer __P((struct DATA *, unsigned long));
-static void strings __P((struct DATA *, char *));
+static void pointer PARAMS((struct DATA *, unsigned long));
+static void strings PARAMS((struct DATA *, char *));
#ifdef FLOATING_POINT
# define FALLBACK_FMTSIZE 32
# define FALLBACK_BASE 4096
# define LFALLBACK_BASE 5120
# ifdef HAVE_LONG_DOUBLE
-static void ldfallback __P((struct DATA *, const char *, const char *, long double));
+static void ldfallback PARAMS((struct DATA *, const char *, const char *, long double));
# endif
-static void dfallback __P((struct DATA *, const char *, const char *, double));
+static void dfallback PARAMS((struct DATA *, const char *, const char *, double));
#endif
-static char *groupnum __P((char *));
+static char *groupnum PARAMS((char *));
#if defined (HAVE_LONG_DOUBLE)
# define LONGDOUBLE long double
@@ -332,9 +332,9 @@ static char *groupnum __P((char *));
#ifdef DRIVER
static void memory_error_and_abort ();
-static void *xmalloc __P((size_t));
-static void *xrealloc __P((void *, size_t));
-static void xfree __P((void *));
+static void *xmalloc PARAMS((size_t));
+static void *xrealloc PARAMS((void *, size_t));
+static void xfree PARAMS((void *));
#else
# include <xmalloc.h>
#endif
diff --git a/lib/sh/spell.c b/lib/sh/spell.c
index da78690c..cdf465b2 100644
--- a/lib/sh/spell.c
+++ b/lib/sh/spell.c
@@ -1,6 +1,6 @@
/* spell.c -- spelling correction for pathnames. */
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -40,8 +40,8 @@
#include <maxpath.h>
#include <stdc.h>
-static int mindist __P((char *, char *, char *));
-static int spdist __P((char *, char *));
+static int mindist PARAMS((char *, char *, char *));
+static int spdist PARAMS((char *, char *));
/*
* `spname' and its helpers are inspired by the code in "The UNIX
diff --git a/lib/sh/strftime.c b/lib/sh/strftime.c
index 0ababc14..08ccb9a3 100644
--- a/lib/sh/strftime.c
+++ b/lib/sh/strftime.c
@@ -62,6 +62,7 @@
#include <stdio.h>
#include <ctype.h>
#include <time.h>
+#include <errno.h>
#if defined(TM_IN_SYS_TIME)
#include <sys/types.h>
@@ -80,6 +81,10 @@
#undef strchr /* avoid AIX weirdness */
+#if !defined (errno)
+extern int errno;
+#endif
+
#if defined (SHELL)
extern char *get_string_value (const char *);
#endif
@@ -172,7 +177,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
char *start = s;
auto char tbuf[100];
long off;
- int i, w;
+ int i, w, oerrno;
long y;
static short first = 1;
#ifdef POSIX_SEMANTICS
@@ -217,6 +222,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
};
static const char *ampm[] = { "AM", "PM", };
+ oerrno = errno;
+
if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)
return 0;
@@ -642,7 +649,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
sprintf(tbuf+1, "%02ld%02ld", off/60, off%60);
break;
- case 'Z': /* time zone name or abbrevation */
+ case 'Z': /* time zone name or abbreviation */
#ifdef HAVE_TZNAME
i = (daylight && timeptr->tm_isdst > 0); /* 0 or 1 */
strcpy(tbuf, tzname[i]);
@@ -716,6 +723,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
out:
if (s < endp && *format == '\0') {
*s = '\0';
+ if (s == start)
+ errno = oerrno;
return (s - start);
} else
return 0;
@@ -939,7 +948,7 @@ static char *array[] =
"(%%H) hour (24-hour clock, 00..23) %H",
"(%%I) hour (12-hour clock, 01..12) %I",
"(%%M) minute (00..59) %M",
- "(%%N) Emporer/Era Name %N",
+ "(%%N) Emperor/Era Name %N",
"(%%O) Locale extensions (ignored) %O",
"(%%R) time, 24-hour (%%H:%%M) %R",
"(%%S) second (00..60) %S",
@@ -960,7 +969,7 @@ static char *array[] =
"(%%k) hour, 24-hour clock, blank pad ( 0..23) %k",
"(%%l) hour, 12-hour clock, blank pad ( 0..12) %l",
"(%%m) month (01..12) %m",
- "(%%o) Emporer/Era Year %o",
+ "(%%o) Emperor/Era Year %o",
"(%%p) locale's AM or PM based on 12-hour clock %p",
"(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r",
"(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u",
diff --git a/lib/sh/stringlist.c b/lib/sh/stringlist.c
index b0c272ae..3f28b631 100644
--- a/lib/sh/stringlist.c
+++ b/lib/sh/stringlist.c
@@ -1,6 +1,6 @@
/* stringlist.c - functions to handle a generic `list of strings' structure */
-/* Copyright (C) 2000-2002 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -255,7 +255,7 @@ strlist_sort (sl)
{
if (sl == 0 || sl->list_len == 0 || sl->list == 0)
return;
- strvec_sort (sl->list);
+ strvec_sort (sl->list, 0);
}
STRINGLIST *
diff --git a/lib/sh/stringvec.c b/lib/sh/stringvec.c
index 3bb4ab70..86000429 100644
--- a/lib/sh/stringvec.c
+++ b/lib/sh/stringvec.c
@@ -122,7 +122,6 @@ strvec_remove (array, name)
return 0;
}
-#ifdef INCLUDE_UNUSED
/* Find NAME in ARRAY. Return the index of NAME, or -1 if not present.
ARRAY should be NULL terminated. */
int
@@ -137,7 +136,6 @@ strvec_search (array, name)
return (-1);
}
-#endif
/* Allocate and return a new copy of ARRAY and its contents. */
char **
@@ -158,6 +156,28 @@ strvec_copy (array)
return (ret);
}
+/* Comparison routine for use by qsort that conforms to the new Posix
+ requirements (http://austingroupbugs.net/view.php?id=1070).
+
+ Perform a bytewise comparison if *S1 and *S2 collate equally. */
+int
+strvec_posixcmp (s1, s2)
+ register char **s1, **s2;
+{
+ int result;
+
+#if defined (HAVE_STRCOLL)
+ result = strcoll (*s1, *s2);
+ if (result != 0)
+ return result;
+#endif
+
+ if ((result = **s1 - **s2) == 0)
+ result = strcmp (*s1, *s2);
+
+ return (result);
+}
+
/* Comparison routine for use with qsort() on arrays of strings. Uses
strcoll(3) if available, otherwise it uses strcmp(3). */
int
@@ -178,10 +198,14 @@ strvec_strcmp (s1, s2)
/* Sort ARRAY, a null terminated array of pointers to strings. */
void
-strvec_sort (array)
+strvec_sort (array, posix)
char **array;
+ int posix;
{
- qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp);
+ if (posix)
+ qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_posixcmp);
+ else
+ qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp);
}
/* Cons up a new array of words. The words are taken from LIST,
diff --git a/lib/sh/strtod.c b/lib/sh/strtod.c
index 851d99b9..55e11540 100644
--- a/lib/sh/strtod.c
+++ b/lib/sh/strtod.c
@@ -49,6 +49,10 @@ extern int errno;
# define HUGE_VAL HUGE
#endif
+#ifndef locale_decpoint
+extern int locale_decpoint PARAMS((void));
+#endif
+
/* Convert NPTR to a double. If ENDPTR is not NULL, a pointer to the
character after the last one used in the number is put in *ENDPTR. */
double
@@ -62,6 +66,7 @@ strtod (nptr, endptr)
/* The number so far. */
double num;
+ int radixchar;
int got_dot; /* Found a decimal point. */
int got_digit; /* Seen any digits. */
@@ -85,6 +90,7 @@ strtod (nptr, endptr)
if (*s == '-' || *s == '+')
++s;
+ radixchar = locale_decpoint ();
num = 0.0;
got_dot = 0;
got_digit = 0;
@@ -113,7 +119,7 @@ strtod (nptr, endptr)
if (got_dot)
--exponent;
}
- else if (!got_dot && *s == '.')
+ else if (!got_dot && *s == radixchar)
/* Record that we have found the decimal point. */
got_dot = 1;
else
diff --git a/lib/sh/strtoimax.c b/lib/sh/strtoimax.c
index a4170f06..676e02ef 100644
--- a/lib/sh/strtoimax.c
+++ b/lib/sh/strtoimax.c
@@ -1,6 +1,6 @@
/* strtoimax - convert string representation of a number into an intmax_t value. */
-/* Copyright 1999-2009 Free Software Foundation, Inc.
+/* Copyright 1999-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -45,14 +45,14 @@
"this configure-time declaration test was not run"
#endif
#if !HAVE_DECL_STRTOL
-extern long strtol __P((const char *, char **, int));
+extern long strtol PARAMS((const char *, char **, int));
#endif
#ifndef HAVE_DECL_STRTOLL
"this configure-time declaration test was not run"
#endif
#if !HAVE_DECL_STRTOLL && HAVE_LONG_LONG
-extern long long strtoll __P((const char *, char **, int));
+extern long long strtoll PARAMS((const char *, char **, int));
#endif
#ifdef strtoimax
diff --git a/lib/sh/strtoumax.c b/lib/sh/strtoumax.c
index 09423add..0247e57b 100644
--- a/lib/sh/strtoumax.c
+++ b/lib/sh/strtoumax.c
@@ -1,6 +1,6 @@
/* strtoumax - convert string representation of a number into an uintmax_t value. */
-/* Copyright 1999-2009 Free Software Foundation, Inc.
+/* Copyright 1999-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -45,14 +45,14 @@
"this configure-time declaration test was not run"
#endif
#if !HAVE_DECL_STRTOUL
-extern unsigned long strtoul __P((const char *, char **, int));
+extern unsigned long strtoul PARAMS((const char *, char **, int));
#endif
#ifndef HAVE_DECL_STRTOULL
"this configure-time declaration test was not run"
#endif
#if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG
-extern unsigned long long strtoull __P((const char *, char **, int));
+extern unsigned long long strtoull PARAMS((const char *, char **, int));
#endif
#ifdef strtoumax
diff --git a/lib/sh/strtrans.c b/lib/sh/strtrans.c
index 48f255f5..b2b1acca 100644
--- a/lib/sh/strtrans.c
+++ b/lib/sh/strtrans.c
@@ -55,12 +55,18 @@ ansicstr (string, len, flags, sawc, rlen)
int c, temp;
char *ret, *r, *s;
unsigned long v;
+ size_t clen;
+ int b, mb_cur_max;
+#if defined (HANDLE_MULTIBYTE)
+ wchar_t wc;
+#endif
if (string == 0 || *string == '\0')
return ((char *)NULL);
+ mb_cur_max = MB_CUR_MAX;
#if defined (HANDLE_MULTIBYTE)
- temp = 4*len + 1;
+ temp = 4*len + 4;
if (temp < 12)
temp = 12; /* ensure enough for eventual u32cesc */
ret = (char *)xmalloc (temp);
@@ -71,7 +77,21 @@ ansicstr (string, len, flags, sawc, rlen)
{
c = *s++;
if (c != '\\' || *s == '\0')
- *r++ = c;
+ {
+ clen = 1;
+#if defined (HANDLE_MULTIBYTE)
+ if ((locale_utf8locale && (c & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 0 && is_basic (c) == 0))
+ {
+ clen = mbrtowc (&wc, s - 1, mb_cur_max, 0);
+ if (MB_INVALIDCH (clen))
+ clen = 1;
+ }
+#endif
+ *r++ = c;
+ for (--clen; clen > 0; clen--)
+ *r++ = *s++;
+ }
else
{
switch (c = *s++)
diff --git a/lib/sh/times.c b/lib/sh/times.c
index 47ddf577..2423078a 100644
--- a/lib/sh/times.c
+++ b/lib/sh/times.c
@@ -1,6 +1,6 @@
/* times.c - times(3) library function */
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -30,7 +30,7 @@
# include <sys/resource.h>
#endif /* HAVE_SYS_RESOURCE_H && HAVE_GETRUSAGE */
-extern long get_clk_tck __P((void));
+extern long get_clk_tck PARAMS((void));
#define CONVTCK(r) (r.tv_sec * clk_tck + r.tv_usec / (1000000 / clk_tck))
@@ -58,7 +58,7 @@ times(tms)
tms->tms_cutime = CONVTCK(ru.ru_utime);
tms->tms_cstime = CONVTCK(ru.ru_stime);
- if (gettimeofday(&tv, (struct timezone *) 0) < 0)
+ if (gettimeofday(&tv, NULL) < 0)
return ((clock_t)-1);
rv = (clock_t)(CONVTCK(tv));
#else /* !HAVE_GETRUSAGE */
diff --git a/lib/sh/timeval.c b/lib/sh/timeval.c
index c4b61dc8..f2ca7624 100644
--- a/lib/sh/timeval.c
+++ b/lib/sh/timeval.c
@@ -67,6 +67,32 @@ addtimeval (d, t1, t2)
return d;
}
+struct timeval *
+multimeval (d, m)
+ struct timeval *d;
+ int m;
+{
+ time_t t;
+
+ t = d->tv_usec * m;
+ d->tv_sec = d->tv_sec * m + t / 1000000;
+ d->tv_usec = t % 1000000;
+ return d;
+}
+
+struct timeval *
+divtimeval (d, m)
+ struct timeval *d;
+ int m;
+{
+ time_t t;
+
+ t = d->tv_sec;
+ d->tv_sec = t / m;
+ d->tv_usec = (d->tv_usec + 1000000 * (t % m)) / m;
+ return d;
+}
+
/* Do "cpu = ((user + sys) * 10000) / real;" with timevals.
Barely-tested code from Deven T. Corzine <deven@ties.org>. */
int
@@ -149,4 +175,5 @@ print_timeval (fp, tvp)
fprintf (fp, "%ldm%d%c%03ds", minutes, seconds, locale_decpoint (), seconds_fraction);
}
+
#endif /* HAVE_TIMEVAL */
diff --git a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c
index e41e45bd..ef8b067b 100644
--- a/lib/sh/tmpfile.c
+++ b/lib/sh/tmpfile.c
@@ -2,7 +2,7 @@
* tmpfile.c - functions to create and safely open temp files for the shell.
*/
-/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -54,8 +54,8 @@ extern int errno;
extern pid_t dollar_dollar_pid;
-static char *get_sys_tmpdir __P((void));
-static char *get_tmpdir __P((int));
+static char *get_sys_tmpdir PARAMS((void));
+static char *get_tmpdir PARAMS((int));
static char *sys_tmpdir = (char *)NULL;
static int ntmpfiles;
@@ -146,9 +146,17 @@ sh_mktmpname (nameroot, flags)
tdlen = strlen (tdir);
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
+ if (nameroot == 0)
+ flags &= ~MT_TEMPLATE;
+
+ if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
+ flags &= ~MT_TEMPLATE;
#ifdef USE_MKTEMP
- sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+ if (flags & MT_TEMPLATE)
+ strcpy (filename, nameroot);
+ else
+ sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
if (mktemp (filename) == 0)
{
free (filename);
@@ -192,9 +200,17 @@ sh_mktmpfd (nameroot, flags, namep)
tdlen = strlen (tdir);
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
+ if (nameroot == 0)
+ flags &= ~MT_TEMPLATE;
+
+ if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
+ flags &= ~MT_TEMPLATE;
#ifdef USE_MKSTEMP
- sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+ if (flags & MT_TEMPLATE)
+ strcpy (filename, nameroot);
+ else
+ sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
fd = mkstemp (filename);
if (fd < 0 || namep == 0)
{
@@ -245,3 +261,51 @@ sh_mktmpfp (nameroot, flags, namep)
close (fd);
return fp;
}
+
+char *
+sh_mktmpdir (nameroot, flags)
+ char *nameroot;
+ int flags;
+{
+ char *filename, *tdir, *lroot, *dirname;
+ int fd, tdlen;
+
+#ifdef USE_MKDTEMP
+ filename = (char *)xmalloc (PATH_MAX + 1);
+ tdir = get_tmpdir (flags);
+ tdlen = strlen (tdir);
+
+ lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
+ if (nameroot == 0)
+ flags &= ~MT_TEMPLATE;
+
+ if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
+ flags &= ~MT_TEMPLATE;
+
+ if (flags & MT_TEMPLATE)
+ strcpy (filename, nameroot);
+ else
+ sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+ dirname = mkdtemp (filename);
+ if (dirname == 0)
+ {
+ free (filename);
+ filename = NULL;
+ }
+ return dirname;
+#else /* !USE_MKDTEMP */
+ filename = (char *)NULL;
+ do
+ {
+ filename = sh_mktmpname (nameroot, flags);
+ fd = mkdir (filename, 0700);
+ if (fd == 0)
+ break;
+ free (filename);
+ filename = (char *)NULL;
+ }
+ while (fd < 0 && errno == EEXIST);
+
+ return (filename);
+#endif /* !USE_MKDTEMP */
+}
diff --git a/lib/sh/uconvert.c b/lib/sh/uconvert.c
index 3d656df0..457552eb 100644
--- a/lib/sh/uconvert.c
+++ b/lib/sh/uconvert.c
@@ -1,7 +1,7 @@
/* uconvert - convert string representations of decimal numbers into whole
number/fractional value pairs. */
-/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008,2009,2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -23,16 +23,7 @@
#include "bashtypes.h"
-#if defined (TIME_WITH_SYS_TIME)
-# include <sys/time.h>
-# include <time.h>
-#else
-# if defined (HAVE_SYS_TIME_H)
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
+#include "posixtime.h"
#if defined (HAVE_UNISTD_H)
#include <unistd.h>
@@ -50,6 +41,7 @@
do { \
if (ip) *ip = ipart * mult; \
if (up) *up = upart; \
+ if (ep) *ep = p; \
return (x); \
} while (0)
@@ -61,12 +53,14 @@ static int multiplier[7] = { 1, 100000, 10000, 1000, 100, 10, 1 };
/* Take a decimal number int-part[.[micro-part]] and convert it to the whole
and fractional portions. The fractional portion is returned in
millionths (micro); callers are responsible for multiplying appropriately.
+ EP, if non-null, gets the address of the character where conversion stops.
Return 1 if value converted; 0 if invalid integer for either whole or
fractional parts. */
int
-uconvert(s, ip, up)
+uconvert(s, ip, up, ep)
char *s;
long *ip, *up;
+ char **ep;
{
int n, mult;
long ipart, upart;
@@ -102,7 +96,14 @@ uconvert(s, ip, up)
for (n = 0; n < 6 && p[n]; n++)
{
if (DIGIT(p[n]) == 0)
- RETURN(0);
+ {
+ if (ep)
+ {
+ upart *= multiplier[n];
+ p += n; /* To set EP */
+ }
+ RETURN(0);
+ }
upart = (upart * 10) + (p[n] - '0');
}
@@ -112,5 +113,12 @@ uconvert(s, ip, up)
if (n == 6 && p[6] >= '5' && p[6] <= '9')
upart++; /* round up 1 */
+ if (ep)
+ {
+ p += n;
+ while (DIGIT(*p))
+ p++;
+ }
+
RETURN(1);
}
diff --git a/lib/sh/ufuncs.c b/lib/sh/ufuncs.c
index ad9284cc..4dc4853b 100644
--- a/lib/sh/ufuncs.c
+++ b/lib/sh/ufuncs.c
@@ -1,6 +1,6 @@
/* ufuncs - sleep and alarm functions that understand fractional values */
-/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,16 +22,7 @@
#include "bashtypes.h"
-#if defined (TIME_WITH_SYS_TIME)
-# include <sys/time.h>
-# include <time.h>
-#else
-# if defined (HAVE_SYS_TIME_H)
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
+#include "posixtime.h"
#if defined (HAVE_UNISTD_H)
#include <unistd.h>
@@ -130,7 +121,7 @@ fsleep(sec, usec)
#endif
e = errno;
if (r < 0 && errno == EINTR)
- QUIT; /* just signals, no traps */
+ return -1; /* caller will handle */
errno = e;
}
while (r < 0 && errno == EINTR);
diff --git a/lib/sh/unicode.c b/lib/sh/unicode.c
index fe13c4a0..d95d1e25 100644
--- a/lib/sh/unicode.c
+++ b/lib/sh/unicode.c
@@ -1,6 +1,6 @@
/* unicode.c - functions to convert unicode characters */
-/* Copyright (C) 2010-2016 Free Software Foundation, Inc.
+/* Copyright (C) 2010-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -50,9 +50,9 @@
#endif /* !STREQ */
#if defined (HAVE_LOCALE_CHARSET)
-extern const char *locale_charset __P((void));
+extern const char *locale_charset PARAMS((void));
#else
-extern char *get_locale_var __P((char *));
+extern char *get_locale_var PARAMS((char *));
#endif
extern int locale_utf8locale;
@@ -196,7 +196,7 @@ u32toutf8 (wc, s)
}
else if (wc < 0x080000000)
{
- s[0] = (wc >> 30) | 0xf8;
+ s[0] = (wc >> 30) | 0xfc;
s[1] = ((wc >> 24) & 0x3f) | 0x80;
s[2] = ((wc >> 18) & 0x3f) | 0x80;
s[3] = ((wc >> 12) & 0x3f) | 0x80;
@@ -216,21 +216,21 @@ u32toutf8 (wc, s)
int
u32toutf16 (c, s)
u_bits32_t c;
- unsigned short *s;
+ wchar_t *s;
{
int l;
l = 0;
if (c < 0x0d800 || (c >= 0x0e000 && c <= 0x0ffff))
{
- s[0] = (unsigned short) (c & 0xFFFF);
+ s[0] = (wchar_t) (c & 0xFFFF);
l = 1;
}
else if (c >= 0x10000 && c <= 0x010ffff)
{
c -= 0x010000;
- s[0] = (unsigned short)((c >> 10) + 0xd800);
- s[1] = (unsigned short)((c & 0x3ff) + 0xdc00);
+ s[0] = (wchar_t)((c >> 10) + 0xd800);
+ s[1] = (wchar_t)((c & 0x3ff) + 0xdc00);
l = 2;
}
s[l] = 0;
diff --git a/lib/sh/utf8.c b/lib/sh/utf8.c
index d27fcf54..fed25226 100644
--- a/lib/sh/utf8.c
+++ b/lib/sh/utf8.c
@@ -76,13 +76,13 @@ utf8_mbsnlen(src, srclen, maxlen)
return (count);
}
-/* Adapted from GNU gnulib */
+/* Adapted from GNU gnulib. Handles UTF-8 characters up to 4 bytes long */
int
utf8_mblen (s, n)
const char *s;
size_t n;
{
- unsigned char c, c1;
+ unsigned char c, c1, c2, c3;
if (s == 0)
return (0); /* no shift states */
@@ -97,25 +97,74 @@ utf8_mblen (s, n)
c1 = (unsigned char)s[1];
if (c < 0xe0)
{
- if (n >= 2 && (s[1] ^ 0x80) < 0x40)
+ if (n == 1)
+ return -2;
+
+ /*
+ * c c1
+ *
+ * U+0080..U+07FF C2..DF 80..BF
+ */
+
+ if (n >= 2 && (c1 ^ 0x80) < 0x40) /* 0x80..0xbf */
return 2;
}
else if (c < 0xf0)
{
- if (n >= 3
- && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
+ if (n == 1)
+ return -2;
+
+ /*
+ * c c1 c2
+ *
+ * U+0800..U+0FFF E0 A0..BF 80..BF
+ * U+1000..U+CFFF E1..EC 80..BF 80..BF
+ * U+D000..U+D7FF ED 80..9F 80..BF
+ * U+E000..U+FFFF EE..EF 80..BF 80..BF
+ */
+
+ if ((c1 ^ 0x80) < 0x40
&& (c >= 0xe1 || c1 >= 0xa0)
&& (c != 0xed || c1 < 0xa0))
- return 3;
+ {
+ if (n == 2)
+ return -2; /* incomplete */
+
+ c2 = (unsigned char)s[2];
+ if ((c2 ^ 0x80) < 0x40)
+ return 3;
+ }
}
- else if (c < 0xf8)
+ else if (c <= 0xf4)
{
- if (n >= 4
- && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
- && (s[3] ^ 0x80) < 0x40
+ if (n == 1)
+ return -2;
+
+ /*
+ * c c1 c2 c3
+ *
+ * U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
+ * U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
+ * U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
+ */
+ if (((c1 ^ 0x80) < 0x40)
&& (c >= 0xf1 || c1 >= 0x90)
&& (c < 0xf4 || (c == 0xf4 && c1 < 0x90)))
- return 4;
+ {
+ if (n == 2)
+ return -2; /* incomplete */
+
+ c2 = (unsigned char)s[2];
+ if ((c2 ^ 0x80) < 0x40)
+ {
+ if (n == 3)
+ return -2;
+
+ c3 = (unsigned char)s[3];
+ if ((c3 ^ 0x80) < 0x40)
+ return 4;
+ }
+ }
}
}
/* invalid or incomplete multibyte character */
diff --git a/lib/sh/winsize.c b/lib/sh/winsize.c
index ab83433a..861c7c89 100644
--- a/lib/sh/winsize.c
+++ b/lib/sh/winsize.c
@@ -1,6 +1,6 @@
/* winsize.c - handle window size changes and information. */
-/* Copyright (C) 2005-2015 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -68,9 +68,9 @@ extern int errno;
extern int shell_tty;
#if defined (READLINE)
-extern void rl_set_screen_size __P((int, int));
+extern void rl_set_screen_size PARAMS((int, int));
#endif
-extern void sh_set_lines_and_columns __P((int, int));
+extern void sh_set_lines_and_columns PARAMS((int, int));
void
get_new_window_size (from_sig, rp, cp)
diff --git a/lib/sh/zcatfd.c b/lib/sh/zcatfd.c
index bdbcd910..aa8199fd 100644
--- a/lib/sh/zcatfd.c
+++ b/lib/sh/zcatfd.c
@@ -1,6 +1,6 @@
/* zcatfd - copy contents of file descriptor to another */
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -34,8 +34,12 @@
extern int errno;
#endif
-extern ssize_t zread __P((int, char *, size_t));
-extern int zwrite __P((int, char *, ssize_t));
+#ifndef ZBUFSIZ
+# define ZBUFSIZ 4096
+#endif
+
+extern ssize_t zread PARAMS((int, char *, size_t));
+extern int zwrite PARAMS((int, char *, ssize_t));
/* Dump contents of file descriptor FD to OFD. FN is the filename for
error messages (not used right now). */
@@ -46,7 +50,7 @@ zcatfd (fd, ofd, fn)
{
ssize_t nr;
int rval;
- char lbuf[128];
+ char lbuf[ZBUFSIZ];
rval = 0;
while (1)
diff --git a/lib/sh/zgetline.c b/lib/sh/zgetline.c
index a686ba3d..8ded1442 100644
--- a/lib/sh/zgetline.c
+++ b/lib/sh/zgetline.c
@@ -1,7 +1,7 @@
/* zgetline - read a line of input from a specified file descriptor and return
a pointer to a newly-allocated buffer containing the data. */
-/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -34,13 +34,13 @@
extern int errno;
#endif
-extern ssize_t zread __P((int, char *, size_t));
-extern ssize_t zreadc __P((int, char *));
-extern ssize_t zreadintr __P((int, char *, size_t));
-extern ssize_t zreadcintr __P((int, char *));
+extern ssize_t zread PARAMS((int, char *, size_t));
+extern ssize_t zreadc PARAMS((int, char *));
+extern ssize_t zreadintr PARAMS((int, char *, size_t));
+extern ssize_t zreadcintr PARAMS((int, char *));
-typedef ssize_t breadfunc_t __P((int, char *, size_t));
-typedef ssize_t creadfunc_t __P((int, char *));
+typedef ssize_t breadfunc_t PARAMS((int, char *, size_t));
+typedef ssize_t creadfunc_t PARAMS((int, char *));
/* Initial memory allocation for automatic growing buffer in zreadlinec */
#define GET_LINE_INITIAL_ALLOCATION 16
diff --git a/lib/sh/zmapfd.c b/lib/sh/zmapfd.c
index e7208921..f9e9ed71 100644
--- a/lib/sh/zmapfd.c
+++ b/lib/sh/zmapfd.c
@@ -1,6 +1,6 @@
/* zmapfd - read contents of file descriptor into a newly-allocated buffer */
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -36,7 +36,11 @@
extern int errno;
#endif
-extern ssize_t zread __P((int, char *, size_t));
+#ifndef ZBUFSIZ
+# define ZBUFSIZ 4096
+#endif
+
+extern ssize_t zread PARAMS((int, char *, size_t));
/* Dump contents of file descriptor FD to *OSTR. FN is the filename for
error messages (not used right now). */
@@ -48,12 +52,12 @@ zmapfd (fd, ostr, fn)
{
ssize_t nr;
int rval;
- char lbuf[128];
+ char lbuf[ZBUFSIZ];
char *result;
int rsize, rind;
rval = 0;
- result = (char *)xmalloc (rsize = 64);
+ result = (char *)xmalloc (rsize = ZBUFSIZ);
rind = 0;
while (1)
@@ -72,7 +76,7 @@ zmapfd (fd, ostr, fn)
return -1;
}
- RESIZE_MALLOCED_BUFFER (result, rind, nr, rsize, 128);
+ RESIZE_MALLOCED_BUFFER (result, rind, nr, rsize, ZBUFSIZ);
memcpy (result+rind, lbuf, nr);
rind += nr;
}
diff --git a/lib/sh/zread.c b/lib/sh/zread.c
index 8b7ecedf..71a06a76 100644
--- a/lib/sh/zread.c
+++ b/lib/sh/zread.c
@@ -1,6 +1,6 @@
/* zread - read data from file descriptor into buffer with retries */
-/* Copyright (C) 1999-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -37,6 +37,10 @@ extern int errno;
# define SEEK_CUR 1
#endif
+#ifndef ZBUFSIZ
+# define ZBUFSIZ 4096
+#endif
+
extern int executing_builtin;
extern void check_signals_and_traps (void);
@@ -55,12 +59,17 @@ zread (fd, buf, len)
check_signals (); /* check for signals before a blocking read */
while ((r = read (fd, buf, len)) < 0 && errno == EINTR)
- /* XXX - bash-5.0 */
- /* We check executing_builtin and run traps here for backwards compatibility */
- if (executing_builtin)
- check_signals_and_traps (); /* XXX - should it be check_signals()? */
- else
- check_signals ();
+ {
+ int t;
+ t = errno;
+ /* XXX - bash-5.0 */
+ /* We check executing_builtin and run traps here for backwards compatibility */
+ if (executing_builtin)
+ check_signals_and_traps (); /* XXX - should it be check_signals()? */
+ else
+ check_signals ();
+ errno = t;
+ }
return r;
}
@@ -112,7 +121,7 @@ zreadintr (fd, buf, len)
in read(2). This does some local buffering to avoid many one-character
calls to read(2), like those the `read' builtin performs. */
-static char lbuf[128];
+static char lbuf[ZBUFSIZ];
static size_t lind, lused;
ssize_t