[klibc] [git patch] klibc dash 0.5.4 update

maximilian attems max at stro.at
Thu Aug 23 01:11:14 PDT 2007


hello hpa,

please pull for the dash update
git pull git://brane.itp.tuwien.ac.at/~mattems/klibc.git maks

with this changes:

Alexey Gladkov (1):
      Check return code for getgroups and fwrite

Herbert Xu (17):
      Remove unnecessary truncation in _STPUTC
      Always call conv_escape_str in echocmd
      Fix \c spillage across echo commands
      Release 0.5.3.
      Make eval with empty arguments return 0
      Fixed inverted char class matching
      Fixed command -v segmentation fault
      Fix mkbuiltin sort order
      Fix typo in comment
      Remove unnecessary inclusion of redir.h
      Remove EMFILE special case
      Use dup2 instead of copyfd in evalbackcmd
      Replace copyfd by savefd and use dup2 elsewhere
      Remove redundant CLOEXEC calls
      Fix redirect restore on saved file descriptors
      Size optimisations in redir.c
      Release 0.5.4.

maximilian attems (1):
      README.klibc: dash update to latest HEAD

with the following diffstat
 usr/dash/README.klibc   |    2 
 usr/dash/bltin/printf.c |   32 +++-----
 usr/dash/bltin/test.c   |    3 
 usr/dash/config.h       |    6 -
 usr/dash/eval.c         |   21 ++---
 usr/dash/exec.c         |    7 +
 usr/dash/expand.c       |    2 
 usr/dash/input.c        |   11 --
 usr/dash/jobs.c         |   14 +--
 usr/dash/memalloc.h     |    2 
 usr/dash/mkbuiltins     |    2 
 usr/dash/mkinit.c       |    9 +-
 usr/dash/parser.c       |    1 
 usr/dash/parser.h       |    2 
 usr/dash/redir.c        |  144 +++++++++++++++++++++-----------------
 usr/dash/redir.h        |    4 -
 usr/dash/trap.c         |    9 +-
 17 files changed, 137 insertions(+), 134 deletions(-)

the merge was prompted due to the fixed klibc dash bug
on inverted char class matching, that initramfs-tools uses.

see current with small test case:
/usr/lib/klibc/bin/sh.shared 
$ foo="a-z"
$ case $foo in *[![:alnum:]]*) echo bad; esac
bad
$ foo="az"
$ case $foo in *[![:alnum:]]*) echo bad; esac
bad

the patches where generated wit git format-patch out of dash git
and then seded to apply to the different path location inside of klibc.
the only rejects where minor white space diffs.
ah the version stuff, but that is trivial.

the parser unsigned char patch series already was in klibc.
the only thing i dropped on to the floor and that Sam might
want to take a look at, but i don't think it is that klibc
relevant is the 13537aaa484b1f3ea914c0dc4f71070602003880
"Added --with-libedit option to configure"

on x86_32 i didn't see any size change to current sh.shared.
looking at the current dash 0.5.4 deb i only see one diff,
so that release looks golden. :)

-- 
maks

commit a61d42236f43ca0a9a08b7af5bfe341b43fc84b0
Author: maximilian attems <max at stro.at>
Date:   Thu Aug 23 09:48:58 2007 +0200

    README.klibc: dash update to latest HEAD
    
    note the 0.5.4 sha1sum.
    
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/README.klibc b/usr/dash/README.klibc
index 0394fb0..1e9f005 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.

commit c5627a7d69b6d62ff19c91429693c6006568a111
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Thu Jul 12 17:32:51 2007 +0800

    Release 0.5.4.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/config.h b/usr/dash/config.h
index 61536d0..a557b46 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.3"
+#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.3"
+#define PACKAGE_VERSION "0.5.4"
 
 /* Version number of package */
-#define VERSION "0.5.3"
+#define VERSION "0.5.4"
 
 /* Enable GNU extensions on systems that have them.  */
 #ifndef _GNU_SOURCE

