dash: synced with latest upstream git as of 2023-01-09

This commit is contained in:
Juergen Daubert 2024-03-06 11:59:15 +01:00
parent d4a30d65d4
commit 76d014e128
3 changed files with 740 additions and 4 deletions

View File

@ -1,5 +1,6 @@
untrusted comment: verify with /etc/ports/core.pub
RWRJc1FUaeVeqpqlDdEYV0IlJIn9Hz0JX4k7Hf7kJr7XTwOZX0I+agEiSyK5naIUV6Zi90Jj1HW1vzxzK6dos96UJI5ZmfqAsAA=
SHA256 (Pkgfile) = e439121090fef16525e2fb1ccc74d12b0dc5ff3c44391b0b949831072c38a8d9
RWRJc1FUaeVequDaIQA9vE05EjKRWRPtCCawlhf/SkB0UM4rQbxgjdg3cVllnqHb5vY/CSmB4DBnG+DknIZnR/NEWzoRvz+V1ww=
SHA256 (Pkgfile) = c1e2b59a432234fb21d5bc63e898be9daa856ea40752272a0376241729010686
SHA256 (.footprint) = 3a7bbfc94c40691a4871ab86fb334dfcbc7f98f74ed06847f091ba0b1721d540
SHA256 (dash-0.5.12.tar.gz) = 6a474ac46e8b0b32916c4c60df694c82058d3297d8b385b74508030ca4a8f28a
SHA256 (dash-20230109.patch) = 8a0c2b670b18cb0a4b7f5816e89e11dcebf8e5638cd4d8041e839f83bb39872c

View File

