• access(2) is broken in at least kFreeBSD 9.0 as “modern” OS, so bring

back the wrapper code as well as refactor most other code calling it
• apparently, names can’t end in ‘_’ or contain ‘__’ anywhere…
This commit is contained in:
tg
2011-09-07 15:24:22 +00:00
parent 577c918beb
commit 9782f6b4d1
16 changed files with 326 additions and 332 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.481 2011/08/27 18:06:38 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.482 2011/09/07 15:24:10 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas 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: 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 $ # $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 # http://www.research.att.com/~gsf/public/ifs.sh
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R40 2011/08/27 @(#)MIRBSD KSH R40 2011/09/07
description: description:
Check version of shell. Check version of shell.
stdin: stdin:

73
edit.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.220 2011/08/27 18:06:41 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/edit.c,v 1.221 2011/09/07 15:24:12 tg Exp $");
/* /*
* in later versions we might use libtermcap for this, but since external * in later versions we might use libtermcap for this, but since external
@ -695,7 +695,6 @@ glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
const char *sp = lpath, *p; const char *sp = lpath, *p;
char *xp, **words; char *xp, **words;
size_t pathlen, patlen, oldsize, newsize, i, j; size_t pathlen, patlen, oldsize, newsize, i, j;
int staterr;
XString xs; XString xs;
patlen = strlen(pat); patlen = strlen(pat);
@ -735,9 +734,7 @@ glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
/* Check that each match is executable... */ /* Check that each match is executable... */
words = (char **)XPptrv(*wp); words = (char **)XPptrv(*wp);
for (i = j = oldsize; i < newsize; i++) { for (i = j = oldsize; i < newsize; i++) {
staterr = 0; if (ksh_access(words[i], X_OK) == 0) {
if ((search_access(words[i], X_OK, &staterr) >= 0) ||
(staterr == EISDIR)) {
words[j] = words[i]; words[j] = words[i];
if (!(flags & XCF_FULLPATH)) if (!(flags & XCF_FULLPATH))
memmove(words[j], words[j] + pathlen, memmove(words[j], words[j] + pathlen,
@ -2467,7 +2464,7 @@ x_bind(const char *a1, const char *a2,
strcmp(x_ftab[f].xf_name, a2) == 0) strcmp(x_ftab[f].xf_name, a2) == 0)
break; break;
if (f == NELEM(x_ftab) || x_ftab[f].xf_flags & XF_NOBIND) { if (f == NELEM(x_ftab) || x_ftab[f].xf_flags & XF_NOBIND) {
bi_errorf("%s: %s %s", a2, "no such", T_function); bi_errorf("%s: %s %s", a2, "no such", Tfunction);
return (1); return (1);
} }
} }
@ -3291,58 +3288,58 @@ static void vi_error(void);
static void vi_macro_reset(void); static void vi_macro_reset(void);
static int x_vi_putbuf(const char *, size_t); static int x_vi_putbuf(const char *, size_t);
#define C_ 0x1 /* a valid command that isn't a M_, E_, U_ */ #define vC 0x01 /* a valid command that isn't a vM, vE, vU */
#define M_ 0x2 /* movement command (h, l, etc.) */ #define vM 0x02 /* movement command (h, l, etc.) */
#define E_ 0x4 /* extended command (c, d, y) */ #define vE 0x04 /* extended command (c, d, y) */
#define X_ 0x8 /* long command (@, f, F, t, T, etc.) */ #define vX 0x08 /* long command (@, f, F, t, T, etc.) */
#define U_ 0x10 /* an UN-undoable command (that isn't a M_) */ #define vU 0x10 /* an UN-undoable command (that isn't a vM) */
#define B_ 0x20 /* bad command (^@) */ #define vB 0x20 /* bad command (^@) */
#define Z_ 0x40 /* repeat count defaults to 0 (not 1) */ #define vZ 0x40 /* repeat count defaults to 0 (not 1) */
#define S_ 0x80 /* search (/, ?) */ #define vS 0x80 /* search (/, ?) */
#define is_bad(c) (classify[(c)&0x7f]&B_) #define is_bad(c) (classify[(c)&0x7f]&vB)
#define is_cmd(c) (classify[(c)&0x7f]&(M_|E_|C_|U_)) #define is_cmd(c) (classify[(c)&0x7f]&(vM|vE|vC|vU))
#define is_move(c) (classify[(c)&0x7f]&M_) #define is_move(c) (classify[(c)&0x7f]&vM)
#define is_extend(c) (classify[(c)&0x7f]&E_) #define is_extend(c) (classify[(c)&0x7f]&vE)
#define is_long(c) (classify[(c)&0x7f]&X_) #define is_long(c) (classify[(c)&0x7f]&vX)
#define is_undoable(c) (!(classify[(c)&0x7f]&U_)) #define is_undoable(c) (!(classify[(c)&0x7f]&vU))
#define is_srch(c) (classify[(c)&0x7f]&S_) #define is_srch(c) (classify[(c)&0x7f]&vS)
#define is_zerocount(c) (classify[(c)&0x7f]&Z_) #define is_zerocount(c) (classify[(c)&0x7f]&vZ)
static const unsigned char classify[128] = { static const unsigned char classify[128] = {
/* 0 1 2 3 4 5 6 7 */ /* 0 1 2 3 4 5 6 7 */
/* 0 ^@ ^A ^B ^C ^D ^E ^F ^G */ /* 0 ^@ ^A ^B ^C ^D ^E ^F ^G */
B_, 0, 0, 0, 0, C_|U_, C_|Z_, 0, vB, 0, 0, 0, 0, vC|vU, vC|vZ, 0,
/* 1 ^H ^I ^J ^K ^L ^M ^N ^O */ /* 1 ^H ^I ^J ^K ^L ^M ^N ^O */
M_, C_|Z_, 0, 0, C_|U_, 0, C_, 0, vM, vC|vZ, 0, 0, vC|vU, 0, vC, 0,
/* 2 ^P ^Q ^R ^S ^T ^U ^V ^W */ /* 2 ^P ^Q ^R ^S ^T ^U ^V ^W */
C_, 0, C_|U_, 0, 0, 0, C_, 0, vC, 0, vC|vU, 0, 0, 0, vC, 0,
/* 3 ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */ /* 3 ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
C_, 0, 0, C_|Z_, 0, 0, 0, 0, vC, 0, 0, vC|vZ, 0, 0, 0, 0,
/* 4 <space> ! " # $ % & ' */ /* 4 <space> ! " # $ % & ' */
M_, 0, 0, C_, M_, M_, 0, 0, vM, 0, 0, vC, vM, vM, 0, 0,
/* 5 ( ) * + , - . / */ /* 5 ( ) * + , - . / */
0, 0, C_, C_, M_, C_, 0, C_|S_, 0, 0, vC, vC, vM, vC, 0, vC|vS,
/* 6 0 1 2 3 4 5 6 7 */ /* 6 0 1 2 3 4 5 6 7 */
M_, 0, 0, 0, 0, 0, 0, 0, vM, 0, 0, 0, 0, 0, 0, 0,
/* 7 8 9 : ; < = > ? */ /* 7 8 9 : ; < = > ? */
0, 0, 0, M_, 0, C_, 0, C_|S_, 0, 0, 0, vM, 0, vC, 0, vC|vS,
/* 8 @ A B C D E F G */ /* 8 @ A B C D E F G */
C_|X_, C_, M_, C_, C_, M_, M_|X_, C_|U_|Z_, vC|vX, vC, vM, vC, vC, vM, vM|vX, vC|vU|vZ,
/* 9 H I J K L M N O */ /* 9 H I J K L M N O */
0, C_, 0, 0, 0, 0, C_|U_, 0, 0, vC, 0, 0, 0, 0, vC|vU, 0,
/* A P Q R S T U V W */ /* A P Q R S T U V W */
C_, 0, C_, C_, M_|X_, C_, 0, M_, vC, 0, vC, vC, vM|vX, vC, 0, vM,
/* B X Y Z [ \ ] ^ _ */ /* B X Y Z [ \ ] ^ _ */
C_, C_|U_, 0, 0, C_|Z_, 0, M_, C_|Z_, vC, vC|vU, 0, 0, vC|vZ, 0, vM, vC|vZ,
/* C ` a b c d e f g */ /* C ` a b c d e f g */
0, C_, M_, E_, E_, M_, M_|X_, C_|Z_, 0, vC, vM, vE, vE, vM, vM|vX, vC|vZ,
/* D h i j k l m n o */ /* D h i j k l m n o */
M_, C_, C_|U_, C_|U_, M_, 0, C_|U_, 0, vM, vC, vC|vU, vC|vU, vM, 0, vC|vU, 0,
/* E p q r s t u v w */ /* E p q r s t u v w */
C_, 0, X_, C_, M_|X_, C_|U_, C_|U_|Z_, M_, vC, 0, vX, vC, vM|vX, vC|vU, vC|vU|vZ, vM,
/* F x y z { | } ~ ^? */ /* F x y z { | } ~ ^? */
C_, E_|U_, 0, 0, M_|Z_, 0, C_, 0 vC, vE|vU, 0, 0, vM|vZ, 0, vC, 0
}; };
#define MAXVICMD 3 #define MAXVICMD 3

36
eval.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.107 2011/08/27 18:06:42 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.108 2011/09/07 15:24:13 tg Exp $");
/* /*
* string expansion * string expansion
@ -232,7 +232,7 @@ expand(const char *cp, /* input word */
if (Flag(FMARKDIRS)) if (Flag(FMARKDIRS))
f |= DOMARKDIRS; f |= DOMARKDIRS;
if (Flag(FBRACEEXPAND) && (f & DOGLOB)) if (Flag(FBRACEEXPAND) && (f & DOGLOB))
f |= DOBRACE_; f |= DOBRACE;
/* init destination string */ /* init destination string */
Xinit(ds, dp, 128, ATEMP); Xinit(ds, dp, 128, ATEMP);
@ -573,9 +573,9 @@ expand(const char *cp, /* input word */
} }
case '#': case '#':
case '%': case '%':
/* ! DOBLANK,DOBRACE_,DOTILDE */ /* ! DOBLANK,DOBRACE,DOTILDE */
f = DOPAT | (f&DONTRUNCOMMAND) | f = DOPAT | (f&DONTRUNCOMMAND) |
DOTEMP_; DOTEMP;
st->quotew = quote = 0; st->quotew = quote = 0;
/* /*
* Prepend open pattern (so | * Prepend open pattern (so |
@ -604,17 +604,17 @@ expand(const char *cp, /* input word */
*/ */
if (!(x.var->flag & INTEGER)) if (!(x.var->flag & INTEGER))
f |= DOASNTILDE|DOTILDE; f |= DOASNTILDE|DOTILDE;
f |= DOTEMP_; f |= DOTEMP;
/* /*
* These will be done after the * These will be done after the
* value has been assigned. * value has been assigned.
*/ */
f &= ~(DOBLANK|DOGLOB|DOBRACE_); f &= ~(DOBLANK|DOGLOB|DOBRACE);
tilde_ok = 1; tilde_ok = 1;
break; break;
case '?': case '?':
f &= ~DOBLANK; f &= ~DOBLANK;
f |= DOTEMP_; f |= DOTEMP;
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
/* Enable tilde expansion */ /* Enable tilde expansion */
@ -849,14 +849,14 @@ expand(const char *cp, /* input word */
*dp++ = '\0'; *dp++ = '\0';
p = Xclose(ds, dp); p = Xclose(ds, dp);
if (fdo & DOBRACE_) if (fdo & DOBRACE)
/* also does globbing */ /* also does globbing */
alt_expand(wp, p, p, alt_expand(wp, p, p,
p + Xlength(ds, (dp - 1)), p + Xlength(ds, (dp - 1)),
fdo | (f & DOMARKDIRS)); fdo | (f & DOMARKDIRS));
else if (fdo & DOGLOB) else if (fdo & DOGLOB)
glob(p, wp, f & DOMARKDIRS); glob(p, wp, f & DOMARKDIRS);
else if ((f & DOPAT) || !(fdo & DOMAGIC_)) else if ((f & DOPAT) || !(fdo & DOMAGIC))
XPput(*wp, p); XPput(*wp, p);
else else
XPput(*wp, debunk(p, p, strlen(p) + 1)); XPput(*wp, debunk(p, p, strlen(p) + 1));
@ -897,7 +897,7 @@ expand(const char *cp, /* input word */
* [...] expressions. * [...] expressions.
*/ */
if (f & (DOPAT | DOGLOB)) { if (f & (DOPAT | DOGLOB)) {
fdo |= DOMAGIC_; fdo |= DOMAGIC;
if (c == '[') if (c == '[')
fdo |= f & DOGLOB; fdo |= f & DOGLOB;
*dp++ = MAGIC; *dp++ = MAGIC;
@ -906,22 +906,22 @@ expand(const char *cp, /* input word */
case '*': case '*':
case '?': case '?':
if (f & (DOPAT | DOGLOB)) { if (f & (DOPAT | DOGLOB)) {
fdo |= DOMAGIC_ | (f & DOGLOB); fdo |= DOMAGIC | (f & DOGLOB);
*dp++ = MAGIC; *dp++ = MAGIC;
} }
break; break;
case OBRACE: case OBRACE:
case ',': case ',':
case CBRACE: case CBRACE:
if ((f & DOBRACE_) && (c == OBRACE || if ((f & DOBRACE) && (c == OBRACE ||
(fdo & DOBRACE_))) { (fdo & DOBRACE))) {
fdo |= DOBRACE_|DOMAGIC_; fdo |= DOBRACE|DOMAGIC;
*dp++ = MAGIC; *dp++ = MAGIC;
} }
break; break;
case '=': case '=':
/* Note first unquoted = for ~ */ /* Note first unquoted = for ~ */
if (!(f & DOTEMP_) && !saw_eq && if (!(f & DOTEMP) && !saw_eq &&
(Flag(FBRACEEXPAND) || (Flag(FBRACEEXPAND) ||
(f & DOASNTILDE))) { (f & DOASNTILDE))) {
saw_eq = 1; saw_eq = 1;
@ -931,7 +931,7 @@ expand(const char *cp, /* input word */
case ':': case ':':
/* : */ /* : */
/* Note unquoted : for ~ */ /* Note unquoted : for ~ */
if (!(f & DOTEMP_) && (f & DOASNTILDE)) if (!(f & DOTEMP) && (f & DOASNTILDE))
tilde_ok = 1; tilde_ok = 1;
break; break;
case '~': case '~':
@ -967,10 +967,10 @@ expand(const char *cp, /* input word */
if (make_magic) { if (make_magic) {
make_magic = 0; make_magic = 0;
fdo |= DOMAGIC_ | (f & DOGLOB); fdo |= DOMAGIC | (f & DOGLOB);
*dp++ = MAGIC; *dp++ = MAGIC;
} else if (ISMAGIC(c)) { } else if (ISMAGIC(c)) {
fdo |= DOMAGIC_; fdo |= DOMAGIC;
*dp++ = MAGIC; *dp++ = MAGIC;
} }
/* save output char */ /* save output char */

127
exec.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.95 2011/08/27 18:06:43 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.96 2011/09/07 15:24:14 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL #ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh" #define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -38,6 +38,7 @@ static const char *do_selectargs(const char **, bool);
static Test_op dbteste_isa(Test_env *, Test_meta); static Test_op dbteste_isa(Test_env *, Test_meta);
static const char *dbteste_getopnd(Test_env *, Test_op, bool); static const char *dbteste_getopnd(Test_env *, Test_op, bool);
static void dbteste_error(Test_env *, int, const char *); static void dbteste_error(Test_env *, int, const char *);
static int search_access(const char *, int);
/* /*
* execute command tree * execute command tree
@ -102,7 +103,7 @@ execute(struct op * volatile t,
/* set variable to its expanded value */ /* set variable to its expanded value */
z = strlen(cp) + 1; z = strlen(cp) + 1;
if (notoktomul(z, 2) || notoktoadd(z * 2, n)) if (notoktomul(z, 2) || notoktoadd(z * 2, n))
internal_errorf(T_oomem, (unsigned long)-1); internal_errorf(Toomem, (unsigned long)-1);
dp = alloc(z * 2 + n, ATEMP); dp = alloc(z * 2 + n, ATEMP);
memcpy(dp, t->vars[0], n); memcpy(dp, t->vars[0], n);
t->vars[0] = dp; t->vars[0] = dp;
@ -481,7 +482,7 @@ execute(struct op * volatile t,
unwind(LEXIT); unwind(LEXIT);
if (rv != 0 && !(flags & XERROK) && if (rv != 0 && !(flags & XERROK) &&
(xerrok == NULL || !*xerrok)) { (xerrok == NULL || !*xerrok)) {
trapsig(SIGERR_); trapsig(ksh_SIGERR);
if (Flag(FERREXIT)) if (Flag(FERREXIT))
unwind(LERROR); unwind(LERROR);
} }
@ -546,7 +547,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
break; break;
} }
if ((tp = findcom(cp, FC_BI)) == NULL) if ((tp = findcom(cp, FC_BI)) == NULL)
errorf("%s: %s: %s", T_builtin, cp, "not a builtin"); errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin");
continue; continue;
} else if (tp->val.f == c_exec) { } else if (tp->val.f == c_exec) {
if (ap[1] == NULL) if (ap[1] == NULL)
@ -678,18 +679,10 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
struct tbl *ftp; struct tbl *ftp;
if (!tp->u.fpath) { if (!tp->u.fpath) {
if (tp->u2.errno_) { rv = (tp->u2.errnov == ENOENT) ? 127 : 126;
warningf(true, "%s: %s %s: %s", cp, warningf(true, "%s: %s %s: %s", cp,
"can't find", "can't find", "function definition file",
"function definition file", strerror(tp->u2.errnov));
strerror(tp->u2.errno_));
rv = 126;
} else {
warningf(true, "%s: %s %s", cp,
"can't find",
"function definition file");
rv = 127;
}
break; break;
} }
if (include(tp->u.fpath, 0, NULL, 0) < 0) { if (include(tp->u.fpath, 0, NULL, 0) < 0) {
@ -785,20 +778,13 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
/* tracked alias */ /* tracked alias */
case CTALIAS: case CTALIAS:
if (!(tp->flag&ISSET)) { if (!(tp->flag&ISSET)) {
/* if (tp->u2.errnov == ENOENT) {
* errno_ will be set if the named command was found
* but could not be executed (permissions, no execute
* bit, directory, etc). Print out a (hopefully)
* useful error message and set the exit status to 126.
*/
if (tp->u2.errno_) {
warningf(true, "%s: %s: %s", cp,
"can't execute", strerror(tp->u2.errno_));
/* POSIX */
rv = 126;
} else {
warningf(true, "%s: %s", cp, "not found");
rv = 127; rv = 127;
warningf(true, "%s: %s", cp, "not found");
} else {
rv = 126;
warningf(true, "%s: %s: %s", cp, "can't execute",
strerror(tp->u2.errnov));
} }
break; break;
} }
@ -851,7 +837,7 @@ scriptexec(struct op *tp, const char **ap)
sh = str_val(global("EXECSHELL")); sh = str_val(global("EXECSHELL"));
if (sh && *sh) if (sh && *sh)
sh = search(sh, path, X_OK, NULL); sh = search_path(sh, path, X_OK, NULL);
if (!sh || !*sh) if (!sh || !*sh)
sh = MKSH_DEFAULT_EXECSHELL; sh = MKSH_DEFAULT_EXECSHELL;
@ -1094,10 +1080,10 @@ findcom(const char *name, int flags)
if (tp && !(tp->flag & ISSET)) { if (tp && !(tp->flag & ISSET)) {
if ((fpath = str_val(global("FPATH"))) == null) { if ((fpath = str_val(global("FPATH"))) == null) {
tp->u.fpath = NULL; tp->u.fpath = NULL;
tp->u2.errno_ = 0; tp->u2.errnov = ENOENT;
} else } else
tp->u.fpath = search(name, fpath, R_OK, tp->u.fpath = search_path(name, fpath, R_OK,
&tp->u2.errno_); &tp->u2.errnov);
} }
} }
if (!tp && (flags & FC_REGBI) && tbi && (tbi->flag & REG_BI)) if (!tp && (flags & FC_REGBI) && tbi && (tbi->flag & REG_BI))
@ -1106,7 +1092,8 @@ findcom(const char *name, int flags)
tp = tbi; tp = tbi;
if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) { if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {
tp = ktsearch(&taliases, name, h); tp = ktsearch(&taliases, name, h);
if (tp && (tp->flag & ISSET) && access(tp->val.s, X_OK) != 0) { if (tp && (tp->flag & ISSET) &&
ksh_access(tp->val.s, X_OK) != 0) {
if (tp->flag & ALLOC) { if (tp->flag & ALLOC) {
tp->flag &= ~ALLOC; tp->flag &= ~ALLOC;
afree(tp->val.s, APERM); afree(tp->val.s, APERM);
@ -1129,8 +1116,9 @@ findcom(const char *name, int flags)
/* make ~ISSET */ /* make ~ISSET */
tp->flag = DEFINED; tp->flag = DEFINED;
} }
npath.ro = search(name, flags & FC_DEFPATH ? def_path : path, npath.ro = search_path(name,
X_OK, &tp->u2.errno_); (flags & FC_DEFPATH) ? def_path : path,
X_OK, &tp->u2.errnov);
if (npath.ro) { if (npath.ro) {
strdupx(tp->val.s, npath.ro, APERM); strdupx(tp->val.s, npath.ro, APERM);
if (npath.ro != name) if (npath.ro != name)
@ -1138,8 +1126,8 @@ findcom(const char *name, int flags)
tp->flag |= ISSET|ALLOC; tp->flag |= ISSET|ALLOC;
} else if ((flags & FC_FUNC) && } else if ((flags & FC_FUNC) &&
(fpath = str_val(global("FPATH"))) != null && (fpath = str_val(global("FPATH"))) != null &&
(npath.ro = search(name, fpath, R_OK, (npath.ro = search_path(name, fpath, R_OK,
&tp->u2.errno_)) != NULL) { &tp->u2.errnov)) != NULL) {
/* /*
* An undocumented feature of AT&T ksh is that * An undocumented feature of AT&T ksh is that
* it searches FPATH if a command is not found, * it searches FPATH if a command is not found,
@ -1176,37 +1164,31 @@ flushcom(bool all)
} }
} }
/* Check if path is something we want to find. Returns -1 for failure. */ /* check if path is something we want to find */
int static int
search_access(const char *lpath, int mode, search_access(const char *fn, int mode)
/* set if candidate found, but not suitable */
int *errnop)
{ {
int ret, err = 0; struct stat sb;
struct stat statb;
if (stat(lpath, &statb) < 0) if (stat(fn, &sb) < 0)
return (-1); /* file does not exist */
ret = access(lpath, mode); return (ENOENT);
if (ret < 0) /* LINTED use of access */
/* File exists, but we can't access it */ if (access(fn, mode) < 0)
err = errno; /* file exists, but we can't access it */
else if (mode == X_OK && (!S_ISREG(statb.st_mode) || return (errno);
!(statb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))) { if (mode == X_OK && (!S_ISREG(sb.st_mode) ||
/* This 'cause access() says root can execute everything */ !(sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))))
ret = -1; /* access(2) may say root can execute everything */
err = S_ISDIR(statb.st_mode) ? EISDIR : EACCES; return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES);
} return (0);
if (err && errnop && !*errnop)
*errnop = err;
return (ret);
} }
/* /*
* search for command with PATH * search for command with PATH
*/ */
const char * const char *
search(const char *name, const char *lpath, search_path(const char *name, const char *lpath,
/* R_OK or X_OK */ /* R_OK or X_OK */
int mode, int mode,
/* set if candidate found, but not suitable */ /* set if candidate found, but not suitable */
@ -1216,13 +1198,16 @@ search(const char *name, const char *lpath,
char *xp; char *xp;
XString xs; XString xs;
size_t namelen; size_t namelen;
int ec = 0, ev;
if (errnop)
*errnop = 0;
if (vstrchr(name, '/')) { if (vstrchr(name, '/')) {
if (search_access(name, mode, errnop) == 0) if ((ec = search_access(name, mode)) == 0) {
search_path_ok:
if (errnop)
*errnop = 0;
return (name); return (name);
return (NULL); }
goto search_path_err;
} }
namelen = strlen(name) + 1; namelen = strlen(name) + 1;
@ -1242,12 +1227,20 @@ search(const char *name, const char *lpath,
sp = p; sp = p;
XcheckN(xs, xp, namelen); XcheckN(xs, xp, namelen);
memcpy(xp, name, namelen); memcpy(xp, name, namelen);
if (search_access(Xstring(xs, xp), mode, errnop) == 0) if ((ev = search_access(Xstring(xs, xp), mode)) == 0) {
return (Xclose(xs, xp + namelen)); name = Xclose(xs, xp + namelen);
goto search_path_ok;
}
/* accumulate non-ENOENT errors only */
if (ev != ENOENT && ec == 0)
ec = ev;
if (*sp++ == '\0') if (*sp++ == '\0')
sp = NULL; sp = NULL;
} }
Xfree(xs, xp); Xfree(xs, xp);
search_path_err:
if (errnop)
*errnop = ec ? ec : ENOENT;
return (NULL); return (NULL);
} }

21
expr.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.48 2011/08/27 18:06:44 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/expr.c,v 1.49 2011/09/07 15:24:14 tg Exp $");
/* The order of these enums is constrained by the order of opinfo[] */ /* The order of these enums is constrained by the order of opinfo[] */
enum token { enum token {
@ -913,3 +913,22 @@ utf_wcwidth(unsigned int c)
} }
/* --- end of wcwidth.c excerpt --- */ /* --- end of wcwidth.c excerpt --- */
#endif #endif
/*
* Wrapper around access(2) because it says root can execute everything
* on some operating systems. Does not set errno, no user needs it. Use
* this iff mode can have the X_OK bit set, access otherwise.
*/
int
ksh_access(const char *fn, int mode)
{
int rv;
struct stat sb;
if ((rv = access(fn, mode)) == 0 && kshuid == 0 && (mode & X_OK) &&
(rv = stat(fn, &sb)) == 0 && !S_ISDIR(sb.st_mode) &&
(sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0)
rv = -1;
return (rv);
}

91
funcs.c
View File

@ -38,7 +38,7 @@
#endif #endif
#endif #endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.196 2011/08/27 18:06:44 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.197 2011/09/07 15:24:15 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -87,14 +87,14 @@ const struct builtin mkshbuiltins[] = {
{"*=:", c_true}, {"*=:", c_true},
{"[", c_test}, {"[", c_test},
{"*=break", c_brkcont}, {"*=break", c_brkcont},
{T_gbuiltin, c_builtin}, {Tgbuiltin, c_builtin},
{"*=continue", c_brkcont}, {"*=continue", c_brkcont},
{"*=eval", c_eval}, {"*=eval", c_eval},
{"*=exec", c_exec}, {"*=exec", c_exec},
{"*=exit", c_exitreturn}, {"*=exit", c_exitreturn},
{"+false", c_false}, {"+false", c_false},
{"*=return", c_exitreturn}, {"*=return", c_exitreturn},
{T_sgset, c_set}, {Tsgset, c_set},
{"*=shift", c_shift}, {"*=shift", c_shift},
{"=times", c_times}, {"=times", c_times},
{"*=trap", c_trap}, {"*=trap", c_trap},
@ -106,7 +106,7 @@ const struct builtin mkshbuiltins[] = {
{"+umask", c_umask}, {"+umask", c_umask},
{"*=unset", c_unset}, {"*=unset", c_unset},
/* no =: AT&T manual wrong */ /* no =: AT&T manual wrong */
{T_palias, c_alias}, {Tpalias, c_alias},
{"+cd", c_cd}, {"+cd", c_cd},
/* dash compatibility hack */ /* dash compatibility hack */
{"chdir", c_cd}, {"chdir", c_cd},
@ -125,8 +125,8 @@ const struct builtin mkshbuiltins[] = {
#endif #endif
{"pwd", c_pwd}, {"pwd", c_pwd},
{"*=readonly", c_typeset}, {"*=readonly", c_typeset},
{T__typeset, c_typeset}, {T_typeset, c_typeset},
{T_punalias, c_unalias}, {Tpunalias, c_unalias},
{"whence", c_whence}, {"whence", c_whence},
#ifndef MKSH_UNEMPLOYED #ifndef MKSH_UNEMPLOYED
{"+bg", c_fgbg}, {"+bg", c_fgbg},
@ -205,7 +205,6 @@ static const struct t_op b_ops[] = {
{"", TO_NONOP } {"", TO_NONOP }
}; };
static int test_eaccess(const char *, int);
static int test_oexpr(Test_env *, bool); static int test_oexpr(Test_env *, bool);
static int test_aexpr(Test_env *, bool); static int test_aexpr(Test_env *, bool);
static int test_nexpr(Test_env *, bool); static int test_nexpr(Test_env *, bool);
@ -244,6 +243,7 @@ c_pwd(const char **wp)
} }
p = current_wd[0] ? (physical ? allocd = do_realpath(current_wd) : p = current_wd[0] ? (physical ? allocd = do_realpath(current_wd) :
current_wd) : NULL; current_wd) : NULL;
/* LINTED use of access */
if (p && access(p, R_OK) < 0) if (p && access(p, R_OK) < 0)
p = NULL; p = NULL;
if (!p && !(p = allocd = ksh_get_wd())) { if (!p && !(p = allocd = ksh_get_wd())) {
@ -544,9 +544,9 @@ c_whence(const char **wp)
if (vflag) if (vflag)
shprintf("n %s%s for ", shprintf("n %s%s for ",
(tp->flag & EXPORT) ? "exported " : null, (tp->flag & EXPORT) ? "exported " : null,
T_alias); Talias);
if (!iam_whence && !vflag) if (!iam_whence && !vflag)
shprintf("%s %s=", T_alias, id); shprintf("%s %s=", Talias, id);
print_value_quoted(tp->val.s); print_value_quoted(tp->val.s);
break; break;
case CFUNC: case CFUNC:
@ -561,14 +561,14 @@ c_whence(const char **wp)
shprintf(" (autoload from %s)", shprintf(" (autoload from %s)",
tp->u.fpath); tp->u.fpath);
} }
shf_puts(T__function, shl_stdout); shf_puts(T_function, shl_stdout);
} }
break; break;
case CSHELL: case CSHELL:
if (vflag) if (vflag)
shprintf("%s %s %s", shprintf("%s %s %s",
(tp->flag & SPEC_BI) ? " special" : null, (tp->flag & SPEC_BI) ? " special" : null,
"shell", T_builtin); "shell", Tbuiltin);
break; break;
case CTALIAS: case CTALIAS:
case CEXEC: case CEXEC:
@ -579,7 +579,7 @@ c_whence(const char **wp)
shprintf("a tracked %s%s for ", shprintf("a tracked %s%s for ",
(tp->flag & EXPORT) ? (tp->flag & EXPORT) ?
"exported " : null, "exported " : null,
T_alias); Talias);
} }
shf_puts(tp->val.s, shl_stdout); shf_puts(tp->val.s, shl_stdout);
} else { } else {
@ -1031,12 +1031,12 @@ c_alias(const char **wp)
/* "hash -r" means reset all the tracked aliases.. */ /* "hash -r" means reset all the tracked aliases.. */
if (rflag) { if (rflag) {
static const char *args[] = { static const char *args[] = {
T_unalias, "-ta", NULL Tunalias, "-ta", NULL
}; };
if (!tflag || *wp) { if (!tflag || *wp) {
shprintf("%s: -r flag can only be used with -t" shprintf("%s: -r flag can only be used with -t"
" and without arguments\n", T_alias); " and without arguments\n", Talias);
return (1); return (1);
} }
ksh_getopt_reset(&builtin_opt, GF_ERROR); ksh_getopt_reset(&builtin_opt, GF_ERROR);
@ -1049,7 +1049,7 @@ c_alias(const char **wp)
for (p = ktsort(t); (ap = *p++) != NULL; ) for (p = ktsort(t); (ap = *p++) != NULL; )
if ((ap->flag & (ISSET|xflag)) == (ISSET|xflag)) { if ((ap->flag & (ISSET|xflag)) == (ISSET|xflag)) {
if (pflag) if (pflag)
shprintf("%s ", T_alias); shprintf("%s ", Talias);
shf_puts(ap->name, shl_stdout); shf_puts(ap->name, shl_stdout);
if (prefix != '+') { if (prefix != '+') {
shf_putc('=', shl_stdout); shf_putc('=', shl_stdout);
@ -1074,7 +1074,7 @@ c_alias(const char **wp)
ap = ktsearch(t, alias, h); ap = ktsearch(t, alias, h);
if (ap != NULL && (ap->flag&ISSET)) { if (ap != NULL && (ap->flag&ISSET)) {
if (pflag) if (pflag)
shprintf("%s ", T_alias); shprintf("%s ", Talias);
shf_puts(ap->name, shl_stdout); shf_puts(ap->name, shl_stdout);
if (prefix != '+') { if (prefix != '+') {
shf_putc('=', shl_stdout); shf_putc('=', shl_stdout);
@ -1082,7 +1082,7 @@ c_alias(const char **wp)
} }
shf_putc('\n', shl_stdout); shf_putc('\n', shl_stdout);
} else { } else {
shprintf("%s %s %s\n", alias, T_alias, shprintf("%s %s %s\n", alias, Talias,
"not found"); "not found");
rv = 1; rv = 1;
} }
@ -1097,7 +1097,9 @@ c_alias(const char **wp)
afree(ap->val.s, APERM); afree(ap->val.s, APERM);
} }
/* ignore values for -t (AT&T ksh does this) */ /* ignore values for -t (AT&T ksh does this) */
newval = tflag ? search(alias, path, X_OK, NULL) : val; newval = tflag ?
search_path(alias, path, X_OK, NULL) :
val;
if (newval) { if (newval) {
strdupx(ap->val.s, newval, APERM); strdupx(ap->val.s, newval, APERM);
ap->flag |= ALLOC|ISSET; ap->flag |= ALLOC|ISSET;
@ -1711,9 +1713,8 @@ c_dot(const char **wp)
bi_errorf("missing argument"); bi_errorf("missing argument");
return (1); return (1);
} }
if ((file = search(cp, path, R_OK, &errcode)) == NULL) { if ((file = search_path(cp, path, R_OK, &errcode)) == NULL) {
bi_errorf("%s: %s", cp, bi_errorf("%s: %s", cp, strerror(errcode));
errcode ? strerror(errcode) : "not found");
return (1); return (1);
} }
@ -1821,7 +1822,7 @@ c_read(const char **wp)
#if HAVE_SELECT #if HAVE_SELECT
case 't': case 't':
if (parse_usec(builtin_opt.optarg, &tv)) { if (parse_usec(builtin_opt.optarg, &tv)) {
bi_errorf("%s: %s '%s'", T_synerr, strerror(errno), bi_errorf("%s: %s '%s'", Tsynerr, strerror(errno),
builtin_opt.optarg); builtin_opt.optarg);
return (2); return (2);
} }
@ -1903,7 +1904,7 @@ c_read(const char **wp)
rv = 1; rv = 1;
goto c_read_out; goto c_read_out;
default: default:
bi_errorf("%s: %s", T_select, strerror(errno)); bi_errorf("%s: %s", Tselect, strerror(errno));
rv = 2; rv = 2;
goto c_read_out; goto c_read_out;
} }
@ -2361,7 +2362,7 @@ c_set(const char **wp)
const char **owp; const char **owp;
if (wp[1] == NULL) { if (wp[1] == NULL) {
static const char *args[] = { T_set, "-", NULL }; static const char *args[] = { Tset, "-", NULL };
return (c_typeset(args)); return (c_typeset(args));
} }
@ -2862,15 +2863,17 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
/* -r */ /* -r */
case TO_FILRD: case TO_FILRD:
return (test_eaccess(opnd1, R_OK) == 0); /* LINTED use of access */
return (access(opnd1, R_OK) == 0);
/* -w */ /* -w */
case TO_FILWR: case TO_FILWR:
return (test_eaccess(opnd1, W_OK) == 0); /* LINTED use of access */
return (access(opnd1, W_OK) == 0);
/* -x */ /* -x */
case TO_FILEX: case TO_FILEX:
return (test_eaccess(opnd1, X_OK) == 0); return (ksh_access(opnd1, X_OK) == 0);
/* -a */ /* -a */
case TO_FILAXST: case TO_FILAXST:
@ -3067,26 +3070,6 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
return (1); return (1);
} }
/* On most/all unixen, access() says everything is executable for root... */
static int
test_eaccess(const char *pathl, int mode)
{
int rv;
if ((rv = access(pathl, mode)) == 0 && ksheuid == 0 && (mode & X_OK)) {
struct stat statb;
if (stat(pathl, &statb) < 0)
rv = -1;
else if (S_ISDIR(statb.st_mode))
rv = 0;
else
rv = (statb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) ?
0 : -1;
}
return (rv);
}
int int
test_parse(Test_env *te) test_parse(Test_env *te)
{ {
@ -3516,7 +3499,7 @@ c_rename(const char **wp)
if (wp[0] == NULL /* first argument */ || if (wp[0] == NULL /* first argument */ ||
wp[1] == NULL /* second argument */ || wp[1] == NULL /* second argument */ ||
wp[2] != NULL /* no further args please */) wp[2] != NULL /* no further args please */)
bi_errorf(T_synerr); bi_errorf(Tsynerr);
else if ((rv = rename(wp[0], wp[1])) != 0) { else if ((rv = rename(wp[0], wp[1])) != 0) {
rv = errno; rv = errno;
bi_errorf("%s: %s", "failed", strerror(rv)); bi_errorf("%s: %s", "failed", strerror(rv));
@ -3539,7 +3522,7 @@ c_realpath(const char **wp)
/* check for exactly one argument */ /* check for exactly one argument */
if (wp[0] == NULL || wp[1] != NULL) if (wp[0] == NULL || wp[1] != NULL)
bi_errorf(T_synerr); bi_errorf(Tsynerr);
else if ((buf = do_realpath(wp[0])) == NULL) { else if ((buf = do_realpath(wp[0])) == NULL) {
rv = errno; rv = errno;
bi_errorf("%s: %s", wp[0], strerror(rv)); bi_errorf("%s: %s", wp[0], strerror(rv));
@ -3564,7 +3547,7 @@ c_cat(const char **wp)
#define MKSH_CAT_BUFSIZ 4096 #define MKSH_CAT_BUFSIZ 4096
if ((buf = malloc_osfunc(MKSH_CAT_BUFSIZ)) == NULL) { if ((buf = malloc_osfunc(MKSH_CAT_BUFSIZ)) == NULL) {
bi_errorf(T_oomem, (unsigned long)MKSH_CAT_BUFSIZ); bi_errorf(Toomem, (unsigned long)MKSH_CAT_BUFSIZ);
return (1); return (1);
} }
@ -3575,7 +3558,7 @@ c_cat(const char **wp)
/* we already operate unbuffered */ /* we already operate unbuffered */
break; break;
default: default:
bi_errorf(T_synerr); bi_errorf(Tsynerr);
return (1); return (1);
} }
} }
@ -3653,9 +3636,9 @@ c_sleep(const char **wp)
++wp; ++wp;
if (!wp[0] || wp[1]) if (!wp[0] || wp[1])
bi_errorf(T_synerr); bi_errorf(Tsynerr);
else if (parse_usec(wp[0], &tv)) else if (parse_usec(wp[0], &tv))
bi_errorf("%s: %s '%s'", T_synerr, strerror(errno), wp[0]); bi_errorf("%s: %s '%s'", Tsynerr, strerror(errno), wp[0]);
else { else {
#ifndef MKSH_NOPROSPECTOFWORK #ifndef MKSH_NOPROSPECTOFWORK
sigset_t omask; sigset_t omask;
@ -3670,7 +3653,7 @@ c_sleep(const char **wp)
*/ */
rv = 0; rv = 0;
else else
bi_errorf("%s: %s", T_select, strerror(errno)); bi_errorf("%s: %s", Tselect, strerror(errno));
#ifndef MKSH_NOPROSPECTOFWORK #ifndef MKSH_NOPROSPECTOFWORK
sigprocmask(SIG_SETMASK, &omask, NULL); sigprocmask(SIG_SETMASK, &omask, NULL);
#endif #endif

View File

@ -26,7 +26,7 @@
#include <sys/file.h> #include <sys/file.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.110 2011/08/27 18:06:45 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.111 2011/09/07 15:24:16 tg Exp $");
/*- /*-
* MirOS: This is the default mapping type, and need not be specified. * MirOS: This is the default mapping type, and need not be specified.
@ -66,8 +66,8 @@ static int histfd;
static size_t hsize; static size_t hsize;
#endif #endif
static const char T_not_in_history[] = "not in history"; static const char Tnot_in_history[] = "not in history";
#define T_history (T_not_in_history + 7) #define Thistory (Tnot_in_history + 7)
int int
c_fc(const char **wp) c_fc(const char **wp)
@ -83,7 +83,7 @@ c_fc(const char **wp)
char **hfirst, **hlast, **hp; char **hfirst, **hlast, **hp;
if (!Flag(FTALKING_I)) { if (!Flag(FTALKING_I)) {
bi_errorf("history %ss not available", T_function); bi_errorf("history %ss not available", Tfunction);
return (1); return (1);
} }
@ -290,7 +290,7 @@ c_fc(const char **wp)
if (stat(tf->name, &statb) < 0) if (stat(tf->name, &statb) < 0)
n = 128; n = 128;
else if (statb.st_size > (1024 * 1048576)) { else if (statb.st_size > (1024 * 1048576)) {
bi_errorf("%s %s too large: %lu", T_history, bi_errorf("%s %s too large: %lu", Thistory,
"file", (unsigned long)statb.st_size); "file", (unsigned long)statb.st_size);
goto errout; goto errout;
} else } else
@ -414,14 +414,14 @@ hist_get(const char *str, bool approx, bool allow_cur)
if (approx) if (approx)
hp = hist_get_oldest(); hp = hist_get_oldest();
else { else {
bi_errorf("%s: %s", str, T_not_in_history); bi_errorf("%s: %s", str, Tnot_in_history);
hp = NULL; hp = NULL;
} }
} else if ((ptrdiff_t)hp > (ptrdiff_t)histptr) { } else if ((ptrdiff_t)hp > (ptrdiff_t)histptr) {
if (approx) if (approx)
hp = hist_get_newest(allow_cur); hp = hist_get_newest(allow_cur);
else { else {
bi_errorf("%s: %s", str, T_not_in_history); bi_errorf("%s: %s", str, Tnot_in_history);
hp = NULL; hp = NULL;
} }
} else if (!allow_cur && hp == histptr) { } else if (!allow_cur && hp == histptr) {
@ -433,7 +433,7 @@ hist_get(const char *str, bool approx, bool allow_cur)
/* the -1 is to avoid the current fc command */ /* the -1 is to avoid the current fc command */
if ((n = findhist(histptr - history - 1, 0, str, anchored)) < 0) if ((n = findhist(histptr - history - 1, 0, str, anchored)) < 0)
bi_errorf("%s: %s", str, T_not_in_history); bi_errorf("%s: %s", str, Tnot_in_history);
else else
hp = &history[n]; hp = &history[n];
} }
@ -1077,7 +1077,7 @@ inittraps(void)
/* Populate sigtraps based on sys_signame and sys_siglist. */ /* Populate sigtraps based on sys_signame and sys_siglist. */
for (i = 0; i <= NSIG; i++) { for (i = 0; i <= NSIG; i++) {
sigtraps[i].signal = i; sigtraps[i].signal = i;
if (i == SIGERR_) { if (i == ksh_SIGERR) {
sigtraps[i].name = "ERR"; sigtraps[i].name = "ERR";
sigtraps[i].mess = "Error handler"; sigtraps[i].mess = "Error handler";
} else { } else {
@ -1116,7 +1116,7 @@ inittraps(void)
} }
} }
/* our name for signal 0 */ /* our name for signal 0 */
sigtraps[SIGEXIT_].name = "EXIT"; sigtraps[ksh_SIGEXIT].name = "EXIT";
(void)sigemptyset(&Sigact_ign.sa_mask); (void)sigemptyset(&Sigact_ign.sa_mask);
Sigact_ign.sa_flags = 0; /* interruptible */ Sigact_ign.sa_flags = 0; /* interruptible */
@ -1194,7 +1194,7 @@ void
trapsig(int i) trapsig(int i)
{ {
Trap *p = &sigtraps[i]; Trap *p = &sigtraps[i];
int errno_ = errno; int errno_sv = errno;
trap = p->set = 1; trap = p->set = 1;
if (p->flags & TF_DFL_INTR) if (p->flags & TF_DFL_INTR)
@ -1205,7 +1205,7 @@ trapsig(int i)
} }
if (p->shtrap) if (p->shtrap)
(*p->shtrap)(i); (*p->shtrap)(i);
errno = errno_; errno = errno_sv;
} }
/* /*
@ -1319,7 +1319,7 @@ runtrap(Trap *p, bool is_last)
if (trapstr[0] == '\0') if (trapstr[0] == '\0')
/* SIG_IGN */ /* SIG_IGN */
goto donetrap; goto donetrap;
if (i == SIGEXIT_ || i == SIGERR_) { if (i == ksh_SIGEXIT || i == ksh_SIGERR) {
/* avoid recursion on these */ /* avoid recursion on these */
old_changed = p->flags & TF_CHANGED; old_changed = p->flags & TF_CHANGED;
p->flags &= ~TF_CHANGED; p->flags &= ~TF_CHANGED;
@ -1332,7 +1332,7 @@ runtrap(Trap *p, bool is_last)
* no problem with afree(p->trap) in settrap() while still in use. * no problem with afree(p->trap) in settrap() while still in use.
*/ */
command(trapstr, current_lineno); command(trapstr, current_lineno);
if (i == SIGEXIT_ || i == SIGERR_) { if (i == ksh_SIGEXIT || i == ksh_SIGERR) {
if (p->flags & TF_CHANGED) if (p->flags & TF_CHANGED)
/* don't clear TF_CHANGED */ /* don't clear TF_CHANGED */
afree(trapstr, APERM); afree(trapstr, APERM);
@ -1454,7 +1454,7 @@ setsig(Trap *p, sig_t f, int flags)
{ {
struct sigaction sigact; struct sigaction sigact;
if (p->signal == SIGEXIT_ || p->signal == SIGERR_) if (p->signal == ksh_SIGEXIT || p->signal == ksh_SIGERR)
return (1); return (1);
/* /*

View File

@ -20,7 +20,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.18 2011/08/27 18:06:47 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.19 2011/09/07 15:24:16 tg Exp $");
/* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */ /* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */
#if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0) #if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0)
@ -77,7 +77,7 @@ void *
aresize2(void *ptr, size_t fac1, size_t fac2, Area *ap) aresize2(void *ptr, size_t fac1, size_t fac2, Area *ap)
{ {
if (notoktomul(fac1, fac2)) if (notoktomul(fac1, fac2))
internal_errorf(T_intovfl, fac1, '*', fac2); internal_errorf(Tintovfl, fac1, '*', fac2);
return (aresize(ptr, fac1 * fac2, ap)); return (aresize(ptr, fac1 * fac2, ap));
} }
@ -100,7 +100,7 @@ aresize(void *ptr, size_t numb, Area *ap)
|| ALLOC_ISUNALIGNED(lp) || ALLOC_ISUNALIGNED(lp)
#endif #endif
) )
internal_errorf(T_oomem, (unsigned long)numb); internal_errorf(Toomem, (unsigned long)numb);
/* this only works because Area is an ALLOC_ITEM */ /* this only works because Area is an ALLOC_ITEM */
lp->next = ap->next; lp->next = ap->next;
ap->next = lp; ap->next = lp;

44
lex.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.155 2011/08/27 18:06:47 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.156 2011/09/07 15:24:16 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -91,7 +91,7 @@ typedef struct {
static void readhere(struct ioword *); static void readhere(struct ioword *);
static void ungetsc(int); static void ungetsc(int);
static void ungetsc_(int); static void ungetsc_(int);
static int getsc__(void); static int getsc_uu(void);
static void getsc_line(Source *); static void getsc_line(Source *);
static int getsc_bn(void); static int getsc_bn(void);
static int s_get(void); static int s_get(void);
@ -111,13 +111,13 @@ static struct sretrace_info *retrace_info;
short subshell_nesting_level = 0; short subshell_nesting_level = 0;
/* optimised getsc_bn() */ /* optimised getsc_bn() */
#define _getsc() (*source->str != '\0' && *source->str != '\\' && \ #define o_getsc() (*source->str != '\0' && *source->str != '\\' && \
!backslash_skip ? *source->str++ : getsc_bn()) !backslash_skip ? *source->str++ : getsc_bn())
/* optimised getsc__() */ /* optimised getsc_uu() */
#define _getsc_() ((*source->str != '\0') ? *source->str++ : getsc__()) #define o_getsc_u() ((*source->str != '\0') ? *source->str++ : getsc_uu())
/* retrace helper */ /* retrace helper */
#define _getsc_r(carg) { \ #define o_getsc_r(carg) { \
int cev = (carg); \ int cev = (carg); \
struct sretrace_info *rp = retrace_info; \ struct sretrace_info *rp = retrace_info; \
\ \
@ -136,7 +136,7 @@ static int getsc(void);
static int static int
getsc(void) getsc(void)
{ {
_getsc_r(_getsc()); o_getsc_r(o_getsc());
} }
#else #else
static int getsc_r(int); static int getsc_r(int);
@ -144,10 +144,10 @@ static int getsc_r(int);
static int static int
getsc_r(int c) getsc_r(int c)
{ {
_getsc_r(c); o_getsc_r(c);
} }
#define getsc() getsc_r(_getsc()) #define getsc() getsc_r(o_getsc())
#endif #endif
#define STATE_BSIZE 8 #define STATE_BSIZE 8
@ -1260,7 +1260,7 @@ pushs(int type, Area *areap)
} }
static int static int
getsc__(void) getsc_uu(void)
{ {
Source *s = source; Source *s = source;
int c; int c;
@ -1328,7 +1328,7 @@ getsc__(void)
/* pop source stack */ /* pop source stack */
source = s->next; source = s->next;
source->flags |= s->flags & SF_ALIAS; source->flags |= s->flags & SF_ALIAS;
c = getsc__(); c = getsc_uu();
if (c) { if (c) {
s->flags |= SF_ALIASEND; s->flags |= SF_ALIASEND;
s->ugbuf[0] = c; s->ugbuf[1] = '\0'; s->ugbuf[0] = c; s->ugbuf[1] = '\0';
@ -1445,7 +1445,7 @@ getsc_line(Source *s)
int linelen; int linelen;
linelen = Xlength(s->xs, xp); linelen = Xlength(s->xs, xp);
XcheckN(s->xs, xp, Tn_fc_e_ + /* NUL */ 1); XcheckN(s->xs, xp, Zfc_e_dash + /* NUL */ 1);
/* reload after potential realloc */ /* reload after potential realloc */
cp = Xstring(s->xs, xp); cp = Xstring(s->xs, xp);
/* change initial '!' into space */ /* change initial '!' into space */
@ -1453,10 +1453,10 @@ getsc_line(Source *s)
/* NUL terminate the current string */ /* NUL terminate the current string */
*xp = '\0'; *xp = '\0';
/* move the actual string forward */ /* move the actual string forward */
memmove(cp + Tn_fc_e_, cp, linelen + /* NUL */ 1); memmove(cp + Zfc_e_dash, cp, linelen + /* NUL */ 1);
xp += Tn_fc_e_; xp += Zfc_e_dash;
/* prepend it with "fc -e -" */ /* prepend it with "fc -e -" */
memcpy(cp, T_fc_e_, Tn_fc_e_); memcpy(cp, Tfc_e_dash, Zfc_e_dash);
} }
#endif #endif
s->start = s->str = cp; s->start = s->str = cp;
@ -1753,19 +1753,19 @@ getsc_bn(void)
int c, c2; int c, c2;
if (ignore_backslash_newline) if (ignore_backslash_newline)
return (_getsc_()); return (o_getsc_u());
if (backslash_skip == 1) { if (backslash_skip == 1) {
backslash_skip = 2; backslash_skip = 2;
return (_getsc_()); return (o_getsc_u());
} }
backslash_skip = 0; backslash_skip = 0;
while (/* CONSTCOND */ 1) { while (/* CONSTCOND */ 1) {
c = _getsc_(); c = o_getsc_u();
if (c == '\\') { if (c == '\\') {
if ((c2 = _getsc_()) == '\n') if ((c2 = o_getsc_u()) == '\n')
/* ignore the \newline; get the next char... */ /* ignore the \newline; get the next char... */
continue; continue;
ungetsc_(c2); ungetsc_(c2);
@ -1780,16 +1780,16 @@ yyskiputf8bom(void)
{ {
int c; int c;
if ((unsigned char)(c = _getsc_()) != 0xEF) { if ((unsigned char)(c = o_getsc_u()) != 0xEF) {
ungetsc_(c); ungetsc_(c);
return; return;
} }
if ((unsigned char)(c = _getsc_()) != 0xBB) { if ((unsigned char)(c = o_getsc_u()) != 0xBB) {
ungetsc_(c); ungetsc_(c);
ungetsc_(0xEF); ungetsc_(0xEF);
return; return;
} }
if ((unsigned char)(c = _getsc_()) != 0xBF) { if ((unsigned char)(c = o_getsc_u()) != 0xBF) {
ungetsc_(c); ungetsc_(c);
ungetsc_(0xBB); ungetsc_(0xBB);
ungetsc_(0xEF); ungetsc_(0xEF);

26
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.198 2011/08/27 18:06:48 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.199 2011/09/07 15:24:17 tg Exp $");
extern char **environ; extern char **environ;
@ -59,12 +59,12 @@ static const char initsubs[] =
"${PS2=> } ${PS3=#? } ${PS4=+ } ${SECONDS=0} ${TMOUT=0}"; "${PS2=> } ${PS3=#? } ${PS4=+ } ${SECONDS=0} ${TMOUT=0}";
static const char *initcoms[] = { static const char *initcoms[] = {
T_typeset, "-r", initvsn, NULL, Ttypeset, "-r", initvsn, NULL,
T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL, Ttypeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
T_typeset, "-i10", "SECONDS", "TMOUT", NULL, Ttypeset, "-i10", "SECONDS", "TMOUT", NULL,
T_alias, Talias,
"integer=typeset -i", "integer=typeset -i",
T_local_typeset, Tlocal_typeset,
/* not "alias -t --": hash -r needs to work */ /* not "alias -t --": hash -r needs to work */
"hash=alias -t", "hash=alias -t",
"type=whence -v", "type=whence -v",
@ -79,19 +79,19 @@ static const char *initcoms[] = {
"history=fc -l", "history=fc -l",
"nameref=typeset -n", "nameref=typeset -n",
"nohup=nohup ", "nohup=nohup ",
T_r_fc_e_, Tr_fc_e_dash,
"source=PATH=$PATH:. command .", "source=PATH=$PATH:. command .",
"login=exec login", "login=exec login",
NULL, NULL,
/* this is what AT&T ksh seems to track, with the addition of emacs */ /* this is what AT&T ksh seems to track, with the addition of emacs */
T_alias, "-tU", Talias, "-tU",
"cat", "cc", "chmod", "cp", "date", "ed", "emacs", "grep", "ls", "cat", "cc", "chmod", "cp", "date", "ed", "emacs", "grep", "ls",
"make", "mv", "pr", "rm", "sed", "sh", "vi", "who", NULL, "make", "mv", "pr", "rm", "sed", "sh", "vi", "who", NULL,
NULL NULL
}; };
static const char *restr_com[] = { static const char *restr_com[] = {
T_typeset, "-r", "PATH", "ENV", "SHELL", NULL Ttypeset, "-r", "PATH", "ENV", "SHELL", NULL
}; };
static int initio_done; static int initio_done;
@ -105,7 +105,7 @@ rndsetup(void)
{ {
register uint32_t h; register uint32_t h;
struct { struct {
ALLOC_ITEM __alloc_i; ALLOC_ITEM alloc_INT;
void *dataptr, *stkptr, *mallocptr; void *dataptr, *stkptr, *mallocptr;
sigjmp_buf jbuf; sigjmp_buf jbuf;
struct timeval tv; struct timeval tv;
@ -799,14 +799,14 @@ unwind(int i)
{ {
/* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */ /* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */
if (i == LEXIT || (Flag(FERREXIT) && (i == LERROR || i == LINTR) && if (i == LEXIT || (Flag(FERREXIT) && (i == LERROR || i == LINTR) &&
sigtraps[SIGEXIT_].trap)) { sigtraps[ksh_SIGEXIT].trap)) {
++trap_nested; ++trap_nested;
runtrap(&sigtraps[SIGEXIT_], trap_nested == 1); runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1);
--trap_nested; --trap_nested;
i = LLEAVE; i = LLEAVE;
} else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) { } else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) {
++trap_nested; ++trap_nested;
runtrap(&sigtraps[SIGERR_], trap_nested == 1); runtrap(&sigtraps[ksh_SIGERR], trap_nested == 1);
--trap_nested; --trap_nested;
i = LLEAVE; i = LLEAVE;
} }

13
misc.c
View File

@ -29,7 +29,7 @@
#include <grp.h> #include <grp.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.171 2011/08/27 18:06:49 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.172 2011/09/07 15:24:18 tg Exp $");
/* type bits for unsigned char */ /* type bits for unsigned char */
unsigned char chtypes[UCHAR_MAX + 1]; unsigned char chtypes[UCHAR_MAX + 1];
@ -185,7 +185,7 @@ printoptions(bool verbose)
octs + 4, oi.opt_width + 4, true); octs + 4, oi.opt_width + 4, true);
} else { } else {
/* short version like AT&T ksh93 */ /* short version like AT&T ksh93 */
shf_puts(T_set, shl_stdout); shf_puts(Tset, shl_stdout);
while (i < (int)NELEM(options)) { while (i < (int)NELEM(options)) {
if (Flag(i) && options[i].name) if (Flag(i) && options[i].name)
shprintf("%s %s %s", null, "-o", shprintf("%s %s %s", null, "-o",
@ -1074,7 +1074,7 @@ print_value_quoted(const char *s)
void void
print_columns(struct shf *shf, int n, print_columns(struct shf *shf, int n,
char *(*func)(char *, size_t, int, const void *), char *(*func)(char *, size_t, int, const void *),
const void *arg, size_t max_oct, size_t max_col_, bool prefcol) const void *arg, size_t max_oct, size_t max_colz, bool prefcol)
{ {
int i, r, c, rows, cols, nspace, max_col; int i, r, c, rows, cols, nspace, max_col;
char *str; char *str;
@ -1086,13 +1086,14 @@ print_columns(struct shf *shf, int n,
return; return;
} }
if (max_col_ > 2147483647) { if (max_colz > 2147483647) {
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
internal_warningf("print_columns called with max_col=%zu > INT_MAX", max_col_); internal_warningf("print_columns called with max_col=%zu > INT_MAX",
max_colz);
#endif #endif
return; return;
} }
max_col = (int)max_col_; max_col = (int)max_colz;
++max_oct; ++max_oct;
str = alloc(max_oct, ATEMP); str = alloc(max_oct, ATEMP);

138
sh.h
View File

@ -151,9 +151,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.493 2011/08/27 18:06:50 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.494 2011/09/07 15:24:19 tg Exp $");
#endif #endif
#define MKSH_VERSION "R40 2011/08/27" #define MKSH_VERSION "R40 2011/09/07"
#ifndef MKSH_INCLUDES_ONLY #ifndef MKSH_INCLUDES_ONLY
@ -333,9 +333,9 @@ extern int wcwidth(__WCHAR_TYPE__);
/* some useful #defines */ /* some useful #defines */
#ifdef EXTERN #ifdef EXTERN
# define I__(i) = i # define E_INIT(i) = i
#else #else
# define I__(i) # define E_INIT(i)
# define EXTERN extern # define EXTERN extern
# define EXTERN_DEFINED # define EXTERN_DEFINED
#endif #endif
@ -383,11 +383,11 @@ typedef unsigned char mksh_bool;
#define LINE 4096 /* input line size */ #define LINE 4096 /* input line size */
EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */ EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */
EXTERN const char initvsn[] I__("KSH_VERSION=@(#)MIRBSD KSH " MKSH_VERSION); EXTERN const char initvsn[] E_INIT("KSH_VERSION=@(#)MIRBSD KSH " MKSH_VERSION);
#define KSH_VERSION (initvsn + /* "KSH_VERSION=@(#)" */ 16) #define KSH_VERSION (initvsn + /* "KSH_VERSION=@(#)" */ 16)
EXTERN const char digits_uc[] I__("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); EXTERN const char digits_uc[] E_INIT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
EXTERN const char digits_lc[] I__("0123456789abcdefghijklmnopqrstuvwxyz"); EXTERN const char digits_lc[] E_INIT("0123456789abcdefghijklmnopqrstuvwxyz");
/* /*
* Evil hack for const correctness due to API brokenness * Evil hack for const correctness due to API brokenness
@ -565,7 +565,7 @@ enum sh_flag {
* parsing & execution environment * parsing & execution environment
*/ */
extern struct env { extern struct env {
ALLOC_ITEM __alloc_i; /* internal, do not touch */ ALLOC_ITEM alloc_INT; /* internal, do not touch */
Area area; /* temporary allocation area */ Area area; /* temporary allocation area */
struct env *oenv; /* link to previous environment */ struct env *oenv; /* link to previous environment */
struct block *loc; /* local variables and functions */ struct block *loc; /* local variables and functions */
@ -618,22 +618,22 @@ EXTERN uint8_t trap_nested; /* running nested traps */
EXTERN uint8_t shell_flags[FNFLAGS]; EXTERN uint8_t shell_flags[FNFLAGS];
EXTERN const char *kshname; /* $0 */ EXTERN const char *kshname; /* $0 */
EXTERN struct { EXTERN struct {
uid_t kshuid_; /* real UID of shell */ uid_t kshuid_v; /* real UID of shell */
uid_t ksheuid_; /* effective UID of shell */ uid_t ksheuid_v; /* effective UID of shell */
gid_t kshgid_; /* real GID of shell */ gid_t kshgid_v; /* real GID of shell */
gid_t kshegid_; /* effective GID of shell */ gid_t kshegid_v; /* effective GID of shell */
pid_t kshpgrp_; /* process group of shell */ pid_t kshpgrp_v; /* process group of shell */
pid_t kshppid_; /* PID of parent of shell */ pid_t kshppid_v; /* PID of parent of shell */
pid_t kshpid_; /* $$, shell PID */ pid_t kshpid_v; /* $$, shell PID */
} rndsetupstate; } rndsetupstate;
#define kshpid rndsetupstate.kshpid_ #define kshpid rndsetupstate.kshpid_v
#define kshpgrp rndsetupstate.kshpgrp_ #define kshpgrp rndsetupstate.kshpgrp_v
#define kshuid rndsetupstate.kshuid_ #define kshuid rndsetupstate.kshuid_v
#define ksheuid rndsetupstate.ksheuid_ #define ksheuid rndsetupstate.ksheuid_v
#define kshgid rndsetupstate.kshgid_ #define kshgid rndsetupstate.kshgid_v
#define kshegid rndsetupstate.kshegid_ #define kshegid rndsetupstate.kshegid_v
#define kshppid rndsetupstate.kshppid_ #define kshppid rndsetupstate.kshppid_v
/* option processing */ /* option processing */
@ -652,33 +652,33 @@ struct shoption {
extern const struct shoption options[]; extern const struct shoption options[];
/* null value for variable; comparison pointer for unset */ /* null value for variable; comparison pointer for unset */
EXTERN char null[] I__(""); EXTERN char null[] E_INIT("");
/* helpers for string pooling */ /* helpers for string pooling */
EXTERN const char T_intovfl[] I__("integer overflow %zu %c %zu prevented"); EXTERN const char Tintovfl[] E_INIT("integer overflow %zu %c %zu prevented");
EXTERN const char T_oomem[] I__("can't allocate %lu data bytes"); EXTERN const char Toomem[] E_INIT("can't allocate %lu data bytes");
#if defined(__GNUC__) #if defined(__GNUC__)
/* trust this to have string pooling; -Wformat bitches otherwise */ /* trust this to have string pooling; -Wformat bitches otherwise */
#define T_synerr "syntax error" #define Tsynerr "syntax error"
#else #else
EXTERN const char T_synerr[] I__("syntax error"); EXTERN const char Tsynerr[] E_INIT("syntax error");
#endif #endif
EXTERN const char T_select[] I__("select"); EXTERN const char Tselect[] E_INIT("select");
EXTERN const char T_r_fc_e_[] I__("r=fc -e -"); EXTERN const char Tr_fc_e_dash[] E_INIT("r=fc -e -");
#define T_fc_e_ (T_r_fc_e_ + 2) /* "fc -e -" */ #define Tfc_e_dash (Tr_fc_e_dash + 2) /* "fc -e -" */
#define Tn_fc_e_ 7 /* strlen(T_fc_e_) */ #define Zfc_e_dash 7 /* strlen(Tfc_e_dash) */
EXTERN const char T_local_typeset[] I__("local=typeset"); EXTERN const char Tlocal_typeset[] E_INIT("local=typeset");
#define T__typeset (T_local_typeset + 5) /* "=typeset" */ #define T_typeset (Tlocal_typeset + 5) /* "=typeset" */
#define T_typeset (T_local_typeset + 6) /* "typeset" */ #define Ttypeset (Tlocal_typeset + 6) /* "typeset" */
EXTERN const char T_palias[] I__("+alias"); EXTERN const char Tpalias[] E_INIT("+alias");
#define T_alias (T_palias + 1) /* "alias" */ #define Talias (Tpalias + 1) /* "alias" */
EXTERN const char T_punalias[] I__("+unalias"); EXTERN const char Tpunalias[] E_INIT("+unalias");
#define T_unalias (T_punalias + 1) /* "unalias" */ #define Tunalias (Tpunalias + 1) /* "unalias" */
EXTERN const char T_sgset[] I__("*=set"); EXTERN const char Tsgset[] E_INIT("*=set");
#define T_set (T_sgset + 2) /* "set" */ #define Tset (Tsgset + 2) /* "set" */
EXTERN const char T_gbuiltin[] I__("=builtin"); EXTERN const char Tgbuiltin[] E_INIT("=builtin");
#define T_builtin (T_gbuiltin + 1) /* "builtin" */ #define Tbuiltin (Tgbuiltin + 1) /* "builtin" */
EXTERN const char T__function[] I__(" function"); EXTERN const char T_function[] E_INIT(" function");
#define T_function (T__function + 1) /* "function" */ #define Tfunction (T_function + 1) /* "function" */
enum temp_type { enum temp_type {
TT_HEREDOC_EXP, /* expanded heredoc */ TT_HEREDOC_EXP, /* expanded heredoc */
@ -739,8 +739,8 @@ typedef struct trap {
#define SS_USER BIT(4) /* user is doing the set (ie, trap command) */ #define SS_USER BIT(4) /* user is doing the set (ie, trap command) */
#define SS_SHTRAP BIT(5) /* trap for internal use (ALRM, CHLD, WINCH) */ #define SS_SHTRAP BIT(5) /* trap for internal use (ALRM, CHLD, WINCH) */
#define SIGEXIT_ 0 /* for trap EXIT */ #define ksh_SIGEXIT 0 /* for trap EXIT */
#define SIGERR_ NSIG /* for trap ERR */ #define ksh_SIGERR NSIG /* for trap ERR */
EXTERN volatile sig_atomic_t trap; /* traps pending? */ EXTERN volatile sig_atomic_t trap; /* traps pending? */
EXTERN volatile sig_atomic_t intrsig; /* pending trap interrupts command */ EXTERN volatile sig_atomic_t intrsig; /* pending trap interrupts command */
@ -749,7 +749,7 @@ extern Trap sigtraps[NSIG+1];
/* got_winch = 1 when we need to re-adjust the window size */ /* got_winch = 1 when we need to re-adjust the window size */
#ifdef SIGWINCH #ifdef SIGWINCH
EXTERN volatile sig_atomic_t got_winch I__(1); EXTERN volatile sig_atomic_t got_winch E_INIT(1);
#else #else
#define got_winch true #define got_winch true
#endif #endif
@ -764,7 +764,7 @@ enum tmout_enum {
TMOUT_LEAVING /* have timed out */ TMOUT_LEAVING /* have timed out */
}; };
EXTERN unsigned int ksh_tmout; EXTERN unsigned int ksh_tmout;
EXTERN enum tmout_enum ksh_tmout_state I__(TMOUT_EXECUTING); EXTERN enum tmout_enum ksh_tmout_state E_INIT(TMOUT_EXECUTING);
/* For "You have stopped jobs" message */ /* For "You have stopped jobs" message */
EXTERN int really_exit; EXTERN int really_exit;
@ -790,7 +790,7 @@ extern unsigned char chtypes[];
#define ksh_isalphx(c) ctype((c), C_ALPHA) #define ksh_isalphx(c) ctype((c), C_ALPHA)
#define ksh_isalnux(c) ctype((c), C_ALPHA | C_DIGIT) #define ksh_isalnux(c) ctype((c), C_ALPHA | C_DIGIT)
EXTERN int ifs0 I__(' '); /* for "$*" */ EXTERN int ifs0 E_INIT(' '); /* for "$*" */
/* Argument parsing for built-in commands and getopts command */ /* Argument parsing for built-in commands and getopts command */
@ -859,8 +859,8 @@ EXTERN char *current_wd;
*/ */
#define MIN_COLS (2 + MIN_EDIT_SPACE + 3) #define MIN_COLS (2 + MIN_EDIT_SPACE + 3)
#define MIN_LINS 3 #define MIN_LINS 3
EXTERN mksh_ari_t x_cols I__(80); /* tty columns */ EXTERN mksh_ari_t x_cols E_INIT(80); /* tty columns */
EXTERN mksh_ari_t x_lins I__(-1); /* tty lines */ EXTERN mksh_ari_t x_lins E_INIT(-1); /* tty lines */
/* These to avoid bracket matching problems */ /* These to avoid bracket matching problems */
#define OPAREN '(' #define OPAREN '('
@ -904,7 +904,7 @@ EXTERN mksh_ari_t x_lins I__(-1); /* tty lines */
((shf)->wnleft--, *(shf)->wp++ = (c))) ((shf)->wnleft--, *(shf)->wp++ = (c)))
#define shf_eof(shf) ((shf)->flags & SHF_EOF) #define shf_eof(shf) ((shf)->flags & SHF_EOF)
#define shf_error(shf) ((shf)->flags & SHF_ERROR) #define shf_error(shf) ((shf)->flags & SHF_ERROR)
#define shf_errno(shf) ((shf)->errno_) #define shf_errno(shf) ((shf)->errnosv)
#define shf_clearerr(shf) ((shf)->flags &= ~(SHF_EOF | SHF_ERROR)) #define shf_clearerr(shf) ((shf)->flags &= ~(SHF_EOF | SHF_ERROR))
/* Flags passed to shf_*open() */ /* Flags passed to shf_*open() */
@ -941,7 +941,7 @@ struct shf {
ssize_t wnleft; /* write: how much space left in buffer */ ssize_t wnleft; /* write: how much space left in buffer */
int flags; /* see SHF_* */ int flags; /* see SHF_* */
int fd; /* file descriptor */ int fd; /* file descriptor */
int errno_; /* saved value of errno after error */ int errnosv; /* saved value of errno after error */
}; };
extern struct shf shf_iob[]; extern struct shf shf_iob[];
@ -971,7 +971,7 @@ struct tbl {
} u; } u;
union { union {
int field; /* field with for -L/-R/-Z */ int field; /* field with for -L/-R/-Z */
int errno_; /* CEXEC/CTALIAS */ int errnov; /* CEXEC/CTALIAS */
} u2; } u2;
union { union {
uint32_t hval; /* hash(name) */ uint32_t hval; /* hash(name) */
@ -1037,7 +1037,7 @@ EXTERN enum {
SRF_NOP, SRF_NOP,
SRF_ENABLE, SRF_ENABLE,
SRF_DISABLE SRF_DISABLE
} set_refflag I__(SRF_NOP); } set_refflag E_INIT(SRF_NOP);
/* command types */ /* command types */
#define CNONE 0 /* undefined */ #define CNONE 0 /* undefined */
@ -1061,13 +1061,13 @@ EXTERN enum {
#define AF_ARGV_ALLOC 0x1 /* argv[] array allocated */ #define AF_ARGV_ALLOC 0x1 /* argv[] array allocated */
#define AF_ARGS_ALLOCED 0x2 /* argument strings allocated */ #define AF_ARGS_ALLOCED 0x2 /* argument strings allocated */
#define AI_ARGV(a, i) ((i) == 0 ? (a).argv[0] : (a).argv[(i) - (a).skip]) #define AI_ARGV(a, i) ((i) == 0 ? (a).argv[0] : (a).argv[(i) - (a).skip])
#define AI_ARGC(a) ((a).argc_ - (a).skip) #define AI_ARGC(a) ((a).ai_argc - (a).skip)
/* Argument info. Used for $#, $* for shell, functions, includes, etc. */ /* Argument info. Used for $#, $* for shell, functions, includes, etc. */
struct arg_info { struct arg_info {
const char **argv; const char **argv;
int flags; /* AF_* */ int flags; /* AF_* */
int argc_; int ai_argc;
int skip; /* first arg is argv[0], second is argv[1 + skip] */ int skip; /* first arg is argv[0], second is argv[1 + skip] */
}; };
@ -1249,9 +1249,9 @@ struct ioword {
#define DOTILDE BIT(3) /* normal ~ expansion (first char) */ #define DOTILDE BIT(3) /* normal ~ expansion (first char) */
#define DONTRUNCOMMAND BIT(4) /* do not run $(command) things */ #define DONTRUNCOMMAND BIT(4) /* do not run $(command) things */
#define DOASNTILDE BIT(5) /* assignment ~ expansion (after =, :) */ #define DOASNTILDE BIT(5) /* assignment ~ expansion (after =, :) */
#define DOBRACE_ BIT(6) /* used by expand(): do brace expansion */ #define DOBRACE BIT(6) /* used by expand(): do brace expansion */
#define DOMAGIC_ BIT(7) /* used by expand(): string contains MAGIC */ #define DOMAGIC BIT(7) /* used by expand(): string contains MAGIC */
#define DOTEMP_ BIT(8) /* ditto : in word part of ${..[%#=?]..} */ #define DOTEMP BIT(8) /* dito: in word part of ${..[%#=?]..} */
#define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */ #define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */
#define DOMARKDIRS BIT(10) /* force markdirs behaviour */ #define DOMARKDIRS BIT(10) /* force markdirs behaviour */
@ -1330,10 +1330,10 @@ typedef struct XPtrV {
} XPtrV; } XPtrV;
#define XPinit(x, n) do { \ #define XPinit(x, n) do { \
void **vp__; \ void **XPinit_vp; \
vp__ = alloc2((n), sizeof(void *), ATEMP); \ XPinit_vp = alloc2((n), sizeof(void *), ATEMP); \
(x).cur = (x).beg = vp__; \ (x).cur = (x).beg = XPinit_vp; \
(x).end = vp__ + (n); \ (x).end = XPinit_vp + (n); \
} while (/* CONSTCOND */ 0) } while (/* CONSTCOND */ 0)
#define XPput(x, p) do { \ #define XPput(x, p) do { \
@ -1471,7 +1471,7 @@ EXTERN struct timeval j_usrtime, j_systime;
#define notoktoadd(val, cnst) ((val) > (SIZE_MAX - (cnst))) #define notoktoadd(val, cnst) ((val) > (SIZE_MAX - (cnst)))
#define checkoktoadd(val, cnst) do { \ #define checkoktoadd(val, cnst) do { \
if (notoktoadd((val), (cnst))) \ if (notoktoadd((val), (cnst))) \
internal_errorf(T_intovfl, (size_t)(val), \ internal_errorf(Tintovfl, (size_t)(val), \
'+', (size_t)(cnst)); \ '+', (size_t)(cnst)); \
} while (/* CONSTCOND */ 0) } while (/* CONSTCOND */ 0)
@ -1561,8 +1561,7 @@ int define(const char *, struct op *);
const char *builtin(const char *, int (*)(const char **)); const char *builtin(const char *, int (*)(const char **));
struct tbl *findcom(const char *, int); struct tbl *findcom(const char *, int);
void flushcom(bool); void flushcom(bool);
const char *search(const char *, const char *, int, int *); const char *search_path(const char *, const char *, int, int *);
int search_access(const char *, int, int *);
int pr_menu(const char * const *); int pr_menu(const char * const *);
int pr_list(char * const *); int pr_list(char * const *);
/* expr.c */ /* expr.c */
@ -1578,6 +1577,7 @@ size_t utf_ptradj(const char *);
#ifndef MKSH_mirbsd_wcwidth #ifndef MKSH_mirbsd_wcwidth
int utf_wcwidth(unsigned int); int utf_wcwidth(unsigned int);
#endif #endif
int ksh_access(const char *, int);
/* funcs.c */ /* funcs.c */
int c_hash(const char **); int c_hash(const char **);
int c_pwd(const char **); int c_pwd(const char **);
@ -1910,7 +1910,7 @@ Test_op test_isop(Test_meta, const char *);
int test_eval(Test_env *, Test_op, const char *, const char *, bool); int test_eval(Test_env *, Test_op, const char *, const char *, bool);
int test_parse(Test_env *); int test_parse(Test_env *);
EXTERN int tty_fd I__(-1); /* dup'd tty file descriptor */ EXTERN int tty_fd E_INIT(-1); /* dup'd tty file descriptor */
EXTERN bool tty_devtty; /* true if tty_fd is from /dev/tty */ EXTERN bool tty_devtty; /* true if tty_fd is from /dev/tty */
EXTERN struct termios tty_state; /* saved tty state */ EXTERN struct termios tty_state; /* saved tty state */
@ -1922,6 +1922,6 @@ extern void tty_close(void);
# undef EXTERN_DEFINED # undef EXTERN_DEFINED
# undef EXTERN # undef EXTERN
#endif #endif
#undef I__ #undef E_INIT
#endif /* !MKSH_INCLUDES_ONLY */ #endif /* !MKSH_INCLUDES_ONLY */

24
shf.c
View File

@ -24,7 +24,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.43 2011/08/27 18:06:51 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/shf.c,v 1.44 2011/09/07 15:24:20 tg Exp $");
/* flags to shf_emptybuf() */ /* flags to shf_emptybuf() */
#define EB_READSW 0x01 /* about to switch to reading */ #define EB_READSW 0x01 /* about to switch to reading */
@ -145,7 +145,7 @@ shf_fdopen(int fd, int sflags, struct shf *shf)
shf->wnleft = 0; /* force call to shf_emptybuf() */ shf->wnleft = 0; /* force call to shf_emptybuf() */
shf->wbsize = sflags & SHF_UNBUF ? 0 : bsize; shf->wbsize = sflags & SHF_UNBUF ? 0 : bsize;
shf->flags = sflags; shf->flags = sflags;
shf->errno_ = 0; shf->errnosv = 0;
shf->bsize = bsize; shf->bsize = bsize;
if (sflags & SHF_CLEXEC) if (sflags & SHF_CLEXEC)
fcntl(fd, F_SETFD, FD_CLOEXEC); fcntl(fd, F_SETFD, FD_CLOEXEC);
@ -172,7 +172,7 @@ shf_reopen(int fd, int sflags, struct shf *shf)
shf->wnleft = 0; /* force call to shf_emptybuf() */ shf->wnleft = 0; /* force call to shf_emptybuf() */
shf->wbsize = sflags & SHF_UNBUF ? 0 : bsize; shf->wbsize = sflags & SHF_UNBUF ? 0 : bsize;
shf->flags = (shf->flags & (SHF_ALLOCS | SHF_ALLOCB)) | sflags; shf->flags = (shf->flags & (SHF_ALLOCS | SHF_ALLOCB)) | sflags;
shf->errno_ = 0; shf->errnosv = 0;
if (sflags & SHF_CLEXEC) if (sflags & SHF_CLEXEC)
fcntl(fd, F_SETFD, FD_CLOEXEC); fcntl(fd, F_SETFD, FD_CLOEXEC);
return (shf); return (shf);
@ -212,7 +212,7 @@ shf_sopen(char *buf, ssize_t bsize, int sflags, struct shf *shf)
shf->wnleft = bsize - 1; /* space for a '\0' */ shf->wnleft = bsize - 1; /* space for a '\0' */
shf->wbsize = bsize; shf->wbsize = bsize;
shf->flags = sflags | SHF_STRING; shf->flags = sflags | SHF_STRING;
shf->errno_ = 0; shf->errnosv = 0;
shf->bsize = bsize; shf->bsize = bsize;
return (shf); return (shf);
@ -290,7 +290,7 @@ shf_flush(struct shf *shf)
internal_errorf("%s: %s", "shf_flush", "no fd"); internal_errorf("%s: %s", "shf_flush", "no fd");
if (shf->flags & SHF_ERROR) { if (shf->flags & SHF_ERROR) {
errno = shf->errno_; errno = shf->errnosv;
return (EOF); return (EOF);
} }
@ -321,7 +321,7 @@ shf_emptybuf(struct shf *shf, int flags)
internal_errorf("%s: %s", "shf_emptybuf", "no fd"); internal_errorf("%s: %s", "shf_emptybuf", "no fd");
if (shf->flags & SHF_ERROR) { if (shf->flags & SHF_ERROR) {
errno = shf->errno_; errno = shf->errnosv;
return (EOF); return (EOF);
} }
@ -363,7 +363,7 @@ shf_emptybuf(struct shf *shf, int flags)
!(shf->flags & SHF_INTERRUPT)) !(shf->flags & SHF_INTERRUPT))
continue; continue;
shf->flags |= SHF_ERROR; shf->flags |= SHF_ERROR;
shf->errno_ = errno; shf->errnosv = errno;
shf->wnleft = 0; shf->wnleft = 0;
if (buf != shf->buf) { if (buf != shf->buf) {
/* /*
@ -408,7 +408,7 @@ shf_fillbuf(struct shf *shf)
if (shf->flags & (SHF_EOF | SHF_ERROR)) { if (shf->flags & (SHF_EOF | SHF_ERROR)) {
if (shf->flags & SHF_ERROR) if (shf->flags & SHF_ERROR)
errno = shf->errno_; errno = shf->errnosv;
return (EOF); return (EOF);
} }
@ -426,7 +426,7 @@ shf_fillbuf(struct shf *shf)
} }
if (n < 0) { if (n < 0) {
shf->flags |= SHF_ERROR; shf->flags |= SHF_ERROR;
shf->errno_ = errno; shf->errnosv = errno;
shf->rnleft = 0; shf->rnleft = 0;
shf->rp = shf->buf; shf->rp = shf->buf;
return (EOF); return (EOF);
@ -585,7 +585,7 @@ shf_putchar(int c, struct shf *shf)
if (shf->fd < 0) if (shf->fd < 0)
internal_errorf("%s: %s", "shf_putchar", "no fd"); internal_errorf("%s: %s", "shf_putchar", "no fd");
if (shf->flags & SHF_ERROR) { if (shf->flags & SHF_ERROR) {
errno = shf->errno_; errno = shf->errnosv;
return (EOF); return (EOF);
} }
while ((n = write(shf->fd, &cc, 1)) != 1) while ((n = write(shf->fd, &cc, 1)) != 1)
@ -594,7 +594,7 @@ shf_putchar(int c, struct shf *shf)
!(shf->flags & SHF_INTERRUPT)) !(shf->flags & SHF_INTERRUPT))
continue; continue;
shf->flags |= SHF_ERROR; shf->flags |= SHF_ERROR;
shf->errno_ = errno; shf->errnosv = errno;
return (EOF); return (EOF);
} }
} else { } else {
@ -668,7 +668,7 @@ shf_write(const char *buf, ssize_t nbytes, struct shf *shf)
!(shf->flags & SHF_INTERRUPT)) !(shf->flags & SHF_INTERRUPT))
continue; continue;
shf->flags |= SHF_ERROR; shf->flags |= SHF_ERROR;
shf->errno_ = errno; shf->errnosv = errno;
shf->wnleft = 0; shf->wnleft = 0;
/* /*
* Note: fwrite(3) returns 0 * Note: fwrite(3) returns 0

16
syn.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.68 2011/08/27 18:06:51 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.69 2011/09/07 15:24:21 tg Exp $");
extern short subshell_nesting_level; extern short subshell_nesting_level;
extern void yyskiputf8bom(void); extern void yyskiputf8bom(void);
@ -420,7 +420,7 @@ get_command(int cf)
t = newtp((c == FOR) ? TFOR : TSELECT); t = newtp((c == FOR) ? TFOR : TSELECT);
musthave(LWORD, ARRAYVAR); musthave(LWORD, ARRAYVAR);
if (!is_wdvarname(yylval.cp, true)) if (!is_wdvarname(yylval.cp, true))
yyerror("%s: %s\n", c == FOR ? "for" : T_select, yyerror("%s: %s\n", c == FOR ? "for" : Tselect,
"bad identifier"); "bad identifier");
strdupx(t->str, ident, ATEMP); strdupx(t->str, ident, ATEMP);
nesting_push(&old_nesting, c); nesting_push(&old_nesting, c);
@ -764,13 +764,13 @@ const struct tokeninfo {
{ "case", CASE, true }, { "case", CASE, true },
{ "esac", ESAC, true }, { "esac", ESAC, true },
{ "for", FOR, true }, { "for", FOR, true },
{ T_select, SELECT, true }, { Tselect, SELECT, true },
{ "while", WHILE, true }, { "while", WHILE, true },
{ "until", UNTIL, true }, { "until", UNTIL, true },
{ "do", DO, true }, { "do", DO, true },
{ "done", DONE, true }, { "done", DONE, true },
{ "in", IN, true }, { "in", IN, true },
{ T_function, FUNCTION, true }, { Tfunction, FUNCTION, true },
{ "time", TIME, true }, { "time", TIME, true },
{ "{", '{', true }, { "{", '{', true },
{ "}", '}', true }, { "}", '}', true },
@ -831,7 +831,7 @@ syntaxerr(const char *what)
goto Again; goto Again;
} }
/* don't quote the EOF */ /* don't quote the EOF */
yyerror("%s: %s %s\n", T_synerr, "unexpected", "EOF"); yyerror("%s: %s %s\n", Tsynerr, "unexpected", "EOF");
/* NOTREACHED */ /* NOTREACHED */
case LWORD: case LWORD:
@ -858,7 +858,7 @@ syntaxerr(const char *what)
s = redir; s = redir;
} }
} }
yyerror("%s: '%s' %s\n", T_synerr, s, what); yyerror("%s: '%s' %s\n", Tsynerr, s, what);
} }
static void static void
@ -920,10 +920,10 @@ assign_command(char *s)
{ {
if (!*s) if (!*s)
return (0); return (0);
return ((strcmp(s, T_alias) == 0) || return ((strcmp(s, Talias) == 0) ||
(strcmp(s, "export") == 0) || (strcmp(s, "export") == 0) ||
(strcmp(s, "readonly") == 0) || (strcmp(s, "readonly") == 0) ||
(strcmp(s, T_typeset) == 0)); (strcmp(s, Ttypeset) == 0));
} }
/* Check if we are in the middle of reading an alias */ /* Check if we are in the middle of reading an alias */

6
tree.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.50 2011/08/27 18:06:51 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/tree.c,v 1.51 2011/09/07 15:24:21 tg Exp $");
#define INDENT 8 #define INDENT 8
@ -100,7 +100,7 @@ ptree(struct op *t, int indent, struct shf *shf)
case TSELECT: case TSELECT:
case TFOR: case TFOR:
fptreef(shf, indent, "%s %s ", fptreef(shf, indent, "%s %s ",
(t->type == TFOR) ? "for" : T_select, t->str); (t->type == TFOR) ? "for" : Tselect, t->str);
if (t->vars != NULL) { if (t->vars != NULL) {
shf_puts("in ", shf); shf_puts("in ", shf);
w = (const char **)t->vars; w = (const char **)t->vars;
@ -701,7 +701,7 @@ void
fpFUNCTf(struct shf *shf, int i, bool isksh, const char *k, struct op *v) fpFUNCTf(struct shf *shf, int i, bool isksh, const char *k, struct op *v)
{ {
if (isksh) if (isksh)
fptreef(shf, i, "%s %s %T", T_function, k, v); fptreef(shf, i, "%s %s %T", Tfunction, k, v);
else else
fptreef(shf, i, "%s() %T", k, v); fptreef(shf, i, "%s() %T", k, v);
} }

3
var.c
View File

@ -26,7 +26,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.131 2011/08/27 18:06:52 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.132 2011/09/07 15:24:22 tg Exp $");
/*- /*-
* Variables * Variables
@ -1170,6 +1170,7 @@ setspec(struct tbl *vp)
struct stat statb; struct stat statb;
s = str_val(vp); s = str_val(vp);
/* LINTED use of access */
if (s[0] == '/' && access(s, W_OK|X_OK) == 0 && if (s[0] == '/' && access(s, W_OK|X_OK) == 0 &&
stat(s, &statb) == 0 && S_ISDIR(statb.st_mode)) stat(s, &statb) == 0 && S_ISDIR(statb.st_mode))
strdupx(tmpdir, s, APERM); strdupx(tmpdir, s, APERM);