Subject: bashism for ksh
To: None <tech-userlevel@NetBSD.org>
From: Christian Biere <christianbiere@gmx.de>
List: tech-userlevel
Date: 01/29/2007 08:36:18
--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi,
I'm a fan of this particular bashism:
make >& make.log
In bash this causes both standard output and standard error output to be
redirected to make.log. Thus it's a short-cut for
make > make.log 2>&1
This is not only longer, but the combination 2>&1 is rather awkward to type,
IMHO. The attached patch adds this feature to ksh. This feature isn't POSIX
but POSIX doesn't seem to forbid it either. There's only a minor clash
with ksh's co-process feature, so make >& p (the whitespace is irrelevant)
does not write to file "p" but rather the co-process respectively causes
an error if there's none. I'd think this is neglible.
If checked a couple of cases and couldn't find a problem with my patch so
far. If there are no objections, I'd like to commit it.
For what's it's worth, the following are acceptable and last one wins:
>& /dev/null >& blah
>& /dev/null >& /dev/null
>& /dev/null > blah
>& /dev/null 2> /dev/tty
--
Christian
--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="exec.c.udif"
Index: exec.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/exec.c,v
retrieving revision 1.13
diff -u -p -r1.13 exec.c
--- exec.c 24 Apr 2006 19:58:20 -0000 1.13
+++ exec.c 29 Jan 2007 07:11:07 -0000
@@ -1309,6 +1309,7 @@ iosetup(iop, tp)
int do_open = 1, do_close = 0, UNINITIALIZED(flags);
struct ioword iotmp;
struct stat statb;
+ int redir_both = 0;
if (iotype != IOHERE)
cp = evalonestr(cp, DOTILDE|(Flag(FTALKING_I) ? DOGLOB : 0));
@@ -1361,13 +1362,27 @@ iosetup(iop, tp)
if (*cp == '-' && !cp[1]) {
u = 1009; /* prevent error return below */
do_close = 1;
- } else if ((u = check_fd(cp,
+ } else if (
+ (iop->flag & IORDUP) ||
+ (iop->unit != STDOUT_FILENO) ||
+#ifdef KSH
+ (*cp == 'p' && !cp[1]) ||
+#endif
+ isdigit((unsigned char) *cp)) {
+ if ((u = check_fd(cp,
X_OK | ((iop->flag & IORDUP) ? R_OK : W_OK),
&emsg)) < 0)
- {
- warningf(TRUE, "%s: %s",
- snptreef((char *) 0, 32, "%R", &iotmp), emsg);
- return -1;
+ {
+ warningf(TRUE, "%s: %s",
+ snptreef((char *) 0, 32, "%R", &iotmp), emsg);
+ return -1;
+ }
+ } else {
+ u = -1;
+ redir_both = 1;
+ do_open = 1;
+ flags = O_WRONLY | O_CREAT | O_TRUNC;
+
}
if (u == iop->unit)
return 0; /* "dup from" == "dup to" */
@@ -1435,7 +1450,18 @@ iosetup(iop, tp)
}
#endif /* KSH */
}
- if (u == 2) /* Clear any write errors */
+ if (u >= 0 && redir_both) {
+ if (e->savefd[STDERR_FILENO] == 0)
+ e->savefd[STDERR_FILENO] = savefd(STDERR_FILENO, 0);
+ if (ksh_dup2(u, STDERR_FILENO, TRUE) < 0) {
+ warningf(TRUE,
+ "could not finish (dup) redirection %s: %s",
+ snptreef((char *) 0, 32, "%R", &iotmp),
+ strerror(errno));
+ return -1;
+ }
+ }
+ if (u == 2 || redir_both) /* Clear any write errors */
shf_reopen(2, SHF_WR, shl_out);
return 0;
}
--jI8keyz6grp/JLjh--