@ -4,14 +4,20 @@
name=dash
version=0.5.12
release=1
source=(http://gondor.apana.org.au/~herbert/dash/files/$name-$version.tar.gz)
release=2
source=(http://gondor.apana.org.au/~herbert/dash/files/$name-$version.tar.gz
$name-20230109.patch)
build() {
cd $name-$version
patch -p1 -i $SRC/$name-20230109.patch
autoreconf -if
./configure --prefix=/usr --bindir=/bin
make
make DESTDIR=$PKG install
ln -s dash $PKG/bin/sh
ln -s dash.1 $PKG/usr/share/man/man1/sh.1
}

729
dash/dash-20230109.patch Normal file
View File

@ -0,0 +1,729 @@
diff --git a/configure.ac b/configure.ac
index 52aa429..5524650 100644
--- a/configure.ac
+++ b/configure.ac
@@ -177,6 +177,17 @@ if test "$have_st_mtim" = "yes"; then
[Define if your `struct stat' has `st_mtim'])
fi
+dnl F_DUPFD_CLOEXEC is a mandatory part of POSIX since Issue 7
+AC_MSG_CHECKING(for F_DUPFD_CLOEXEC)
+AC_COMPILE_IFELSE(
+[AC_LANG_PROGRAM([#include <unistd.h>
+#include <fcntl.h>],
+[return fcntl(0, F_DUPFD_CLOEXEC, 0)])],
+have_dupfd_cloexec=1, have_dupfd_cloexec=0)
+AC_MSG_RESULT($(expr yes \& $have_dupfd_cloexec \| no))
+AC_DEFINE_UNQUOTED([HAVE_F_DUPFD_CLOEXEC], [$have_dupfd_cloexec],
+ [Define to 1 your system supports F_DUPFD_CLOEXEC])
+
AC_ARG_WITH(libedit, AS_HELP_STRING(--with-libedit, [Compile with libedit support]))
use_libedit=
if test "$with_libedit" = "yes"; then
diff --git a/src/alias.c b/src/alias.c
index daeacbb..fcad43b 100644
--- a/src/alias.c
+++ b/src/alias.c
@@ -197,7 +197,8 @@ freealias(struct alias *ap) {
void
printalias(const struct alias *ap) {
- out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
+ out1str(single_quote(ap->name));
+ out1fmt("=%s\n", single_quote(ap->val));
}
STATIC struct alias **
diff --git a/src/dash.1 b/src/dash.1
index ff02237..d3893bc 100644
--- a/src/dash.1
+++ b/src/dash.1
@@ -1095,6 +1095,8 @@ etc).
.It :
.It true
A null command that returns a 0 (true) exit value.
+.It false
+A null command that returns a 1 (false) exit value.
.It \&. file
The commands in the specified file are read and executed by the shell.
.It alias Op Ar name Ns Op Ar "=string ..."
@@ -1143,8 +1145,8 @@ Do not execute the command but
search for the command and print the absolute pathname
of utilities, the name for builtins or the expansion of aliases.
.El
-.It cd Ar -
-.It Xo cd Op Fl LP
+.It cd|chdir Ar -
+.It Xo cd|chdir Op Fl LP
.Op Ar directory
.Xc
Switch to the specified directory (default
@@ -1342,13 +1344,12 @@ The number of previous commands that are accessible.
.El
.It fg Op Ar job
Move the specified job or the current job to the foreground.
-.It getopts Ar optstring var
+.It getopts Ar optstring var Op Ar arg ...
The
.Tn POSIX
.Ic getopts
command, not to be confused with the
-.Em Bell Labs
--derived
+.Em Bell Labs Ns -derived
.Xr getopt 1 .
.Pp
The first argument should be a series of letters, each of which may be
@@ -1386,6 +1387,12 @@ then
.Ev OPTARG
will be unset.
.Pp
+By default, the variables
+.Va $1 , ... , $n
+are inspected; if
+.Ar arg Ns s
+are specified, they'll be parsed instead.
+.Pp
.Va optstring
is a string of recognized option letters (see
.Xr getopt 3 ) .
@@ -1430,7 +1437,7 @@ do
\\?) echo $USAGE; exit 1;;
esac
done
-shift `expr $OPTIND - 1`
+shift $((OPTIND - 1))
.Ed
.Pp
This code will accept any of the following as equivalent:
@@ -1441,7 +1448,8 @@ cmd \-a \-c arg file file
cmd \-carg -a file file
cmd \-a \-carg \-\- file file
.Ed
-.It hash Fl rv Ar command ...
+.It hash Op Ar command ...
+.It hash Fl r
The shell maintains a hash table which remembers the
locations of commands.
With no arguments whatsoever,
@@ -1457,13 +1465,51 @@ With arguments, the
.Ic hash
command removes the specified commands from the hash table (unless
they are functions) and then locates them.
-With the
-.Fl v
-option, hash prints the locations of the commands as it finds them.
The
.Fl r
option causes the hash command to delete all the entries in the hash table
except for functions.
+.It jobs Oo Fl lp Oc Op Ar job ...
+Display the status of all, or just the specified,
+.Ar job Ns s :
+.Bl -tag -compact -offset 5n -width "By default"
+.It By default
+display the job number, currency
+.Pq Sy +-
+status, if any, the job state, and its shell command.
+.It Fl l
+also output the PID of the group leader, and just the PID and shell commands
+of other members of the job.
+.It Fl p
+Display only leader PIDs, one per line.
+.El
+.It kill Oo Fl s Ar sigspec | Fl Ns Ar signum | Fl Ns Ar sigspec Oc Op Ar pid | job ...
+Equivalent to
+.Xr kill 1 ,
+but a
+.Ar job
+spec may also be specified.
+Signals can be either case-insensitive names without
+.Dv SIG
+prefixes or decimal numbers; the default is
+.Dv TERM .
+.It kill Fl l Op Ar signum | exitstatus
+List available signal names without the
+.Dv SIG
+prefix
+.Pq Ar sigspec Ns s .
+If
+.Ar signum
+specified, display just the
+.Ar sigspec
+for that signal.
+If
+.Ar exitstatus
+specified
+.Pq > Sy 128 ,
+display just the
+.Ar sigspec
+that caused it.
.It pwd Op Fl LP
builtin command remembers what the current directory
is rather than recomputing it each time.
@@ -1528,41 +1574,36 @@ With the
option specified the output will be formatted suitably for non-interactive use.
.\".Pp
.It Xo printf Ar format
-.Op Ar arguments ...
+.Oo Ar value Oc Ns ...
.Xc
.Ic printf
-formats and prints its arguments, after the first, under control
-of the
-.Ar format .
-The
-.Ar format
-is a character string which contains three types of objects: plain characters,
+formats and prints its arguments according to
+.Ar format ,
+a character string which contains three types of objects: plain characters,
which are simply copied to standard output, character escape sequences which
are converted and copied to the standard output, and format specifications,
each of which causes printing of the next successive
-.Ar argument .
+.Ar value .
.Pp
-The
-.Ar arguments
-after the first are treated as strings if the corresponding format is
+Each
+.Ar value
+is treated as a string if the corresponding format specification is
either
.Cm b ,
-.Cm c
+.Cm c ,
or
.Cm s ;
-otherwise it is evaluated as a C constant, with the following extensions:
-.Pp
+otherwise it is evaluated as a C constant, with the following additions:
.Bl -bullet -offset indent -compact
.It
A leading plus or minus sign is allowed.
.It
-If the leading character is a single or double quote, the value is the
-.Tn ASCII
-code of the next character.
+If the leading character is a single or double quote, the value of the next byte.
.El
.Pp
-The format string is reused as often as necessary to satisfy the
-.Ar arguments .
+The format string is reused as often as necessary until all
+.Ar value Ns s
+are consumed.
Any extra format specifications are evaluated with zero or the null
string.
.Pp
@@ -2121,7 +2162,7 @@ printed; for commands and tracked aliases the complete pathname of the
command is printed.
.It ulimit Xo
.Op Fl H \*(Ba Fl S
-.Op Fl a \*(Ba Fl tfdscmlpnv Op Ar value
+.Op Fl a \*(Ba Fl tfdscmlpnvwr Op Ar value
.Xc
Inquire about or set the hard or soft limits on processes or set new
limits.
@@ -2174,6 +2215,8 @@ show or set the limit on the number files a process can have open at once
.It Fl v
show or set the limit on the total virtual memory that can be
in use by a process (in kilobytes)
+.It Fl w
+show or set the limit on the total number of locks held by a process
.It Fl r
show or set the limit on the real-time scheduling priority of a process
.El
diff --git a/src/exec.c b/src/exec.c
index 87354d4..83cba94 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -36,6 +36,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <stdlib.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
@@ -271,11 +272,16 @@ hashcmd(int argc, char **argv)
int c;
struct cmdentry entry;
char *name;
+ bool clear;
- while ((c = nextopt("r")) != '\0') {
+ clear = false;
+ while ((c = nextopt("r")) != '\0')
+ clear = true;
+ if(clear) {
clearcmdentry();
return 0;
}
+
if (*argptr == NULL) {
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
@@ -760,11 +766,11 @@ unsetfunc(const char *name)
int
typecmd(int argc, char **argv)
{
- int i;
int err = 0;
- for (i = 1; i < argc; i++) {
- err |= describe_command(out1, argv[i], NULL, 1);
+ nextopt(nullstr);
+ while (*argptr) {
+ err |= describe_command(out1, *argptr++, NULL, 1);
}
return err;
}
diff --git a/src/input.c b/src/input.c
index ec075f5..38969a7 100644
--- a/src/input.c
+++ b/src/input.c
@@ -54,9 +54,7 @@
#include "alias.h"
#include "parser.h"
#include "main.h"
-#ifndef SMALL
#include "myhistedit.h"
-#endif
#define IBUFSIZ (BUFSIZ + 1)
@@ -77,6 +75,7 @@ INCLUDE <stdio.h>
INCLUDE <unistd.h>
INCLUDE "input.h"
INCLUDE "error.h"
+INCLUDE "syntax.h"
INIT {
basepf.nextc = basepf.buf = basebuf;
@@ -85,9 +84,12 @@ INIT {
RESET {
/* clear input buffer */
- basepf.lleft = basepf.nleft = 0;
- basepf.unget = 0;
popallfiles();
+ basepf.unget = 0;
+ while (basepf.lastc[0] != '\n' &&
+ basepf.lastc[0] != PEOF &&
+ !int_pending())
+ pgetc();
}
FORKRESET {
@@ -159,6 +161,17 @@ int pgetc(void)
return __pgetc();
}
+static int stdin_clear_nonblock(void)
+{
+ int flags = fcntl(0, F_GETFL, 0);
+
+ if (flags >= 0) {
+ flags &=~ O_NONBLOCK;
+ flags = fcntl(0, F_SETFL, flags);
+ }
+
+ return flags;
+}
static int
preadfd(void)
@@ -195,22 +208,38 @@ retry:
} else
#endif
+ if (parsefile->fd)
nr = read(parsefile->fd, buf, IBUFSIZ - 1);
+ else {
+ unsigned len = IBUFSIZ - 1;
+
+ nr = 0;
+ do {
+ int err;
+
+ err = read(0, buf, 1);
+ if (err <= 0) {
+ if (nr)
+ break;
+
+ nr = err;
+ if (errno != EWOULDBLOCK)
+ break;
+ if (stdin_clear_nonblock() < 0)
+ break;
+
+ out2str("sh: turning off NDELAY mode\n");
+ goto retry;
+ }
+
+ nr++;
+ } while (!IS_DEFINED_SMALL && *buf++ != '\n' && --len);
+ }
if (nr < 0) {
if (errno == EINTR)
goto retry;
- if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
- int flags = fcntl(0, F_GETFL, 0);
- if (flags >= 0 && flags & O_NONBLOCK) {
- flags &=~ O_NONBLOCK;
- if (fcntl(0, F_SETFL, flags) >= 0) {
- out2str("sh: turning off NDELAY mode\n");
- goto retry;
- }
- }
- }
}
return nr;
}
@@ -226,12 +255,11 @@ retry:
static int preadbuffer(void)
{
- char *q;
- int more;
-#ifndef SMALL
+ int first = whichprompt == 1;
int something;
-#endif
char savec;
+ int more;
+ char *q;
if (unlikely(parsefile->strpush)) {
popstring();
@@ -241,11 +269,11 @@ static int preadbuffer(void)
return PEOF;
flushall();
- more = parsefile->lleft;
+ more = input_get_lleft(parsefile);
if (more <= 0) {
again:
if ((more = preadfd()) <= 0) {
- parsefile->lleft = parsefile->nleft = 0;
+ input_set_lleft(parsefile, parsefile->nleft = 0);
return PEOF;
}
}
@@ -253,37 +281,38 @@ again:
q = parsefile->nextc;
/* delete nul characters */
-#ifndef SMALL
- something = 0;
-#endif
+ something = !first;
for (;;) {
int c;
more--;
c = *q;
- if (!c)
+ if (!c) {
memmove(q, q + 1, more);
- else {
- q++;
+ goto check;
+ }
- if (c == '\n') {
- parsefile->nleft = q - parsefile->nextc - 1;
- break;
- }
+ q++;
-#ifndef SMALL
- switch (c) {
- default:
- something = 1;
- /* fall through */
- case '\t':
- case ' ':
- break;
- }
-#endif
+ if (IS_DEFINED_SMALL)
+ goto check;
+
+ switch (c) {
+ case '\n':
+ parsefile->nleft = q - parsefile->nextc - 1;
+ goto check;
+
+ default:
+ something = 1;
+ /* fall through */
+
+ case '\t':
+ case ' ':
+ break;
}
+check:
if (more <= 0) {
parsefile->nleft = q - parsefile->nextc - 1;
if (parsefile->nleft < 0)
@@ -291,20 +320,19 @@ again:
break;
}
}
- parsefile->lleft = more;
+ input_set_lleft(parsefile, more);
- savec = *q;
+ if (!IS_DEFINED_SMALL)
+ savec = *q;
*q = '\0';
-#ifndef SMALL
if (parsefile->fd == 0 && hist && something) {
HistEvent he;
INTOFF;
- history(hist, &he, whichprompt == 1? H_ENTER : H_APPEND,
+ history(hist, &he, first ? H_ENTER : H_APPEND,
parsefile->nextc);
INTON;
}
-#endif
if (vflag) {
out2str(parsefile->nextc);
@@ -313,7 +341,8 @@ again:
#endif
}
- *q = savec;
+ if (!IS_DEFINED_SMALL)
+ *q = savec;
return (signed char)*parsefile->nextc++;
}
@@ -428,7 +457,7 @@ setinputfd(int fd, int push)
parsefile->fd = fd;
if (parsefile->buf == NULL)
parsefile->buf = ckmalloc(IBUFSIZ);
- parsefile->lleft = parsefile->nleft = 0;
+ input_set_lleft(parsefile, parsefile->nleft = 0);
plinno = 1;
}
diff --git a/src/input.h b/src/input.h
index 8c39f33..1ff5773 100644
--- a/src/input.h
+++ b/src/input.h
@@ -34,6 +34,12 @@
* @(#)input.h 8.2 (Berkeley) 5/4/95
*/
+#ifdef SMALL
+#define IS_DEFINED_SMALL 1
+#else
+#define IS_DEFINED_SMALL 0
+#endif
+
/* PEOF (the end of file marker) is defined in syntax.h */
enum {
@@ -70,7 +76,9 @@ struct parsefile {
int linno; /* current line */
int fd; /* file descriptor (or -1 if string) */
int nleft; /* number of chars left in this line */
+#ifndef SMALL
int lleft; /* number of chars left in this buffer */
+#endif
char *nextc; /* next char in buffer */
char *buf; /* input buffer */
struct strpush *strpush; /* for pushing strings at this level */
@@ -104,3 +112,19 @@ void setinputstring(char *);
void popfile(void);
void unwindfiles(struct parsefile *);
void popallfiles(void);
+
+static inline int input_get_lleft(struct parsefile *pf)
+{
+#ifdef SMALL
+ return 0;
+#else
+ return pf->lleft;
+#endif
+}
+
+static inline void input_set_lleft(struct parsefile *pf, int len)
+{
+#ifndef SMALL
+ pf->lleft = len;
+#endif
+}
diff --git a/src/miscbltin.c b/src/miscbltin.c
index 5ccbbcb..e553f9e 100644
--- a/src/miscbltin.c
+++ b/src/miscbltin.c
@@ -440,6 +440,9 @@ ulimitcmd(int argc, char **argv)
#endif
#ifdef RLIMIT_LOCKS
"w"
+#endif
+#ifdef RLIMIT_RTPRIO
+ "r"
#endif
)) != '\0')
switch (optc) {
diff --git a/src/myhistedit.h b/src/myhistedit.h
index 22e5c43..1736f62 100644
--- a/src/myhistedit.h
+++ b/src/myhistedit.h
@@ -31,9 +31,27 @@
* @(#)myhistedit.h 8.2 (Berkeley) 5/4/95
*/
+#ifdef SMALL
+typedef void History;
+typedef void EditLine;
+typedef int HistEvent;
+
+enum {
+ H_APPEND,
+ H_ENTER,
+};
+
+#define hist NULL
+
+static inline void history(History *h, HistEvent *he, int action, char *p)
+{
+}
+#else
#include <histedit.h>
extern History *hist;
+#endif
+
extern EditLine *el;
extern int displayhist;
diff --git a/src/options.c b/src/options.c
index a46c23b..2d4bd3b 100644
--- a/src/options.c
+++ b/src/options.c
@@ -409,8 +409,11 @@ getoptscmd(int argc, char **argv)
{
char **optbase;
+ nextopt(nullstr);
+ argc -= argptr - argv - 1;
+ argv = argptr - 1;
if (argc < 3)
- sh_error("Usage: getopts optstring var [arg]");
+ sh_error("Usage: getopts optstring var [arg...]");
else if (argc == 3) {
optbase = shellparam.p;
if ((unsigned)shellparam.optind > shellparam.nparam + 1) {
diff --git a/src/parser.c b/src/parser.c
index a552c47..299c260 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -615,7 +615,7 @@ void fixredir(union node *n, const char *text, int err)
else {
if (err)
- synerror("Bad fd number");
+ sh_error("Bad fd number: %s", text);
else
n->ndup.vname = makename();
}
@@ -1360,12 +1360,10 @@ parsebackq: {
struct heredoc *saveheredoclist;
int uninitialized_var(saveprompt);
- str = NULL;
+ USTPUTC(CTLBACKQ, out);
+ str = stackblock();
savelen = out - (char *)stackblock();
- if (savelen > 0) {
- str = alloca(savelen);
- memcpy(str, stackblock(), savelen);
- }
+ grabstackblock(savelen);
if (oldstyle) {
/* We must read until the closing backquote, giving special
treatment to some slashes, and then push the string and
@@ -1445,12 +1443,7 @@ done:
/* Ignore any pushed back tokens left from the backquote parsing. */
if (oldstyle)
tokpushback = 0;
- out = growstackto(savelen + 1);
- if (str) {
- memcpy(out, str, savelen);
- STADJUST(savelen, out);
- }
- USTPUTC(CTLBACKQ, out);
+ out = stnputs(str, savelen, stackblock());
if (oldstyle)
goto parsebackq_oldreturn;
else
diff --git a/src/redir.c b/src/redir.c
index 5a5835c..631ddc9 100644
--- a/src/redir.c
+++ b/src/redir.c
@@ -446,13 +446,18 @@ savefd(int from, int ofd)
int newfd;
int err;
+#if HAVE_F_DUPFD_CLOEXEC
+ newfd = fcntl(from, F_DUPFD_CLOEXEC, 10);
+#else
newfd = fcntl(from, F_DUPFD, 10);
+#endif
+
err = newfd < 0 ? errno : 0;
if (err != EBADF) {
close(ofd);
if (err)
sh_error("%d: %s", from, strerror(err));
- else
+ else if(!HAVE_F_DUPFD_CLOEXEC)
fcntl(newfd, F_SETFD, FD_CLOEXEC);
}
diff --git a/src/var.c b/src/var.c
index ef9c2bd..b70d72c 100644
--- a/src/var.c
+++ b/src/var.c
@@ -154,6 +154,10 @@ RESET {
}
#endif
+static char *varnull(const char *s)
+{
+ return (strchr(s, '=') ?: nullstr - 1) + 1;
+}
/*
* This routine initializes the builtin variables. It is called when the
@@ -266,7 +270,7 @@ struct var *setvareq(char *s, int flags)
goto out;
if (vp->func && (flags & VNOFUNC) == 0)
- (*vp->func)(strchrnul(s, '=') + 1);
+ (*vp->func)(varnull(s));
if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
ckfree(vp->text);
@@ -531,7 +535,7 @@ poplocalvars(void)
unsetvar(vp->text);
} else {
if (vp->func)
- (*vp->func)(strchrnul(lvp->text, '=') + 1);
+ (*vp->func)(varnull(lvp->text));
if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
ckfree(vp->text);
vp->flags = lvp->flags;