aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-08-23 08:38:57 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-08-23 08:38:57 -0700
commit778eb08b81e53aa3ef5aa4a8e5564f929b784f0d (patch)
tree7ce23e3531a10e340b10108353577ac69b73542e
parentbdb5e3085365f05e8f32719e9d30f4383ab8a8bc (diff)
parenta61d42236f43ca0a9a08b7af5bfe341b43fc84b0 (diff)
downloadklibc-778eb08b81e53aa3ef5aa4a8e5564f929b784f0d.tar.gz
Merge commit 'maks/maks'klibc-1.5.5
-rw-r--r--usr/dash/README.klibc2
-rw-r--r--usr/dash/bltin/printf.c32
-rw-r--r--usr/dash/bltin/test.c3
-rw-r--r--usr/dash/config.h6
-rw-r--r--usr/dash/eval.c21
-rw-r--r--usr/dash/exec.c7
-rw-r--r--usr/dash/expand.c2
-rw-r--r--usr/dash/input.c11
-rw-r--r--usr/dash/jobs.c14
-rw-r--r--usr/dash/memalloc.h2
-rw-r--r--usr/dash/mkbuiltins2
-rw-r--r--usr/dash/mkinit.c9
-rw-r--r--usr/dash/parser.c1
-rw-r--r--usr/dash/parser.h2
-rw-r--r--usr/dash/redir.c144
-rw-r--r--usr/dash/redir.h4
-rw-r--r--usr/dash/trap.c9
17 files changed, 137 insertions, 134 deletions
diff --git a/usr/dash/README.klibc b/usr/dash/README.klibc
index 0394fb07e0130..1e9f005883f81 100644
--- a/usr/dash/README.klibc
+++ b/usr/dash/README.klibc
@@ -2,6 +2,6 @@ This version of dash was obtained from
http://gondor.apana.org.au/~herbert/dash/dash.git/
-It corresponds to changeset 3c98399cdf8d376b2c1ebd9cd32ca5d8c84f3ac9.
+It corresponds to changeset e592f4dfe80dcac85764ac9aaad3132e5ba28663.
The only changes made are the addition of config.h and a new Makefile.
diff --git a/usr/dash/bltin/printf.c b/usr/dash/bltin/printf.c
index 75ba40d02f15d..8efcbe37f2bc0 100644
--- a/usr/dash/bltin/printf.c
+++ b/usr/dash/bltin/printf.c
@@ -40,7 +40,7 @@
#include <string.h>
#include <unistd.h>
-static char *conv_escape_str(char *);
+static int conv_escape_str(char *);
static char *conv_escape(char *, int *);
static int getchr(void);
static intmax_t getintmax(void);
@@ -157,11 +157,12 @@ pc:
switch (ch) {
case 'b': {
- char *p = conv_escape_str(getstr());
+ int done = conv_escape_str(getstr());
+ char *p = stackblock();
*fmt = 's';
PF(start, p);
/* escape if a \c was encountered */
- if (rval & 0x100)
+ if (done)
goto out;
*fmt = 'b';
break;
@@ -212,7 +213,7 @@ pc:
} while (gargv != argv && *gargv);
out:
- return (rval & ~0x100);
+ return rval;
err:
return 1;
}
@@ -222,7 +223,7 @@ err:
* Print SysV echo(1) style escape string
* Halts processing string if a \c escape is encountered.
*/
-static char *
+static int
conv_escape_str(char *str)
{
int ch;
@@ -241,8 +242,7 @@ conv_escape_str(char *str)
ch = *str++;
if (ch == 'c') {
/* \c as in SYSV echo - abort all processing.... */
- rval |= 0x100;
- ch = 0;
+ ch = 0x100;
continue;
}
@@ -269,9 +269,9 @@ conv_escape_str(char *str)
/* Finally test for sequences valid in the format string */
str = conv_escape(str - 1, &c);
ch = c;
- } while (STPUTC(ch, cp), ch);
+ } while (STPUTC(ch, cp), (char)ch);
- return stackblock();
+ return ch;
}
/*
@@ -451,16 +451,11 @@ echocmd(int argc, char **argv)
do {
char c;
- c = *(*argv)++;
- if (!c)
- goto next;
- if (c != '\\')
- goto print;
-
- outstr(conv_escape_str(*argv - 1), outs);
- if (rval & 0x100)
+ nonl += conv_escape_str(*argv);
+ outstr(stackblock(), outs);
+ if (nonl > 0)
break;
-next:
+
c = ' ';
if (!*++argv) {
end:
@@ -469,7 +464,6 @@ end:
}
c = '\n';
}
-print:
outc(c, outs);
} while (*argv);
return 0;
diff --git a/usr/dash/bltin/test.c b/usr/dash/bltin/test.c
index 77949de07576f..8f9e08590b492 100644
--- a/usr/dash/bltin/test.c
+++ b/usr/dash/bltin/test.c
@@ -489,7 +489,8 @@ bash_group_member(gid_t gid)
ngroups = getgroups(0, NULL);
group_array = stalloc(ngroups * sizeof(gid_t));
- getgroups(ngroups, group_array);
+ if ((getgroups(ngroups, group_array)) != ngroups)
+ return (0);
/* Search through the list looking for GID. */
for (i = 0; i < ngroups; i++)
diff --git a/usr/dash/config.h b/usr/dash/config.h
index 1b587cc801445..a557b46e7fcd2 100644
--- a/usr/dash/config.h
+++ b/usr/dash/config.h
@@ -53,16 +53,16 @@
#define PACKAGE_NAME "dash"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "dash 0.5.2"
+#define PACKAGE_STRING "dash 0.5.4"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "dash"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.5.2"
+#define PACKAGE_VERSION "0.5.4"
/* Version number of package */
-#define VERSION "0.5.2"
+#define VERSION "0.5.4"
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index 44ba8500b559a..a9a73db3eb916 100644
--- a/usr/dash/eval.c
+++ b/usr/dash/eval.c
@@ -150,10 +150,9 @@ evalcmd(int argc, char **argv)
STPUTC('\0', concat);
p = grabstackstr(concat);
}
- evalstring(p, ~SKIPEVAL);
-
+ return evalstring(p, ~SKIPEVAL);
}
- return exitstatus;
+ return 0;
}
@@ -166,24 +165,23 @@ evalstring(char *s, int mask)
{
union node *n;
struct stackmark smark;
- int skip;
+ int status;
setinputstring(s);
setstackmark(&smark);
- skip = 0;
+ status = 0;
while ((n = parsecmd(0)) != NEOF) {
evaltree(n, 0);
+ status = exitstatus;
popstackmark(&smark);
- skip = evalskip;
- if (skip)
+ if (evalskip)
break;
}
popfile();
- skip &= mask;
- evalskip = skip;
- return skip;
+ evalskip &= mask;
+ return status;
}
@@ -627,8 +625,7 @@ evalbackcmd(union node *n, struct backcmd *result)
FORCEINTON;
close(pip[0]);
if (pip[1] != 1) {
- close(1);
- copyfd(pip[1], 1);
+ dup2(pip[1], 1);
close(pip[1]);
}
eflag = 0;
diff --git a/usr/dash/exec.c b/usr/dash/exec.c
index 417ba8a4e7117..8a1f7229f5300 100644
--- a/usr/dash/exec.c
+++ b/usr/dash/exec.c
@@ -110,7 +110,6 @@ shellexec(char **argv, const char *path, int idx)
char **envp;
int exerrno;
- clearredir(1);
envp = environment();
if (strchr(argv[0], '/') != NULL) {
tryexec(argv[0], argv, envp);
@@ -846,6 +845,7 @@ commandcmd(argc, argv)
int argc;
char **argv;
{
+ char *cmd;
int c;
enum {
VERIFY_BRIEF = 1,
@@ -862,8 +862,9 @@ commandcmd(argc, argv)
abort();
#endif
- if (verify)
- return describe_command(out1, *argptr, verify - VERIFY_BRIEF);
+ cmd = *argptr;
+ if (verify && cmd)
+ return describe_command(out1, cmd, verify - VERIFY_BRIEF);
return 0;
}
diff --git a/usr/dash/expand.c b/usr/dash/expand.c
index 2eb726eaae180..d5d1b6036812d 100644
--- a/usr/dash/expand.c
+++ b/usr/dash/expand.c
@@ -1581,7 +1581,7 @@ pmatch(const char *pattern, const char *string)
if (c == '[') {
const char *r;
- found |= ccmatch(p, chr, &r);
+ found |= !!ccmatch(p, chr, &r);
if (r) {
p = r;
continue;
diff --git a/usr/dash/input.c b/usr/dash/input.c
index 057da71901e0b..11f7a3f6063f8 100644
--- a/usr/dash/input.c
+++ b/usr/dash/input.c
@@ -428,7 +428,6 @@ int
setinputfile(const char *fname, int flags)
{
int fd;
- int fd2;
INTOFF;
if ((fd = open(fname, O_RDONLY)) < 0) {
@@ -436,13 +435,8 @@ setinputfile(const char *fname, int flags)
goto out;
sh_error("Can't open %s", fname);
}
- if (fd < 10) {
- fd2 = copyfd(fd, 10);
- close(fd);
- if (fd2 < 0)
- sh_error("Out of file descriptors");
- fd = fd2;
- }
+ if (fd < 10)
+ fd = savefd(fd);
setinputfd(fd, flags & INPUT_PUSH_FILE);
out:
INTON;
@@ -458,7 +452,6 @@ out:
void
setinputfd(int fd, int push)
{
- (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (push) {
pushfile();
parsefile->buf = 0;
diff --git a/usr/dash/jobs.c b/usr/dash/jobs.c
index 77ed779110b0d..7e38048728661 100644
--- a/usr/dash/jobs.c
+++ b/usr/dash/jobs.c
@@ -188,18 +188,14 @@ setjobctl(int on)
if (on == jobctl || rootshell == 0)
return;
if (on) {
- int ofd;
- ofd = fd = open(_PATH_TTY, O_RDWR);
+ fd = open(_PATH_TTY, O_RDWR);
if (fd < 0) {
fd += 3;
- while (!isatty(fd) && --fd >= 0)
- ;
+ while (!isatty(fd))
+ if (--fd < 0)
+ goto out;
}
- fd = fcntl(fd, F_DUPFD, 10);
- close(ofd);
- if (fd < 0)
- goto out;
- fcntl(fd, F_SETFD, FD_CLOEXEC);
+ fd = savefd(fd);
do { /* while we are in the background */
if ((pgrp = tcgetpgrp(fd)) < 0) {
out:
diff --git a/usr/dash/memalloc.h b/usr/dash/memalloc.h
index 1691d1353f544..8a41e6440df0d 100644
--- a/usr/dash/memalloc.h
+++ b/usr/dash/memalloc.h
@@ -64,7 +64,7 @@ char *stnputs(const char *, size_t, char *);
char *stputs(const char *, char *);
-static inline char *_STPUTC(char c, char *p) {
+static inline char *_STPUTC(int c, char *p) {
if (p == sstrend)
p = growstackstr();
*p++ = c;
diff --git a/usr/dash/mkbuiltins b/usr/dash/mkbuiltins
index 38330528d65c9..dc0212bd73c55 100644
--- a/usr/dash/mkbuiltins
+++ b/usr/dash/mkbuiltins
@@ -65,7 +65,7 @@ awk '{ for (i = 2 ; i <= NF ; i++) {
if ($i ~ /^-/)
line = $(++i) "\t" line
print line
- }}' $temp | sort -k 1,1 | tee $temp2 | awk '{
+ }}' $temp | LC_COLLATE=C sort -k 1,1 | tee $temp2 | awk '{
opt = ""
if (NF > 2) {
opt = substr($2, 2)
diff --git a/usr/dash/mkinit.c b/usr/dash/mkinit.c
index e8037517501cc..9714bee0659de 100644
--- a/usr/dash/mkinit.c
+++ b/usr/dash/mkinit.c
@@ -427,9 +427,12 @@ writetext(struct text *text, FILE *fp)
struct block *bp;
if (text->start != NULL) {
- for (bp = text->start ; bp != text->last ; bp = bp->next)
- fwrite(bp->text, sizeof (char), BLOCKSIZE, fp);
- fwrite(bp->text, sizeof (char), BLOCKSIZE - text->nleft, fp);
+ for (bp = text->start ; bp != text->last ; bp = bp->next) {
+ if ((fwrite(bp->text, sizeof (char), BLOCKSIZE, fp)) != BLOCKSIZE)
+ error("Can't write data\n");
+ }
+ if ((fwrite(bp->text, sizeof (char), BLOCKSIZE - text->nleft, fp)) != (BLOCKSIZE - text->nleft))
+ error("Can't write data\n");
}
}
diff --git a/usr/dash/parser.c b/usr/dash/parser.c
index 91f019e6a9a2a..c83b14d007fcd 100644
--- a/usr/dash/parser.c
+++ b/usr/dash/parser.c
@@ -39,7 +39,6 @@
#include "parser.h"
#include "nodes.h"
#include "expand.h" /* defines rmescapes() */
-#include "redir.h" /* defines copyfd() */
#include "exec.h" /* defines find_builtin() */
#include "syntax.h"
#include "options.h"
diff --git a/usr/dash/parser.h b/usr/dash/parser.h
index d0cf4407754c6..76ec839ba16e0 100644
--- a/usr/dash/parser.h
+++ b/usr/dash/parser.h
@@ -41,7 +41,7 @@
#define CTLENDVAR -125
#define CTLBACKQ -124
#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
-/* CTLBACKQ | CTLQUOTE == 133 */
+/* CTLBACKQ | CTLQUOTE == -123 */
#define CTLARI -122 /* arithmetic expression */
#define CTLENDARI -121
#define CTLQUOTEMARK -120
diff --git a/usr/dash/redir.c b/usr/dash/redir.c
index 2bd8e9f53fd30..33dbc881e781d 100644
--- a/usr/dash/redir.c
+++ b/usr/dash/redir.c
@@ -57,7 +57,10 @@
#include "error.h"
+#define REALLY_CLOSED -3 /* fd that was closed and still is */
#define EMPTY -2 /* marks an unused slot in redirtab */
+#define CLOSED -1 /* fd opened for redir needs to be closed */
+
#ifndef PIPE_BUF
# define PIPESIZE 4096 /* amount of buffering in a pipe */
#else
@@ -116,7 +119,7 @@ redirect(union node *redir, int flags)
}
sv = NULL;
INTOFF;
- if (flags & REDIR_PUSH) {
+ if (likely(flags & REDIR_PUSH)) {
struct redirtab *q;
q = ckmalloc(sizeof (struct redirtab));
q->next = redirlist;
@@ -129,31 +132,34 @@ redirect(union node *redir, int flags)
}
n = redir;
do {
- fd = n->nfile.fd;
- if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
- n->ndup.dupfd == fd)
- continue; /* redirect from/to same file descriptor */
-
newfd = openredirect(n);
- if (fd == newfd)
+ if (newfd < -1)
continue;
- if (sv && *(p = &sv->renamed[fd]) == EMPTY) {
- int i = fcntl(fd, F_DUPFD, 10);
- if (i == -1) {
- i = errno;
- if (i != EBADF) {
- const char *m = strerror(i);
- close(newfd);
- sh_error("%d: %s", fd, m);
- /* NOTREACHED */
+
+ fd = n->nfile.fd;
+
+ if (sv) {
+ p = &sv->renamed[fd];
+ i = *p;
+
+ if (likely(i == EMPTY)) {
+ i = CLOSED;
+ if (fd != newfd) {
+ i = savefd(fd);
+ fd = -1;
}
- } else {
- *p = i;
- close(fd);
}
- } else {
- close(fd);
+
+ if (i == newfd)
+ /* Can only happen if i == newfd == CLOSED */
+ i = REALLY_CLOSED;
+
+ *p = i;
}
+
+ if (fd == newfd)
+ continue;
+
#ifdef notyet
dupredirect(n, newfd, memory);
#else
@@ -167,7 +173,7 @@ redirect(union node *redir, int flags)
if (memory[2])
out2 = &memout;
#endif
- if (flags & REDIR_SAVEFD2 && sv && sv->renamed[2] >= 0)
+ if (flags & REDIR_SAVEFD2 && sv->renamed[2] >= 0)
preverrout.fd = sv->renamed[2];
}
@@ -208,15 +214,17 @@ openredirect(union node *redir)
if ((f = open64(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
goto ecreate;
break;
+ case NTOFD:
+ case NFROMFD:
+ f = redir->ndup.dupfd;
+ if (f == redir->nfile.fd)
+ f = -2;
+ break;
default:
#ifdef DEBUG
abort();
#endif
/* Fall through to eliminate warning. */
- case NTOFD:
- case NFROMFD:
- f = -1;
- break;
case NHERE:
case NXHERE:
f = openhere(redir);
@@ -244,27 +252,37 @@ dupredirect(redir, f)
#endif
{
int fd = redir->nfile.fd;
+ int err = 0;
#ifdef notyet
memory[fd] = 0;
#endif
if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
- if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
+ /* if not ">&-" */
+ if (f >= 0) {
#ifdef notyet
- if (memory[redir->ndup.dupfd])
+ if (memory[f])
memory[fd] = 1;
else
#endif
- copyfd(redir->ndup.dupfd, fd);
+ if (dup2(f, fd) < 0) {
+ err = errno;
+ goto err;
+ }
+ return;
}
- return;
- }
+ f = fd;
+ } else if (dup2(f, fd) < 0)
+ err = errno;
+
+ close(f);
+ if (err < 0)
+ goto err;
- if (f != fd) {
- copyfd(f, fd);
- close(f);
- }
return;
+
+err:
+ sh_error("%d: %s", f, strerror(err));
}
@@ -326,12 +344,19 @@ popredir(int drop)
INTOFF;
rp = redirlist;
for (i = 0 ; i < 10 ; i++) {
- if (rp->renamed[i] != EMPTY) {
- if (!drop) {
+ switch (rp->renamed[i]) {
+ case CLOSED:
+ if (!drop)
close(i);
- copyfd(rp->renamed[i], i);
- }
+ break;
+ case EMPTY:
+ case REALLY_CLOSED:
+ break;
+ default:
+ if (!drop)
+ dup2(rp->renamed[i], i);
close(rp->renamed[i]);
+ break;
}
}
redirlist = rp->next;
@@ -349,47 +374,42 @@ popredir(int drop)
INCLUDE "redir.h"
RESET {
- clearredir(0);
-}
-
-#endif
-
-/*
- * Discard all saved file descriptors.
- */
-
-void
-clearredir(int drop)
-{
+ /*
+ * Discard all saved file descriptors.
+ */
for (;;) {
nullredirs = 0;
if (!redirlist)
break;
- popredir(drop);
+ popredir(0);
}
}
+#endif
+
/*
- * Copy a file descriptor to be >= to. Returns -1
- * if the source file descriptor is closed, EMPTY if there are no unused
- * file descriptors left.
+ * Move a file descriptor to > 10. Invokes sh_error on error unless
+ * the original file dscriptor is not open.
*/
int
-copyfd(int from, int to)
+savefd(int from)
{
int newfd;
+ int err;
- newfd = fcntl(from, F_DUPFD, to);
- if (newfd < 0) {
- int errno2 = errno;
- if (errno2 == EMFILE)
- return EMPTY;
+ newfd = fcntl(from, F_DUPFD, 10);
+ err = newfd < 0 ? errno : 0;
+ if (err != EBADF) {
+ close(from);
+ if (err)
+ sh_error("%d: %s", from, strerror(err));
else
- sh_error("%d: %s", from, strerror(errno2));
+ fcntl(newfd, F_SETFD, FD_CLOEXEC);
}
+
return newfd;
}
diff --git a/usr/dash/redir.h b/usr/dash/redir.h
index 3297f6a9f0f9e..74c1a7ed1a178 100644
--- a/usr/dash/redir.h
+++ b/usr/dash/redir.h
@@ -44,6 +44,6 @@
union node;
void redirect(union node *, int);
void popredir(int);
-void clearredir(int);
-int copyfd(int, int);
+void clearredir(void);
+int savefd(int);
int redirectsafe(union node *, int);
diff --git a/usr/dash/trap.c b/usr/dash/trap.c
index 51e1d56053a27..dc27224ac8416 100644
--- a/usr/dash/trap.c
+++ b/usr/dash/trap.c
@@ -294,7 +294,6 @@ dotrap(void)
char *q;
int i;
int savestatus;
- int skip = 0;
savestatus = exitstatus;
pendingsigs = 0;
@@ -308,13 +307,13 @@ dotrap(void)
p = trap[i + 1];
if (!p)
continue;
- skip = evalstring(p, SKIPEVAL);
+ evalstring(p, SKIPEVAL);
exitstatus = savestatus;
- if (skip)
- break;
+ if (evalskip)
+ return evalskip;
}
- return skip;
+ return 0;
}