Subject: Re: bashism for ksh
To: None <tech-userlevel@NetBSD.org>
From: Christian Biere <christianbiere@gmx.de>
List: tech-userlevel
Date: 01/30/2007 01:01:32
--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Jeremy C. Reed wrote:
> On Mon, 29 Jan 2007, Aymeric Vincent wrote:
>
> > Christian Biere <christianbiere@gmx.de> writes:
> >
> > > I'm a fan of this particular bashism:
> > >
> > > make >& make.log
>
> > Actually, it's a cshism (although it's a bit harder to pronounce).
>
> Maybe also do: |&
That's a problem because it's already used by ksh to create a co-process.
Maybe I can add this to sh instead.
> (Not for bash, but works in csh.)
The attached patch adds at least >>& to ksh as well.
--
Christian
--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ksh.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 23:50:18 -0000
@@ -1361,13 +1361,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;
+ iop->flag |= IOBOTH;
+ do_open = 1;
+ flags = O_WRONLY | O_CREAT | O_TRUNC;
+
}
if (u == iop->unit)
return 0; /* "dup from" == "dup to" */
@@ -1435,7 +1449,18 @@ iosetup(iop, tp)
}
#endif /* KSH */
}
- if (u == 2) /* Clear any write errors */
+ if (u >= 0 && (iop->flag & IOBOTH)) {
+ if (e->savefd[STDERR_FILENO] == 0)
+ e->savefd[STDERR_FILENO] = savefd(STDERR_FILENO, 0);
+ if (ksh_dup2(iop->unit, 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 || (iop->flag & IOBOTH)) /* Clear any write errors */
shf_reopen(2, SHF_WR, shl_out);
return 0;
}
Index: lex.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/lex.c,v
retrieving revision 1.12
diff -u -p -r1.12 lex.c
--- lex.c 11 Sep 2005 22:16:00 -0000 1.12
+++ lex.c 29 Jan 2007 23:50:21 -0000
@@ -665,6 +665,11 @@ Done:
} else {
ungetsc(c2);
}
+ } else if (iop->flag == IOCAT) {
+ if ((c2 = getsc()) == '&')
+ iop->flag |= IOBOTH;
+ else
+ ungetsc(c2);
}
} else if (c2 == '&')
iop->flag = IODUP | (c == '<' ? IORDUP : 0);
Index: tree.h
===================================================================
RCS file: /cvsroot/src/bin/ksh/tree.h,v
retrieving revision 1.4
diff -u -p -r1.4 tree.h
--- tree.h 7 Jul 2004 19:20:09 -0000 1.4
+++ tree.h 29 Jan 2007 23:50:21 -0000
@@ -96,6 +96,7 @@ struct ioword {
#define IOCLOB BIT(6) /* >|, override -o noclobber */
#define IORDUP BIT(7) /* x<&y (as opposed to x>&y) */
#define IONAMEXP BIT(8) /* name has been expanded */
+#define IOBOTH BIT(9) /* stdout and stderr e.g., >>& */
/* execute/exchild flags */
#define XEXEC BIT(0) /* execute without forking */
--UlVJffcvxoiEqYs2--