summaryrefslogtreecommitdiffstats
path: root/bin/sh
diff options
context:
space:
mode:
authorgjb <gjb@FreeBSD.org>2016-02-02 22:27:48 +0000
committergjb <gjb@FreeBSD.org>2016-02-02 22:27:48 +0000
commitefd5551e55b056811a107b33e1c30676ee37d0e8 (patch)
tree5ea64f05cc16d8a5032524fdefec823e707e1ff3 /bin/sh
parenta6998ad84f9722c560a80302a74fa495e818a153 (diff)
parent6d511d769313fd1dae574a1d395369df219e86b6 (diff)
downloadFreeBSD-src-efd5551e55b056811a107b33e1c30676ee37d0e8.zip
FreeBSD-src-efd5551e55b056811a107b33e1c30676ee37d0e8.tar.gz
MFH
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'bin/sh')
-rw-r--r--bin/sh/redir.c29
-rw-r--r--bin/sh/sh.125
2 files changed, 41 insertions, 13 deletions
diff --git a/bin/sh/redir.c b/bin/sh/redir.c
index 95d3238..0a7aa96 100644
--- a/bin/sh/redir.c
+++ b/bin/sh/redir.c
@@ -70,6 +70,7 @@ struct redirtab {
struct redirtab *next;
int renamed[10];
int fd0_redirected;
+ unsigned int empty_redirs;
};
@@ -82,6 +83,9 @@ static struct redirtab *redirlist;
*/
static int fd0_redirected = 0;
+/* Number of redirtabs that have not been allocated. */
+static unsigned int empty_redirs = 0;
+
static void openredirect(union node *, char[10 ]);
static int openhere(union node *);
@@ -115,12 +119,17 @@ redirect(union node *redir, int flags)
memory[i] = 0;
memory[1] = flags & REDIR_BACKQ;
if (flags & REDIR_PUSH) {
- sv = ckmalloc(sizeof (struct redirtab));
- for (i = 0 ; i < 10 ; i++)
- sv->renamed[i] = EMPTY;
- sv->fd0_redirected = fd0_redirected;
- sv->next = redirlist;
- redirlist = sv;
+ empty_redirs++;
+ if (redir != NULL) {
+ sv = ckmalloc(sizeof (struct redirtab));
+ for (i = 0 ; i < 10 ; i++)
+ sv->renamed[i] = EMPTY;
+ sv->fd0_redirected = fd0_redirected;
+ sv->empty_redirs = empty_redirs - 1;
+ sv->next = redirlist;
+ redirlist = sv;
+ empty_redirs = 0;
+ }
}
for (n = redir ; n ; n = n->nfile.next) {
fd = n->nfile.fd;
@@ -303,6 +312,12 @@ popredir(void)
struct redirtab *rp = redirlist;
int i;
+ INTOFF;
+ if (empty_redirs > 0) {
+ empty_redirs--;
+ INTON;
+ return;
+ }
for (i = 0 ; i < 10 ; i++) {
if (rp->renamed[i] != EMPTY) {
if (rp->renamed[i] >= 0) {
@@ -313,8 +328,8 @@ popredir(void)
}
}
}
- INTOFF;
fd0_redirected = rp->fd0_redirected;
+ empty_redirs = rp->empty_redirs;
redirlist = rp->next;
ckfree(rp);
INTON;
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 14ae898..9406779 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
-.Dd August 29, 2015
+.Dd January 30, 2016
.Dt SH 1
.Os
.Sh NAME
@@ -1952,13 +1952,20 @@ Execute the specified built-in command,
This is useful when the user wishes to override a shell function
with the same name as a built-in command.
.It Ic cd Oo Fl L | P Oc Oo Fl e Oc Op Ar directory
+.It Ic cd Fl
Switch to the specified
.Ar directory ,
-or to the directory specified in the
+to the directory specified in the
.Va HOME
environment variable if no
.Ar directory
-is specified.
+is specified or
+to the directory specified in the
+.Va OLDPWD
+environment variable if
+.Ar directory
+is
+.Fl .
If
.Ar directory
does not begin with
@@ -1982,10 +1989,12 @@ the
.Ic cd
command will print out the name of the directory
that it actually switched to
-if this is different from the name that the user gave.
-These may be different either because the
+if the
.Va CDPATH
-mechanism was used or because a symbolic link was crossed.
+mechanism was used or if
+.Ar directory
+was
+.Fl .
.Pp
If the
.Fl P
@@ -2774,6 +2783,10 @@ Initialization file for interactive shells.
Locale settings.
These are inherited by children of the shell,
and is used in a limited manner by the shell itself.
+.It Ev OLDPWD
+The previous current directory.
+This is used and updated by
+.Ic cd .
.It Ev PWD
An absolute pathname for the current directory,
possibly containing symbolic links.
OpenPOWER on IntegriCloud