while testing haserl-0.9.26 on MirBSD, I discovered that the echo builtin
in FSH mode did in fact, contrary to POSIX and Debian Policy 10.4 behavi- our (I think), interpret escape sequences; fix and add testsuite for echo
This commit is contained in:
parent
b4a32ff5f7
commit
549888a183
23
check.t
23
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.320 2009/10/10 17:39:48 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.321 2009/10/10 21:17:28 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 2009/10/04
|
||||
@(#)MIRBSD KSH R39 2009/10/10
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
@ -6571,3 +6571,22 @@ stdin:
|
||||
expected-stdout:
|
||||
fxbar 0
|
||||
---
|
||||
name: echo-test-1
|
||||
description:
|
||||
Test what the echo builtin does (mksh)
|
||||
stdin:
|
||||
echo -n 'foo\x40bar'
|
||||
echo -e '\tbaz'
|
||||
expected-stdout:
|
||||
foo@bar baz
|
||||
---
|
||||
name: echo-test-2
|
||||
description:
|
||||
Test what the echo builtin does (POSIX)
|
||||
arguments: !-o!sh!
|
||||
stdin:
|
||||
echo -n 'foo\x40bar'
|
||||
echo -e '\tbaz'
|
||||
expected-stdout:
|
||||
foo\x40bar-e \tbaz
|
||||
---
|
||||
|
59
funcs.c
59
funcs.c
@ -25,7 +25,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.136 2009/10/02 18:08:33 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.137 2009/10/10 21:17:29 tg Exp $");
|
||||
|
||||
#if HAVE_KILLPG
|
||||
/*
|
||||
@ -507,31 +507,38 @@ c_print(const char **wp)
|
||||
#define PO_PMINUSMINUS BIT(2) /* print a -- argument */
|
||||
#define PO_HIST BIT(3) /* print to history instead of stdout */
|
||||
#define PO_COPROC BIT(4) /* printing to coprocess: block SIGPIPE */
|
||||
int fd = 1;
|
||||
int fd = 1, c;
|
||||
int flags = PO_EXPAND|PO_NL;
|
||||
const char *s, *emsg;
|
||||
XString xs;
|
||||
char *xp;
|
||||
|
||||
if (wp[0][0] == 'e') { /* echo command */
|
||||
int nflags = flags;
|
||||
|
||||
/* A compromise between sysV and BSD echo commands:
|
||||
* escape sequences are enabled by default, and
|
||||
* -n, -e and -E are recognised if they appear
|
||||
* in arguments with no illegal options (ie, echo -nq
|
||||
* will print -nq).
|
||||
* Different from sysV echo since options are recognised,
|
||||
* different from BSD echo since escape sequences are enabled
|
||||
* by default.
|
||||
*/
|
||||
wp += 1;
|
||||
if (wp[0][0] == 'e') {
|
||||
/* echo builtin */
|
||||
wp++;
|
||||
if (Flag(FSH)) {
|
||||
if (*wp && strcmp(*wp, "-n") == 0) {
|
||||
flags &= ~PO_NL;
|
||||
/* Debian Policy 10.4 compliant "echo" builtin */
|
||||
if (*wp && !strcmp(*wp, "-n")) {
|
||||
/* we recognise "-n" only as the first arg */
|
||||
flags = 0;
|
||||
wp++;
|
||||
}
|
||||
} else
|
||||
} else
|
||||
/* otherwise, we print everything as-is */
|
||||
flags = PO_NL;
|
||||
} else {
|
||||
int nflags = flags;
|
||||
|
||||
/**
|
||||
* a compromise between sysV and BSD echo commands:
|
||||
* escape sequences are enabled by default, and -n,
|
||||
* -e and -E are recognised if they appear in argu-
|
||||
* ments with no illegal options (ie, echo -nq will
|
||||
* print -nq).
|
||||
* Different from sysV echo since options are reco-
|
||||
* gnised, different from BSD echo since escape se-
|
||||
* quences are enabled by default.
|
||||
*/
|
||||
|
||||
while ((s = *wp) && *s == '-' && s[1]) {
|
||||
while (*++s)
|
||||
if (*s == 'n')
|
||||
@ -546,14 +553,17 @@ c_print(const char **wp)
|
||||
* nflags, print argument
|
||||
*/
|
||||
break;
|
||||
|
||||
if (*s)
|
||||
break;
|
||||
wp++;
|
||||
flags = nflags;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int optc;
|
||||
const char *opts = "Rnprsu,";
|
||||
|
||||
while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1)
|
||||
switch (optc) {
|
||||
case 'R': /* fake BSD echo command */
|
||||
@ -590,6 +600,7 @@ c_print(const char **wp)
|
||||
case '?':
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!(builtin_opt.info & GI_MINUSMINUS)) {
|
||||
/* treat a lone - like -- */
|
||||
if (wp[builtin_opt.optind] &&
|
||||
@ -603,7 +614,6 @@ c_print(const char **wp)
|
||||
Xinit(xs, xp, 128, ATEMP);
|
||||
|
||||
while (*wp != NULL) {
|
||||
int c;
|
||||
s = *wp;
|
||||
while ((c = *s++) != '\0') {
|
||||
Xcheck(xs, xp);
|
||||
@ -649,7 +659,7 @@ c_print(const char **wp)
|
||||
histsave(&source->line, Xstring(xs, xp), true, false);
|
||||
Xfree(xs, xp);
|
||||
} else {
|
||||
int n, len = Xlength(xs, xp);
|
||||
int len = Xlength(xs, xp);
|
||||
int opipe = 0;
|
||||
|
||||
/* Ensure we aren't killed by a SIGPIPE while writing to
|
||||
@ -662,8 +672,7 @@ c_print(const char **wp)
|
||||
opipe = block_pipe();
|
||||
}
|
||||
for (s = Xstring(xs, xp); len > 0; ) {
|
||||
n = write(fd, s, len);
|
||||
if (n < 0) {
|
||||
if ((c = write(fd, s, len)) < 0) {
|
||||
if (flags & PO_COPROC)
|
||||
restore_pipe(opipe);
|
||||
if (errno == EINTR) {
|
||||
@ -675,8 +684,8 @@ c_print(const char **wp)
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
s += n;
|
||||
len -= n;
|
||||
s += c;
|
||||
len -= c;
|
||||
}
|
||||
if (flags & PO_COPROC)
|
||||
restore_pipe(opipe);
|
||||
|
8
mksh.1
8
mksh.1
@ -1,4 +1,4 @@
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.193 2009/10/02 18:08:35 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.194 2009/10/10 21:17:30 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $
|
||||
.\"-
|
||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
@ -48,7 +48,7 @@
|
||||
.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
|
||||
..
|
||||
.\"-
|
||||
.Dd $Mdocdate: October 2 2009 $
|
||||
.Dd $Mdocdate: October 10 2009 $
|
||||
.Dt MKSH 1
|
||||
.Os MirBSD
|
||||
.Sh NAME
|
||||
@ -2694,7 +2694,7 @@ assignments are performed and exported for the duration of the command.
|
||||
.Pp
|
||||
The following describes the special and regular built-in commands:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact
|
||||
.Bl -tag -width false -compact
|
||||
.It Ic \&. Ar file Op Ar arg ...
|
||||
This is called the
|
||||
.Dq dot
|
||||
@ -3034,6 +3034,8 @@ If the
|
||||
option is set, only the first argument is treated as an option, and only
|
||||
if it is exactly
|
||||
.Dq Fl n .
|
||||
Backslash interpretation is disabled.
|
||||
.Pp
|
||||
.It Ic eval Ar command ...
|
||||
The arguments are concatenated (with spaces between them) to form a single
|
||||
string which the shell then parses and executes in the current environment.
|
||||
|
4
sh.h
4
sh.h
@ -134,9 +134,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.353 2009/10/04 13:19:33 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.354 2009/10/10 21:17:31 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R39 2009/10/04"
|
||||
#define MKSH_VERSION "R39 2009/10/10"
|
||||
|
||||
#ifndef MKSH_INCLUDES_ONLY
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user