commit 8300fc61659325ac0bf8c3181d4eb1dcfe627440
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sat May 12 18:14:15 2007 +1000

    Size optimisations in redir.c
    
    Add likely flag on REDIR_PUSH.
    Remove sv check on REDIR_SAVEFD2 (it implies REDIR_PUSH).
    Optimise NTOFD/NFROMFD same fd check.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/redir.c b/usr/dash/redir.c
index d4d9c39..33dbc88 100644
--- a/usr/dash/redir.c
+++ b/usr/dash/redir.c
@@ -119,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;
@@ -132,12 +132,11 @@ 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 (newfd < -1)
+			continue;
+
+		fd = n->nfile.fd;
 
 		if (sv) {
 			p = &sv->renamed[fd];
@@ -174,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];
 }
 
@@ -215,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 = redir->ndup.dupfd;
-		break;
 	case NHERE:
 	case NXHERE:
 		f = openhere(redir);

commit 725a7524011ba02c02493750e93eaace6ddc5280
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sat May 12 18:09:24 2007 +1000

    Fix redirect restore on saved file descriptors
    
    As it stands if a redirection occurs on a file descriptor that was
    previously closed, it won't be closed after that redirection goes
    out of effect.  This is because we don't keep track of closed file
    descriptors properly as we do for open ones.
    
    This patch fixes this by introducing two new states, CLOSED and
    REALLY_CLOSED.  The first represents an initially closed descriptor
    which is now open while the second one represents an initally closed
    descriptor which is now closed.
    
    This patch is based on work by Rainer Weikusat.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/redir.c b/usr/dash/redir.c
index 6ffde0c..d4d9c39 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
@@ -135,14 +138,29 @@ redirect(union node *redir, int flags)
 			continue; /* redirect from/to same file descriptor */
 
 		newfd = openredirect(n);
+
+		if (sv) {
+			p = &sv->renamed[fd];
+			i = *p;
+
+			if (likely(i == EMPTY)) {
+				i = CLOSED;
+				if (fd != newfd) {
+					i = savefd(fd);
+					fd = -1;
+				}
+			}
+
+			if (i == newfd)
+				/* Can only happen if i == newfd == CLOSED */
+				i = REALLY_CLOSED;
+
+			*p = i;
+		}
+
 		if (fd == newfd)
 			continue;
-		if (sv && *(p = &sv->renamed[fd]) == EMPTY) {
-			int i = savefd(fd);
 
-			if (i >= 0)
-				*p = i;
-		}
 #ifdef notyet
 		dupredirect(n, newfd, memory);
 #else
@@ -204,7 +222,7 @@ openredirect(union node *redir)
 		/* Fall through to eliminate warning. */
 	case NTOFD:
 	case NFROMFD:
-		f = -1;
+		f = redir->ndup.dupfd;
 		break;
 	case NHERE:
 	case NXHERE:
@@ -239,9 +257,10 @@ dupredirect(redir, f)
 	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
