make cat an mksh builtin, for things like here documents
if any options are given, the external programme is invoked instead
This commit is contained in:
parent
297e2ced89
commit
d09fd67299
4
check.t
4
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.388 2010/08/24 15:47:44 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.389 2010/08/28 17:21:41 tg Exp $
|
||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||
@ -25,7 +25,7 @@
|
||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R39 2010/08/24
|
||||
@(#)MIRBSD KSH R39 2010/08/28
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
|
17
exec.c
17
exec.c
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.77 2010/08/28 15:48:18 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.78 2010/08/28 17:21:43 tg Exp $");
|
||||
|
||||
#ifndef MKSH_DEFAULT_EXECSHELL
|
||||
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
|
||||
@ -489,6 +489,21 @@ comexec(struct op *t, struct tbl *volatile tp, const char **ap,
|
||||
subst_exstat = 0;
|
||||
break;
|
||||
}
|
||||
} else if (tp->val.f == c_cat) {
|
||||
/*
|
||||
* if we have any flags, do not use the builtin
|
||||
* in theory, we could allow -u, but that would
|
||||
* mean to use ksh_getopt here and possibly ad-
|
||||
* ded complexity and more code and isn't worth
|
||||
*/
|
||||
if (ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' &&
|
||||
/* argument, begins with -, is not - or -- */
|
||||
(ap[1][1] != '-' || ap[1][2] != '\0'))
|
||||
/* don't look for builtins or functions */
|
||||
fcflags = FC_PATH;
|
||||
else
|
||||
/* go on, use the builtin */
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
tp = findcom(ap[0], fcflags & (FC_BI|FC_FUNC));
|
||||
|
77
funcs.c
77
funcs.c
@ -25,7 +25,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.157 2010/08/24 14:42:01 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.158 2010/08/28 17:21:44 tg Exp $");
|
||||
|
||||
#if HAVE_KILLPG
|
||||
/*
|
||||
@ -102,6 +102,7 @@ const struct builtin mkshbuiltins[] = {
|
||||
{"+fg", c_fgbg},
|
||||
#endif
|
||||
{"bind", c_bind},
|
||||
{"cat", c_cat},
|
||||
#if HAVE_MKNOD
|
||||
{"mknod", c_mknod},
|
||||
#endif
|
||||
@ -3427,3 +3428,77 @@ c_realpath(const char **wp)
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
c_cat(const char **wp)
|
||||
{
|
||||
int fd = STDIN_FILENO, rv = 0;
|
||||
ssize_t n, w;
|
||||
const char *fn = "<stdin>";
|
||||
char *buf, *cp;
|
||||
#define MKSH_CAT_BUFSIZ 4096
|
||||
|
||||
/* XXX uses malloc instead of lalloc (for alignment/speed) */
|
||||
if ((buf = malloc(MKSH_CAT_BUFSIZ)) == NULL) {
|
||||
bi_errorf("cannot allocate %lu data bytes",
|
||||
(unsigned long)MKSH_CAT_BUFSIZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
++wp; /* argv[0] */
|
||||
if (wp[0] && wp[0][0] == '-' && wp[0][1] == '-' && wp[0][2] == '\0')
|
||||
++wp; /* "--" (options separator) */
|
||||
|
||||
do {
|
||||
if (*wp) {
|
||||
fn = *wp++;
|
||||
if (fn[0] == '-' && fn[1] == '\0')
|
||||
fd = STDIN_FILENO;
|
||||
else if ((fd = open(fn, O_RDONLY)) < 0) {
|
||||
rv = errno;
|
||||
bi_errorf("%s: %s", fn, strerror(rv));
|
||||
rv = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
n = blocking_read(fd, (cp = buf), MKSH_CAT_BUFSIZ);
|
||||
if (n == -1) {
|
||||
if (errno == EINTR)
|
||||
/* interrupted, try again */
|
||||
continue;
|
||||
/* an error occured during reading */
|
||||
rv = errno;
|
||||
bi_errorf("%s: %s", fn, strerror(rv));
|
||||
rv = 1;
|
||||
break;
|
||||
} else if (n == 0)
|
||||
/* end of file reached */
|
||||
break;
|
||||
while (n) {
|
||||
w = write(STDOUT_FILENO, cp, n);
|
||||
if (w == -1) {
|
||||
if (errno == EINTR)
|
||||
/* interrupted, try again */
|
||||
continue;
|
||||
/* an error occured during writing */
|
||||
rv = errno;
|
||||
bi_errorf("%s: %s", "<stdout>",
|
||||
strerror(rv));
|
||||
rv = 1;
|
||||
if (fd != STDIN_FILENO)
|
||||
close(fd);
|
||||
goto out;
|
||||
}
|
||||
n -= w;
|
||||
cp += w;
|
||||
}
|
||||
}
|
||||
if (fd != STDIN_FILENO)
|
||||
close(fd);
|
||||
} while (*wp);
|
||||
|
||||
out:
|
||||
free(buf);
|
||||
return (rv);
|
||||
}
|
||||
|
29
mksh.1
29
mksh.1
@ -1,4 +1,4 @@
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.235 2010/08/24 14:42:03 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.236 2010/08/28 17:21:44 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.136 2010/07/15 20:04:35 schwarze Exp $
|
||||
.\"-
|
||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
@ -71,7 +71,7 @@
|
||||
.\" with -mandoc, it might implement .Mx itself, but we want to
|
||||
.\" use our own definition. And .Dd must come *first*, always.
|
||||
.\"
|
||||
.Dd $Mdocdate: August 24 2010 $
|
||||
.Dd $Mdocdate: August 28 2010 $
|
||||
.\"
|
||||
.\" Check which macro package we use
|
||||
.\"
|
||||
@ -2780,10 +2780,10 @@ Additional
|
||||
.Nm
|
||||
regular commands
|
||||
.Pp
|
||||
.Ic \&[ , chdir , bind , echo ,
|
||||
.Ic let , mknod , print , printf ,
|
||||
.Ic pwd , realpath , rename , test ,
|
||||
.Ic ulimit , whence
|
||||
.Ic \&[ , chdir , bind , cat ,
|
||||
.Ic echo , let , mknod , print ,
|
||||
.Ic printf , pwd , realpath , rename ,
|
||||
.Ic test , ulimit , whence
|
||||
.Pp
|
||||
In the future, the additional
|
||||
.Nm
|
||||
@ -2963,6 +2963,22 @@ Execute the built-in command
|
||||
.Ar command .
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic cat
|
||||
.Op Fl \-
|
||||
.Op Ar
|
||||
.Xc
|
||||
Read files sequentially, in command line order, and write them to
|
||||
standard output.
|
||||
If
|
||||
.Ar file
|
||||
is a single dash
|
||||
.Pq Sq -
|
||||
or absent, read from standard input.
|
||||
If any options are given, an external
|
||||
.Xr cat 1
|
||||
utility is invoked instead.
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic cd
|
||||
.Op Fl LP
|
||||
.Op Ar dir
|
||||
@ -5910,6 +5926,7 @@ Privileged shell profile.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr awk 1 ,
|
||||
.Xr cat 1 ,
|
||||
.Xr ed 1 ,
|
||||
.Xr getopt 1 ,
|
||||
.Xr sed 1 ,
|
||||
|
5
sh.h
5
sh.h
@ -150,9 +150,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.408 2010/08/28 16:47:10 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.409 2010/08/28 17:21:46 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R39 2010/08/24"
|
||||
#define MKSH_VERSION "R39 2010/08/28"
|
||||
|
||||
#ifndef MKSH_INCLUDES_ONLY
|
||||
|
||||
@ -1472,6 +1472,7 @@ int c_mknod(const char **);
|
||||
#endif
|
||||
int c_realpath(const char **);
|
||||
int c_rename(const char **);
|
||||
int c_cat(const char **);
|
||||
/* histrap.c */
|
||||
void init_histvec(void);
|
||||
void hist_init(Source *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user