@@ -324,10 +343,19 @@ popredir(int drop)
 	INTOFF;
 	rp = redirlist;
 	for (i = 0 ; i < 10 ; i++) {
-		if (rp->renamed[i] != EMPTY) {
+		switch (rp->renamed[i]) {
+		case CLOSED:
+			if (!drop)
+				close(i);
+			break;
+		case EMPTY:
+		case REALLY_CLOSED:
+			break;
+		default:
 			if (!drop)
 				dup2(rp->renamed[i], i);
 			close(rp->renamed[i]);
+			break;
 		}
 	}
 	redirlist = rp->next;

commit aa6a4978b0ff19fa6237eee9a4e3b12c3fbee641
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sun May 6 19:28:56 2007 +1000

    Remove redundant CLOEXEC calls
    
    Now that we're marking file descriptors as CLOEXEC in savefd, we no longer
    need to close them on exec or in setinputfd.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/exec.c b/usr/dash/exec.c
index c55683d..8a1f722 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);
diff --git a/usr/dash/input.c b/usr/dash/input.c
index 7f99d4a..11f7a3f 100644
--- a/usr/dash/input.c
+++ b/usr/dash/input.c
@@ -452,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/redir.c b/usr/dash/redir.c
index 9e0fae5..6ffde0c 100644
--- a/usr/dash/redir.c
+++ b/usr/dash/redir.c
@@ -345,26 +345,19 @@ 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
+
 
 
 /*
diff --git a/usr/dash/redir.h b/usr/dash/redir.h
index 71f5202..74c1a7e 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);
+void clearredir(void);
 int savefd(int);
 int redirectsafe(union node *, int);

commit 4d902311bda3a6d01c5addcb2f344c6145665a9d
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sat May 12 18:00:57 2007 +1000

    Replace copyfd by savefd and use dup2 elsewhere
    
    There are two kinds of users to copyfd, those that want to copy an fd to
    an exact value and those that want to move an fd to a value >= 10.  The
    former can simply use dup2 directly while the latter share a lot of common
    code that now constitutes savefd.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/input.c b/usr/dash/input.c
index 49a2972..7f99d4a 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,11 +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);
-		fd = fd2;
-	}
+	if (fd < 10)
+		fd = savefd(fd);
 	setinputfd(fd, flags & INPUT_PUSH_FILE);
 out:
 	INTON;
diff --git a/usr/dash/jobs.c b/usr/dash/jobs.c
index 77ed779..7e38048 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/redir.c b/usr/dash/redir.c
index aab1585..9e0fae5 100644
--- a/usr/dash/redir.c
+++ b/usr/dash/redir.c
@@ -138,21 +138,10 @@ redirect(union node *redir, int flags)
 		if (fd == newfd)
 			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 */
-				}
-			} else {
+			int i = savefd(fd);
+
+			if (i >= 0)
 				*p = i;
-				close(fd);
-			}
-		} else {
-			close(fd);
 		}
 #ifdef notyet
 		dupredirect(n, newfd, memory);
@@ -244,6 +233,7 @@ dupredirect(redir, f)
 #endif
 	{
 	int fd = redir->nfile.fd;
+	int err = 0;
 
 #ifdef notyet
 	memory[fd] = 0;
@@ -255,16 +245,24 @@ dupredirect(redir, 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));
 }
 
 
@@ -327,10 +325,8 @@ popredir(int drop)
 	rp = redirlist;
 	for (i = 0 ; i < 10 ; i++) {
 		if (rp->renamed[i] != EMPTY) {
-			if (!drop) {
-				close(i);
-				copyfd(rp->renamed[i], i);
-			}
+			if (!drop)
+				dup2(rp->renamed[i], i);
 			close(rp->renamed[i]);
 		}
 	}
@@ -372,17 +368,26 @@ clearredir(int drop)
 
 
 /*
- * Copy a file descriptor to be >= to.  Invokes sh_error on error.
+ * 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, 10);
+	err = newfd < 0 ? errno : 0;
+	if (err != EBADF) {
+		close(from);
+		if (err)
+			sh_error("%d: %s", from, strerror(err));
+		else
+			fcntl(newfd, F_SETFD, FD_CLOEXEC);
+	}
 
-	newfd = fcntl(from, F_DUPFD, to);
-	if (newfd < 0)
-		sh_error("%d: %s", from, strerror(errno));
 	return newfd;
 }
 
diff --git a/usr/dash/redir.h b/usr/dash/redir.h
index 3297f6a..71f5202 100644
--- a/usr/dash/redir.h
+++ b/usr/dash/redir.h
@@ -45,5 +45,5 @@ union node;
 void redirect(union node *, int);
 void popredir(int);
 void clearredir(int);
-int copyfd(int, int);
+int savefd(int);
 int redirectsafe(union node *, int);

commit cd1f6d78df693fbb0cd59288d71c6bacc6d09bb1
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sun May 6 15:00:57 2007 +1000

    Use dup2 instead of copyfd in evalbackcmd
    
    Since we know that dup2 must succeed here we can call it directly.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index 23b9608..a9a73db 100644
--- a/usr/dash/eval.c
+++ b/usr/dash/eval.c
@@ -625,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;

commit 42813b34771be5ed6b806aafe75dfe3f58d0c2e2
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sun May 6 12:01:37 2007 +1000

    Remove EMFILE special case
    
    No caller of copyfd need to ignore EMFILE so we can remove the special
    case and just let it call sh_error on any error.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/input.c b/usr/dash/input.c
index 057da71..49a2972 100644
--- a/usr/dash/input.c
+++ b/usr/dash/input.c
@@ -439,8 +439,6 @@ setinputfile(const char *fname, int flags)
 	if (fd < 10) {
 		fd2 = copyfd(fd, 10);
 		close(fd);
-		if (fd2 < 0)
-			sh_error("Out of file descriptors");
 		fd = fd2;
 	}
 	setinputfd(fd, flags & INPUT_PUSH_FILE);
diff --git a/usr/dash/redir.c b/usr/dash/redir.c
index 2bd8e9f..aab1585 100644
--- a/usr/dash/redir.c
+++ b/usr/dash/redir.c
@@ -372,9 +372,7 @@ clearredir(int drop)
 
 
 /*
- * 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.
+ * Copy a file descriptor to be >= to.  Invokes sh_error on error.
  */
 
 int
@@ -383,13 +381,8 @@ copyfd(int from, int to)
 	int newfd;
 
 	newfd = fcntl(from, F_DUPFD, to);
-	if (newfd < 0) {
-		int errno2 = errno;
-		if (errno2 == EMFILE)
-			return EMPTY;
-		else
-			sh_error("%d: %s", from, strerror(errno2));
-	}
+	if (newfd < 0)
+		sh_error("%d: %s", from, strerror(errno));
 	return newfd;
 }
 

commit 2b4c87b04c00d0f9733d14ac1fabdc93e57109d1
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sun May 6 11:03:09 2007 +1000

    Remove unnecessary inclusion of redir.h
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/parser.c b/usr/dash/parser.c
index 91f019e..c83b14d 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"

commit 96a357a84645e84e790bf07af240f7fc2b57b84d
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sat May 5 17:57:18 2007 +1000

    Fix typo in comment
    
    The value for CTLBACKQ | CTLQUOTE is now -123, not 133.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/parser.h b/usr/dash/parser.h
index d0cf440..76ec839 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

commit e74d1684f508110fffd239d6edec7206e70b3d3a
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sat Apr 28 20:50:23 2007 +1000

    Fix mkbuiltin sort order
    
    On Fri, Feb 16, 2007 at 04:24:55PM -0800, Dan Nicholson wrote:
    > I was having a problem building dash where `:' wasn't being recognized
    > as a builtin command. I won't bore you with the details of the
    > debugging, but it came down to the fact that the generated struct in
    > builtins.c wasn't being sorted correctly. The ":" name was coming
    > before the "." name and then was never able to be found by bsearch().
    >
    > The issue turned out to be that I was building with a UTF-8 charset,
    > causing the `sort' to come out differently from the mkbuiltins script.
    > When I finally set LANG=C, it came out correct. Here's an example of
    > the difference.
    >
    > $ LANG=C sort << "EOF"
    > :
    > .
    > EOF
    > .
    > :
    > $ LANG=en_US.ISO-8859-1 sort << "EOF"
    > :
    > .
    > EOF
    > :
    > .
    >
    > My system has glibc-2.3.6, but I also tested it on an RHEL3 server at
    > work. My solution was just to add LC_ALL=C to the mkbuiltins script.
    > Maybe it's overkill to use LC_ALL. Patch against HEAD attached.
    
    I've changed this patch so that we just set LC_COLLATE for the sort
    command.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/mkbuiltins b/usr/dash/mkbuiltins
index 3833052..dc0212b 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)

commit c374dce050b05ebd03c4a55032cc4f26c61c51ce
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sun Oct 22 19:55:00 2006 +1000

    Fixed command -v segmentation fault
    
    On Sat, Oct 21, 2006 at 02:19:18PM +0000, Gerrit Pape wrote:
    > Hi Herbert, please see
    >  http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=387458
    >
    > On Thu, Sep 14, 2006 at 03:50:02PM +0200, Julien Danjou wrote:
    > > I just found this bug which is easily reproductible:
    > >
    > > % dash -c 'command -v'
    > > zsh: segmentation fault  dash -c 'command -v'
    
    Since bash's behaviour is minimalist here, I've decided to adopt its
    behaviour here as well which is to return success silently.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/exec.c b/usr/dash/exec.c
index 417ba8a..c55683d 100644
--- a/usr/dash/exec.c
+++ b/usr/dash/exec.c
@@ -846,6 +846,7 @@ commandcmd(argc, argv)
 	int argc;
 	char **argv;
 {
+	char *cmd;
 	int c;
 	enum {
 		VERIFY_BRIEF = 1,
@@ -862,8 +863,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;
 }

commit 53eaa866587754cb7054eb1b953adea04cf3a4df
Author: Alexey Gladkov <legion at altlinux.org>
Date:   Fri Oct 13 22:58:46 2006 +1000

    Check return code for getgroups and fwrite
    
    Check getgroups() and fwrite() return code, required to build with
    -D_FORTIFY_SOURCE=2.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/bltin/test.c b/usr/dash/bltin/test.c
index 77949de..8f9e085 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/mkinit.c b/usr/dash/mkinit.c
index e803751..9714bee 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");
 	}
 }
 

commit f58909da649342da0e0bf7a37fc0061dd019a386
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Wed Oct 4 17:44:31 2006 +1000

    Fixed inverted char class matching
    
    The return value of ccmatch was being treated as 0 or 1 but
    it's actually zero or non-zero.  This broke inverted character
    class matching.
    
    Reported by Alexander Skwar.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/expand.c b/usr/dash/expand.c
index 2eb726e..d5d1b60 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;

commit e3d0c4d62a49037a765d807ffe3faa14e267d9cc
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Thu Jan 12 21:02:26 2006 +1100

    Make eval with empty arguments return 0
    
    On Tue, Jan 10, 2006 at 10:56:23AM +0000, Gerrit Pape wrote:
    > tags 347232 + patch
    > quit
    >
    > On Mon, Jan 09, 2006 at 04:29:19PM +0100, Marco Nenciarini wrote:
    > > The problem is here:
    > >
    > > # Set the kernel 2.6 option only for fresh install
    > > test -z "$(GetMenuOpt "kopt" "")" && kopt_2_6="root=$root_device_2_6 ro"
    > >
    > > # Extract options for specific kernels
    > > eval $(ExtractMenuOpts "\(kopt_[a-zA-Z0-9_]\+\)")
    > >
    > > If the first test fails and the eval argument is empty then dash
    > > terminate with exitcode 1.
    >
    > > This is a simple testcase:
    > > tm:~# bash -c "set -e ;/bin/false && : ; eval ''; echo 'END'"; echo $?
    > > END
    > > 0
    > > tm:~# dash -c "set -e ;/bin/false && : ; eval ''; echo 'END'"; echo $?
    > > 1
    > >
    > > if you insert any command with successfull exit status before the
    > > empty eval, all work ok:
    > > tm:~# bash -c "set -e ;/bin/false && : ; : ; eval ''; echo 'END'"; echo $?
    > > END
    > > 0
    > > tm:~# dash -c "set -e ;/bin/false && : ; : ; eval ''; echo 'END'"; echo $?
    > > END
    > > 0
    >
    > Yes, I can confirm this is a bug in dash.  The standard says
    >
    >  EXIT STATUS
    >
    >      If there are no arguments, or only null arguments, eval shall
    >      return a zero exit status; otherwise, it shall return the exit
    >      status of the command defined by the string of concatenated
    >      arguments separated by <space>s.
    >
    > Hi Herbert, please see http://bugs.debian.org/347232
    
    Changed evalstring to return the exit status instead of evalskip.  This
    allows us to return zero if the string is empty.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index 44ba850..23b9608 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;
 }
 
 
diff --git a/usr/dash/trap.c b/usr/dash/trap.c
index 51e1d56..dc27224 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;
 }
 
 

commit db69f76ecdb95096518fe6069047b83b8a0293ff
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sat Nov 26 14:15:04 2005 +1100

    Release 0.5.3.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/config.h b/usr/dash/config.h
index 1b587cc..61536d0 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.3"
 
 /* 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.3"
 
 /* Version number of package */
-#define VERSION "0.5.2"
+#define VERSION "0.5.3"
 
 /* Enable GNU extensions on systems that have them.  */
 #ifndef _GNU_SOURCE

commit 52a0132a9ff8c9448db2df2a66cba140520567d6
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Mon Nov 14 21:20:36 2005 +1100

    Fix \c spillage across echo commands
    
    On Thu, Nov 03, 2005 at 07:16:53PM +0100, Mike Hommey wrote:
    > Here is a simple test case:
    >
    > #!/bin/dash
    > echo test\\ test
    > echo '\c'
    > echo test\\ test
    >
    > it outputs:
    > test\ test
    > test\
    >
    > This is due to mis-usage of a global variable. See attached patch for a
    > fix.
    
    Instead of setting rval when \c is detected, this is now set in the
    return value of conv_escape_str.  This prevents the spillage reported
    in http://bugs.debian.org/337294.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/bltin/printf.c b/usr/dash/bltin/printf.c
index 349f898..8efcbe3 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,8 +451,9 @@ echocmd(int argc, char **argv)
 	do {
 		char c;
 
-		outstr(conv_escape_str(*argv), outs);
-		if (rval & 0x100)
+		nonl += conv_escape_str(*argv);
+		outstr(stackblock(), outs);
+		if (nonl > 0)
 			break;
 
 		c = ' ';

commit 74a2b4516e651ff198edf14f25887334186266d3
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sun Nov 13 22:05:18 2005 +1100

    Always call conv_escape_str in echocmd
    
    Instead of calling conv_escape_str when we detect a backslash we will call it
    unconditionally.  This helps get rid of some unnecessary code in echocmd.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/bltin/printf.c b/usr/dash/bltin/printf.c
index 75ba40d..349f898 100644
--- a/usr/dash/bltin/printf.c
+++ b/usr/dash/bltin/printf.c
@@ -451,16 +451,10 @@ 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);
+		outstr(conv_escape_str(*argv), outs);
 		if (rval & 0x100)
 			break;
-next:
+
 		c = ' ';
 		if (!*++argv) {
 end:
@@ -469,7 +463,6 @@ end:
 			}
 			c = '\n';
 		}
-print:
 		outc(c, outs);
 	} while (*argv);
 	return 0;

commit 2e8e9f66247d854dcb813ce0f3a02772daa4cedd
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Sun Nov 13 21:15:19 2005 +1100

    Remove unnecessary truncation in _STPUTC
    
    Using char in the function argument causes unnecessary truncation to occur.
    This patch changes it to an int.
    
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    Signed-off-by: maximilian attems <max at stro.at>

diff --git a/usr/dash/memalloc.h b/usr/dash/memalloc.h
index 1691d13..8a41e64 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;



More information about the klibc mailing list