• 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: 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 R40 2011/08/27
@(#)MIRBSD KSH R40 2011/09/07
description:
Check version of shell.
stdin:

73
edit.c
View File

@ -25,7 +25,7 @@
#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
@ -695,7 +695,6 @@ glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
const char *sp = lpath, *p;
char *xp, **words;
size_t pathlen, patlen, oldsize, newsize, i, j;
int staterr;
XString xs;
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... */
words = (char **)XPptrv(*wp);
for (i = j = oldsize; i < newsize; i++) {
staterr = 0;
if ((search_access(words[i], X_OK, &staterr) >= 0) ||
(staterr == EISDIR)) {
if (ksh_access(words[i], X_OK) == 0) {
words[j] = words[i];
if (!(flags & XCF_FULLPATH))
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)
break;
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);
}
}
@ -3291,58 +3288,58 @@ static void vi_error(void);
static void vi_macro_reset(void);
static int x_vi_putbuf(const char *, size_t);
#define C_ 0x1 /* a valid command that isn't a M_, E_, U_ */
#define M_ 0x2 /* movement command (h, l, etc.) */
#define E_ 0x4 /* extended command (c, d, y) */
#define X_ 0x8 /* long command (@, f, F, t, T, etc.) */
#define U_ 0x10 /* an UN-undoable command (that isn't a M_) */
#define B_ 0x20 /* bad command (^@) */
#define Z_ 0x40 /* repeat count defaults to 0 (not 1) */
#define S_ 0x80 /* search (/, ?) */
#define vC 0x01 /* a valid command that isn't a vM, vE, vU */
#define vM 0x02 /* movement command (h, l, etc.) */
#define vE 0x04 /* extended command (c, d, y) */
#define vX 0x08 /* long command (@, f, F, t, T, etc.) */
#define vU 0x10 /* an UN-undoable command (that isn't a vM) */
#define vB 0x20 /* bad command (^@) */
#define vZ 0x40 /* repeat count defaults to 0 (not 1) */
#define vS 0x80 /* search (/, ?) */
#define is_bad(c) (classify[(c)&0x7f]&B_)
#define is_cmd(c) (classify[(c)&0x7f]&(M_|E_|C_|U_))
#define is_move(c) (classify[(c)&0x7f]&M_)
#define is_extend(c) (classify[(c)&0x7f]&E_)
#define is_long(c) (classify[(c)&0x7f]&X_)
#define is_undoable(c) (!(classify[(c)&0x7f]&U_))
#define is_srch(c) (classify[(c)&0x7f]&S_)
#define is_zerocount(c) (classify[(c)&0x7f]&Z_)
#define is_bad(c) (classify[(c)&0x7f]&vB)
#define is_cmd(c) (classify[(c)&0x7f]&(vM|vE|vC|vU))
#define is_move(c) (classify[(c)&0x7f]&vM)
#define is_extend(c) (classify[(c)&0x7f]&vE)
#define is_long(c) (classify[(c)&0x7f]&vX)
#define is_undoable(c) (!(classify[(c)&0x7f]&vU))
#define is_srch(c) (classify[(c)&0x7f]&vS)
#define is_zerocount(c) (classify[(c)&0x7f]&vZ)
static const unsigned char classify[128] = {
/* 0 1 2 3 4 5 6 7 */
/* 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 */
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 */
C_, 0, C_|U_, 0, 0, 0, C_, 0,
vC, 0, vC|vU, 0, 0, 0, vC, 0,
/* 3 ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
C_, 0, 0, C_|Z_, 0, 0, 0, 0,
vC, 0, 0, vC|vZ, 0, 0, 0, 0,
/* 4 <space> ! " # $ % & ' */
M_, 0, 0, C_, M_, M_, 0, 0,
vM, 0, 0, vC, vM, vM, 0, 0,
/* 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 */
M_, 0, 0, 0, 0, 0, 0, 0,
vM, 0, 0, 0, 0, 0, 0, 0,
/* 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 */
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 */
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 */
C_, 0, C_, C_, M_|X_, C_, 0, M_,
vC, 0, vC, vC, vM|vX, vC, 0, vM,
/* 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 */
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 */
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 */
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 { | } ~ ^? */
C_, E_|U_, 0, 0, M_|Z_, 0, C_, 0
vC, vE|vU, 0, 0, vM|vZ, 0, vC, 0
};
#define MAXVICMD 3

36
eval.c
View File

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

127
exec.c
View File

@ -22,7 +22,7 @@
#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
#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 const char *dbteste_getopnd(Test_env *, Test_op, bool);
static void dbteste_error(Test_env *, int, const char *);
static int search_access(const char *, int);
/*
* execute command tree
@ -102,7 +103,7 @@ execute(struct op * volatile t,
/* set variable to its expanded value */
z = strlen(cp) + 1;
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);
memcpy(dp, t->vars[0], n);
t->vars[0] = dp;
@ -481,7 +482,7 @@ execute(struct op * volatile t,
unwind(LEXIT);
if (rv != 0 && !(flags & XERROK) &&
(xerrok == NULL || !*xerrok)) {
trapsig(SIGERR_);
trapsig(ksh_SIGERR);
if (Flag(FERREXIT))
unwind(LERROR);
}
@ -546,7 +547,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
break;
}
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;
} else if (tp->val.f == c_exec) {
if (ap[1] == NULL)
@ -678,18 +679,10 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
struct tbl *ftp;
if (!tp->u.fpath) {
if (tp->u2.errno_) {
warningf(true, "%s: %s %s: %s", cp,
"can't find",
"function definition file",
strerror(tp->u2.errno_));
rv = 126;
} else {
warningf(true, "%s: %s %s", cp,
"can't find",
"function definition file");
rv = 127;
}
rv = (tp->u2.errnov == ENOENT) ? 127 : 126;
warningf(true, "%s: %s %s: %s", cp,
"can't find", "function definition file",
strerror(tp->u2.errnov));
break;
}
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 */
case CTALIAS:
if (!(tp->flag&ISSET)) {
/*
* 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");
if (tp->u2.errnov == ENOENT) {
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;
}
@ -851,7 +837,7 @@ scriptexec(struct op *tp, const char **ap)
sh = str_val(global("EXECSHELL"));
if (sh && *sh)
sh = search(sh, path, X_OK, NULL);
sh = search_path(sh, path, X_OK, NULL);
if (!sh || !*sh)
sh = MKSH_DEFAULT_EXECSHELL;
@ -1094,10 +1080,10 @@ findcom(const char *name, int flags)
if (tp && !(tp->flag & ISSET)) {
if ((fpath = str_val(global("FPATH"))) == null) {
tp->u.fpath = NULL;
tp->u2.errno_ = 0;
tp->u2.errnov = ENOENT;
} else
tp->u.fpath = search(name, fpath, R_OK,
&tp->u2.errno_);
tp->u.fpath = search_path(name, fpath, R_OK,
&tp->u2.errnov);
}
}
if (!tp && (flags & FC_REGBI) && tbi && (tbi->flag & REG_BI))
@ -1106,7 +1092,8 @@ findcom(const char *name, int flags)
tp = tbi;
if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {
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) {
tp->flag &= ~ALLOC;
afree(tp->val.s, APERM);
@ -1129,8 +1116,9 @@ findcom(const char *name, int flags)
/* make ~ISSET */
tp->flag = DEFINED;
}
npath.ro = search(name, flags & FC_DEFPATH ? def_path : path,
X_OK, &tp->u2.errno_);
npath.ro = search_path(name,
(flags & FC_DEFPATH) ? def_path : path,
X_OK, &tp->u2.errnov);
if (npath.ro) {
strdupx(tp->val.s, npath.ro, APERM);
if (npath.ro != name)
@ -1138,8 +1126,8 @@ findcom(const char *name, int flags)
tp->flag |= ISSET|ALLOC;
} else if ((flags & FC_FUNC) &&
(fpath = str_val(global("FPATH"))) != null &&
(npath.ro = search(name, fpath, R_OK,
&tp->u2.errno_)) != NULL) {
(npath.ro = search_path(name, fpath, R_OK,
&tp->u2.errnov)) != NULL) {
/*
* An undocumented feature of AT&T ksh is that
* 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. */
int
search_access(const char *lpath, int mode,
/* set if candidate found, but not suitable */
int *errnop)
/* check if path is something we want to find */
static int
search_access(const char *fn, int mode)
{
int ret, err = 0;
struct stat statb;
struct stat sb;
if (stat(lpath, &statb) < 0)
return (-1);
ret = access(lpath, mode);
if (ret < 0)
/* File exists, but we can't access it */
err = errno;
else if (mode == X_OK && (!S_ISREG(statb.st_mode) ||
!(statb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))) {
/* This 'cause access() says root can execute everything */
ret = -1;
err = S_ISDIR(statb.st_mode) ? EISDIR : EACCES;
}
if (err && errnop && !*errnop)
*errnop = err;
return (ret);
if (stat(fn, &sb) < 0)
/* file does not exist */
return (ENOENT);
/* LINTED use of access */
if (access(fn, mode) < 0)
/* file exists, but we can't access it */
return (errno);
if (mode == X_OK && (!S_ISREG(sb.st_mode) ||
!(sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))))
/* access(2) may say root can execute everything */
return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES);
return (0);
}
/*
* search for command with PATH
*/
const char *
search(const char *name, const char *lpath,
search_path(const char *name, const char *lpath,
/* R_OK or X_OK */
int mode,
/* set if candidate found, but not suitable */
@ -1216,13 +1198,16 @@ search(const char *name, const char *lpath,
char *xp;
XString xs;
size_t namelen;
int ec = 0, ev;
if (errnop)
*errnop = 0;
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 (NULL);
}
goto search_path_err;
}
namelen = strlen(name) + 1;
@ -1242,12 +1227,20 @@ search(const char *name, const char *lpath,
sp = p;
XcheckN(xs, xp, namelen);
memcpy(xp, name, namelen);
if (search_access(Xstring(xs, xp), mode, errnop) == 0)
return (Xclose(xs, xp + namelen));
if ((ev = search_access(Xstring(xs, xp), mode)) == 0) {
name = Xclose(xs, xp + namelen);
goto search_path_ok;
}
/* accumulate non-ENOENT errors only */
if (ev != ENOENT && ec == 0)
ec = ev;
if (*sp++ == '\0')
sp = NULL;
}
Xfree(xs, xp);
search_path_err:
if (errnop)
*errnop = ec ? ec : ENOENT;
return (NULL);
}

21
expr.c
View File

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

View File

@ -26,7 +26,7 @@
#include <sys/file.h>
#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.
@ -66,8 +66,8 @@ static int histfd;
static size_t hsize;
#endif
static const char T_not_in_history[] = "not in history";
#define T_history (T_not_in_history + 7)
static const char Tnot_in_history[] = "not in history";
#define Thistory (Tnot_in_history + 7)
int
c_fc(const char **wp)
@ -83,7 +83,7 @@ c_fc(const char **wp)
char **hfirst, **hlast, **hp;
if (!Flag(FTALKING_I)) {
bi_errorf("history %ss not available", T_function);
bi_errorf("history %ss not available", Tfunction);
return (1);
}
@ -290,7 +290,7 @@ c_fc(const char **wp)
if (stat(tf->name, &statb) < 0)
n = 128;
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);
goto errout;
} else
@ -414,14 +414,14 @@ hist_get(const char *str, bool approx, bool allow_cur)
if (approx)
hp = hist_get_oldest();
else {
bi_errorf("%s: %s", str, T_not_in_history);
bi_errorf("%s: %s", str, Tnot_in_history);
hp = NULL;
}
} else if ((ptrdiff_t)hp > (ptrdiff_t)histptr) {
if (approx)
hp = hist_get_newest(allow_cur);
else {
bi_errorf("%s: %s", str, T_not_in_history);
bi_errorf("%s: %s", str, Tnot_in_history);
hp = NULL;
}
} 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 */
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
hp = &history[n];
}
@ -1077,7 +1077,7 @@ inittraps(void)
/* Populate sigtraps based on sys_signame and sys_siglist. */
for (i = 0; i <= NSIG; i++) {
sigtraps[i].signal = i;
if (i == SIGERR_) {
if (i == ksh_SIGERR) {
sigtraps[i].name = "ERR";
sigtraps[i].mess = "Error handler";
} else {
@ -1116,7 +1116,7 @@ inittraps(void)
}
}
/* our name for signal 0 */
sigtraps[SIGEXIT_].name = "EXIT";
sigtraps[ksh_SIGEXIT].name = "EXIT";
(void)sigemptyset(&Sigact_ign.sa_mask);
Sigact_ign.sa_flags = 0; /* interruptible */
@ -1194,7 +1194,7 @@ void
trapsig(int i)
{
Trap *p = &sigtraps[i];
int errno_ = errno;
int errno_sv = errno;
trap = p->set = 1;
if (p->flags & TF_DFL_INTR)
@ -1205,7 +1205,7 @@ trapsig(int i)
}
if (p->shtrap)
(*p->shtrap)(i);
errno = errno_;
errno = errno_sv;
}
/*
@ -1319,7 +1319,7 @@ runtrap(Trap *p, bool is_last)
if (trapstr[0] == '\0')
/* SIG_IGN */
goto donetrap;
if (i == SIGEXIT_ || i == SIGERR_) {
if (i == ksh_SIGEXIT || i == ksh_SIGERR) {
/* avoid recursion on these */
old_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.
*/
command(trapstr, current_lineno);
if (i == SIGEXIT_ || i == SIGERR_) {
if (i == ksh_SIGEXIT || i == ksh_SIGERR) {
if (p->flags & TF_CHANGED)
/* don't clear TF_CHANGED */
afree(trapstr, APERM);
@ -1454,7 +1454,7 @@ setsig(Trap *p, sig_t f, int flags)
{
struct sigaction sigact;
if (p->signal == SIGEXIT_ || p->signal == SIGERR_)
if (p->signal == ksh_SIGEXIT || p->signal == ksh_SIGERR)
return (1);
/*

View File

@ -20,7 +20,7 @@
#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 */
#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)
{
if (notoktomul(fac1, fac2))
internal_errorf(T_intovfl, fac1, '*', fac2);
internal_errorf(Tintovfl, fac1, '*', fac2);
return (aresize(ptr, fac1 * fac2, ap));
}
@ -100,7 +100,7 @@ aresize(void *ptr, size_t numb, Area *ap)
|| ALLOC_ISUNALIGNED(lp)
#endif
)
internal_errorf(T_oomem, (unsigned long)numb);
internal_errorf(Toomem, (unsigned long)numb);
/* this only works because Area is an ALLOC_ITEM */
lp->next = ap->next;
ap->next = lp;

44
lex.c
View File

@ -22,7 +22,7 @@
#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
@ -91,7 +91,7 @@ typedef struct {
static void readhere(struct ioword *);
static void ungetsc(int);
static void ungetsc_(int);
static int getsc__(void);
static int getsc_uu(void);
static void getsc_line(Source *);
static int getsc_bn(void);
static int s_get(void);
@ -111,13 +111,13 @@ static struct sretrace_info *retrace_info;
short subshell_nesting_level = 0;
/* optimised getsc_bn() */
#define _getsc() (*source->str != '\0' && *source->str != '\\' && \
#define o_getsc() (*source->str != '\0' && *source->str != '\\' && \
!backslash_skip ? *source->str++ : getsc_bn())
/* optimised getsc__() */
#define _getsc_() ((*source->str != '\0') ? *source->str++ : getsc__())
/* optimised getsc_uu() */
#define o_getsc_u() ((*source->str != '\0') ? *source->str++ : getsc_uu())
/* retrace helper */
#define _getsc_r(carg) { \
#define o_getsc_r(carg) { \
int cev = (carg); \
struct sretrace_info *rp = retrace_info; \
\
@ -136,7 +136,7 @@ static int getsc(void);
static int
getsc(void)
{
_getsc_r(_getsc());
o_getsc_r(o_getsc());
}
#else
static int getsc_r(int);
@ -144,10 +144,10 @@ static int getsc_r(int);
static int
getsc_r(int c)
{
_getsc_r(c);
o_getsc_r(c);
}
#define getsc() getsc_r(_getsc())
#define getsc() getsc_r(o_getsc())
#endif
#define STATE_BSIZE 8
@ -1260,7 +1260,7 @@ pushs(int type, Area *areap)
}
static int
getsc__(void)
getsc_uu(void)
{
Source *s = source;
int c;
@ -1328,7 +1328,7 @@ getsc__(void)
/* pop source stack */
source = s->next;
source->flags |= s->flags & SF_ALIAS;
c = getsc__();
c = getsc_uu();
if (c) {
s->flags |= SF_ALIASEND;
s->ugbuf[0] = c; s->ugbuf[1] = '\0';
@ -1445,7 +1445,7 @@ getsc_line(Source *s)
int linelen;
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 */
cp = Xstring(s->xs, xp);
/* change initial '!' into space */
@ -1453,10 +1453,10 @@ getsc_line(Source *s)
/* NUL terminate the current string */
*xp = '\0';
/* move the actual string forward */
memmove(cp + Tn_fc_e_, cp, linelen + /* NUL */ 1);
xp += Tn_fc_e_;
memmove(cp + Zfc_e_dash, cp, linelen + /* NUL */ 1);
xp += Zfc_e_dash;
/* prepend it with "fc -e -" */
memcpy(cp, T_fc_e_, Tn_fc_e_);
memcpy(cp, Tfc_e_dash, Zfc_e_dash);
}
#endif
s->start = s->str = cp;
@ -1753,19 +1753,19 @@ getsc_bn(void)
int c, c2;
if (ignore_backslash_newline)
return (_getsc_());
return (o_getsc_u());
if (backslash_skip == 1) {
backslash_skip = 2;
return (_getsc_());
return (o_getsc_u());
}
backslash_skip = 0;
while (/* CONSTCOND */ 1) {
c = _getsc_();
c = o_getsc_u();
if (c == '\\') {
if ((c2 = _getsc_()) == '\n')
if ((c2 = o_getsc_u()) == '\n')
/* ignore the \newline; get the next char... */
continue;
ungetsc_(c2);
@ -1780,16 +1780,16 @@ yyskiputf8bom(void)
{
int c;
if ((unsigned char)(c = _getsc_()) != 0xEF) {
if ((unsigned char)(c = o_getsc_u()) != 0xEF) {
ungetsc_(c);
return;
}
if ((unsigned char)(c = _getsc_()) != 0xBB) {
if ((unsigned char)(c = o_getsc_u()) != 0xBB) {
ungetsc_(c);
ungetsc_(0xEF);
return;
}
if ((unsigned char)(c = _getsc_()) != 0xBF) {
if ((unsigned char)(c = o_getsc_u()) != 0xBF) {
ungetsc_(c);
ungetsc_(0xBB);
ungetsc_(0xEF);

26
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h>
#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;
@ -59,12 +59,12 @@ static const char initsubs[] =
"${PS2=> } ${PS3=#? } ${PS4=+ } ${SECONDS=0} ${TMOUT=0}";
static const char *initcoms[] = {
T_typeset, "-r", initvsn, NULL,
T_typeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
T_typeset, "-i10", "SECONDS", "TMOUT", NULL,
T_alias,
Ttypeset, "-r", initvsn, NULL,
Ttypeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
Ttypeset, "-i10", "SECONDS", "TMOUT", NULL,
Talias,
"integer=typeset -i",
T_local_typeset,
Tlocal_typeset,
/* not "alias -t --": hash -r needs to work */
"hash=alias -t",
"type=whence -v",
@ -79,19 +79,19 @@ static const char *initcoms[] = {
"history=fc -l",
"nameref=typeset -n",
"nohup=nohup ",
T_r_fc_e_,
Tr_fc_e_dash,
"source=PATH=$PATH:. command .",
"login=exec login",
NULL,
/* 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",
"make", "mv", "pr", "rm", "sed", "sh", "vi", "who", NULL,
NULL
};
static const char *restr_com[] = {
T_typeset, "-r", "PATH", "ENV", "SHELL", NULL
Ttypeset, "-r", "PATH", "ENV", "SHELL", NULL
};
static int initio_done;
@ -105,7 +105,7 @@ rndsetup(void)
{
register uint32_t h;
struct {
ALLOC_ITEM __alloc_i;
ALLOC_ITEM alloc_INT;
void *dataptr, *stkptr, *mallocptr;
sigjmp_buf jbuf;
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) */
if (i == LEXIT || (Flag(FERREXIT) && (i == LERROR || i == LINTR) &&
sigtraps[SIGEXIT_].trap)) {
sigtraps[ksh_SIGEXIT].trap)) {
++trap_nested;
runtrap(&sigtraps[SIGEXIT_], trap_nested == 1);
runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1);
--trap_nested;
i = LLEAVE;
} else if (Flag(FERREXIT) && (i == LERROR || i == LINTR)) {
++trap_nested;
runtrap(&sigtraps[SIGERR_], trap_nested == 1);
runtrap(&sigtraps[ksh_SIGERR], trap_nested == 1);
--trap_nested;
i = LLEAVE;
}

13
misc.c
View File

@ -29,7 +29,7 @@
#include <grp.h>
#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 */
unsigned char chtypes[UCHAR_MAX + 1];
@ -185,7 +185,7 @@ printoptions(bool verbose)
octs + 4, oi.opt_width + 4, true);
} else {
/* short version like AT&T ksh93 */
shf_puts(T_set, shl_stdout);
shf_puts(Tset, shl_stdout);
while (i < (int)NELEM(options)) {
if (Flag(i) && options[i].name)
shprintf("%s %s %s", null, "-o",
@ -1074,7 +1074,7 @@ print_value_quoted(const char *s)
void
print_columns(struct shf *shf, int n,
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;
char *str;
@ -1086,13 +1086,14 @@ print_columns(struct shf *shf, int n,
return;
}
if (max_col_ > 2147483647) {
if (max_colz > 2147483647) {
#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
return;
}
max_col = (int)max_col_;
max_col = (int)max_colz;
++max_oct;
str = alloc(max_oct, ATEMP);

138
sh.h
View File

@ -151,9 +151,9 @@
#endif
#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
#define MKSH_VERSION "R40 2011/08/27"
#define MKSH_VERSION "R40 2011/09/07"
#ifndef MKSH_INCLUDES_ONLY
@ -333,9 +333,9 @@ extern int wcwidth(__WCHAR_TYPE__);
/* some useful #defines */
#ifdef EXTERN
# define I__(i) = i
# define E_INIT(i) = i
#else
# define I__(i)
# define E_INIT(i)
# define EXTERN extern
# define EXTERN_DEFINED
#endif
@ -383,11 +383,11 @@ typedef unsigned char mksh_bool;
#define LINE 4096 /* input line size */
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)
EXTERN const char digits_uc[] I__("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
EXTERN const char digits_lc[] I__("0123456789abcdefghijklmnopqrstuvwxyz");
EXTERN const char digits_uc[] E_INIT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
EXTERN const char digits_lc[] E_INIT("0123456789abcdefghijklmnopqrstuvwxyz");
/*
* Evil hack for const correctness due to API brokenness
@ -565,7 +565,7 @@ enum sh_flag {
* parsing & execution environment
*/
extern struct env {
ALLOC_ITEM __alloc_i; /* internal, do not touch */
ALLOC_ITEM alloc_INT; /* internal, do not touch */
Area area; /* temporary allocation area */
struct env *oenv; /* link to previous environment */
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 const char *kshname; /* $0 */
EXTERN struct {
uid_t kshuid_; /* real UID of shell */
uid_t ksheuid_; /* effective UID of shell */
gid_t kshgid_; /* real GID of shell */
gid_t kshegid_; /* effective GID of shell */
pid_t kshpgrp_; /* process group of shell */
pid_t kshppid_; /* PID of parent of shell */
pid_t kshpid_; /* $$, shell PID */
uid_t kshuid_v; /* real UID of shell */
uid_t ksheuid_v; /* effective UID of shell */
gid_t kshgid_v; /* real GID of shell */
gid_t kshegid_v; /* effective GID of shell */
pid_t kshpgrp_v; /* process group of shell */
pid_t kshppid_v; /* PID of parent of shell */
pid_t kshpid_v; /* $$, shell PID */
} rndsetupstate;
#define kshpid rndsetupstate.kshpid_
#define kshpgrp rndsetupstate.kshpgrp_
#define kshuid rndsetupstate.kshuid_
#define ksheuid rndsetupstate.ksheuid_
#define kshgid rndsetupstate.kshgid_
#define kshegid rndsetupstate.kshegid_
#define kshppid rndsetupstate.kshppid_
#define kshpid rndsetupstate.kshpid_v
#define kshpgrp rndsetupstate.kshpgrp_v
#define kshuid rndsetupstate.kshuid_v
#define ksheuid rndsetupstate.ksheuid_v
#define kshgid rndsetupstate.kshgid_v
#define kshegid rndsetupstate.kshegid_v
#define kshppid rndsetupstate.kshppid_v
/* option processing */
@ -652,33 +652,33 @@ struct shoption {
extern const struct shoption options[];
/* null value for variable; comparison pointer for unset */
EXTERN char null[] I__("");
EXTERN char null[] E_INIT("");
/* helpers for string pooling */
EXTERN const char T_intovfl[] I__("integer overflow %zu %c %zu prevented");
EXTERN const char T_oomem[] I__("can't allocate %lu data bytes");
EXTERN const char Tintovfl[] E_INIT("integer overflow %zu %c %zu prevented");
EXTERN const char Toomem[] E_INIT("can't allocate %lu data bytes");
#if defined(__GNUC__)
/* trust this to have string pooling; -Wformat bitches otherwise */
#define T_synerr "syntax error"
#define Tsynerr "syntax error"
#else
EXTERN const char T_synerr[] I__("syntax error");
EXTERN const char Tsynerr[] E_INIT("syntax error");
#endif
EXTERN const char T_select[] I__("select");
EXTERN const char T_r_fc_e_[] I__("r=fc -e -");
#define T_fc_e_ (T_r_fc_e_ + 2) /* "fc -e -" */
#define Tn_fc_e_ 7 /* strlen(T_fc_e_) */
EXTERN const char T_local_typeset[] I__("local=typeset");
#define T__typeset (T_local_typeset + 5) /* "=typeset" */
#define T_typeset (T_local_typeset + 6) /* "typeset" */
EXTERN const char T_palias[] I__("+alias");
#define T_alias (T_palias + 1) /* "alias" */
EXTERN const char T_punalias[] I__("+unalias");
#define T_unalias (T_punalias + 1) /* "unalias" */
EXTERN const char T_sgset[] I__("*=set");
#define T_set (T_sgset + 2) /* "set" */
EXTERN const char T_gbuiltin[] I__("=builtin");
#define T_builtin (T_gbuiltin + 1) /* "builtin" */
EXTERN const char T__function[] I__(" function");
#define T_function (T__function + 1) /* "function" */
EXTERN const char Tselect[] E_INIT("select");
EXTERN const char Tr_fc_e_dash[] E_INIT("r=fc -e -");
#define Tfc_e_dash (Tr_fc_e_dash + 2) /* "fc -e -" */
#define Zfc_e_dash 7 /* strlen(Tfc_e_dash) */
EXTERN const char Tlocal_typeset[] E_INIT("local=typeset");
#define T_typeset (Tlocal_typeset + 5) /* "=typeset" */
#define Ttypeset (Tlocal_typeset + 6) /* "typeset" */
EXTERN const char Tpalias[] E_INIT("+alias");
#define Talias (Tpalias + 1) /* "alias" */
EXTERN const char Tpunalias[] E_INIT("+unalias");
#define Tunalias (Tpunalias + 1) /* "unalias" */
EXTERN const char Tsgset[] E_INIT("*=set");
#define Tset (Tsgset + 2) /* "set" */
EXTERN const char Tgbuiltin[] E_INIT("=builtin");
#define Tbuiltin (Tgbuiltin + 1) /* "builtin" */
EXTERN const char T_function[] E_INIT(" function");
#define Tfunction (T_function + 1) /* "function" */
enum temp_type {
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_SHTRAP BIT(5) /* trap for internal use (ALRM, CHLD, WINCH) */
#define SIGEXIT_ 0 /* for trap EXIT */
#define SIGERR_ NSIG /* for trap ERR */
#define ksh_SIGEXIT 0 /* for trap EXIT */
#define ksh_SIGERR NSIG /* for trap ERR */
EXTERN volatile sig_atomic_t trap; /* traps pending? */
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 */
#ifdef SIGWINCH
EXTERN volatile sig_atomic_t got_winch I__(1);
EXTERN volatile sig_atomic_t got_winch E_INIT(1);
#else
#define got_winch true
#endif
@ -764,7 +764,7 @@ enum tmout_enum {
TMOUT_LEAVING /* have timed out */
};
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 */
EXTERN int really_exit;
@ -790,7 +790,7 @@ extern unsigned char chtypes[];
#define ksh_isalphx(c) ctype((c), C_ALPHA)
#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 */
@ -859,8 +859,8 @@ EXTERN char *current_wd;
*/
#define MIN_COLS (2 + MIN_EDIT_SPACE + 3)
#define MIN_LINS 3
EXTERN mksh_ari_t x_cols I__(80); /* tty columns */
EXTERN mksh_ari_t x_lins I__(-1); /* tty lines */
EXTERN mksh_ari_t x_cols E_INIT(80); /* tty columns */
EXTERN mksh_ari_t x_lins E_INIT(-1); /* tty lines */
/* These to avoid bracket matching problems */
#define OPAREN '('
@ -904,7 +904,7 @@ EXTERN mksh_ari_t x_lins I__(-1); /* tty lines */
((shf)->wnleft--, *(shf)->wp++ = (c)))
#define shf_eof(shf) ((shf)->flags & SHF_EOF)
#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))
/* Flags passed to shf_*open() */
@ -941,7 +941,7 @@ struct shf {
ssize_t wnleft; /* write: how much space left in buffer */
int flags; /* see SHF_* */
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[];
@ -971,7 +971,7 @@ struct tbl {
} u;
union {
int field; /* field with for -L/-R/-Z */
int errno_; /* CEXEC/CTALIAS */
int errnov; /* CEXEC/CTALIAS */
} u2;
union {
uint32_t hval; /* hash(name) */
@ -1037,7 +1037,7 @@ EXTERN enum {
SRF_NOP,
SRF_ENABLE,
SRF_DISABLE
} set_refflag I__(SRF_NOP);
} set_refflag E_INIT(SRF_NOP);
/* command types */
#define CNONE 0 /* undefined */
@ -1061,13 +1061,13 @@ EXTERN enum {
#define AF_ARGV_ALLOC 0x1 /* argv[] array 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_ARGC(a) ((a).argc_ - (a).skip)
#define AI_ARGC(a) ((a).ai_argc - (a).skip)
/* Argument info. Used for $#, $* for shell, functions, includes, etc. */
struct arg_info {
const char **argv;
int flags; /* AF_* */
int argc_;
int ai_argc;
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 DONTRUNCOMMAND BIT(4) /* do not run $(command) things */
#define DOASNTILDE BIT(5) /* assignment ~ expansion (after =, :) */
#define DOBRACE_ BIT(6) /* used by expand(): do brace expansion */
#define DOMAGIC_ BIT(7) /* used by expand(): string contains MAGIC */
#define DOTEMP_ BIT(8) /* ditto : in word part of ${..[%#=?]..} */
#define DOBRACE BIT(6) /* used by expand(): do brace expansion */
#define DOMAGIC BIT(7) /* used by expand(): string contains MAGIC */
#define DOTEMP BIT(8) /* dito: in word part of ${..[%#=?]..} */
#define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */
#define DOMARKDIRS BIT(10) /* force markdirs behaviour */
@ -1330,10 +1330,10 @@ typedef struct XPtrV {
} XPtrV;
#define XPinit(x, n) do { \
void **vp__; \
vp__ = alloc2((n), sizeof(void *), ATEMP); \
(x).cur = (x).beg = vp__; \
(x).end = vp__ + (n); \
void **XPinit_vp; \
XPinit_vp = alloc2((n), sizeof(void *), ATEMP); \
(x).cur = (x).beg = XPinit_vp; \
(x).end = XPinit_vp + (n); \
} while (/* CONSTCOND */ 0)
#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 checkoktoadd(val, cnst) do { \
if (notoktoadd((val), (cnst))) \
internal_errorf(T_intovfl, (size_t)(val), \
internal_errorf(Tintovfl, (size_t)(val), \
'+', (size_t)(cnst)); \
} while (/* CONSTCOND */ 0)
@ -1561,8 +1561,7 @@ int define(const char *, struct op *);
const char *builtin(const char *, int (*)(const char **));
struct tbl *findcom(const char *, int);
void flushcom(bool);
const char *search(const char *, const char *, int, int *);
int search_access(const char *, int, int *);
const char *search_path(const char *, const char *, int, int *);
int pr_menu(const char * const *);
int pr_list(char * const *);
/* expr.c */
@ -1578,6 +1577,7 @@ size_t utf_ptradj(const char *);
#ifndef MKSH_mirbsd_wcwidth
int utf_wcwidth(unsigned int);
#endif
int ksh_access(const char *, int);
/* funcs.c */
int c_hash(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_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 struct termios tty_state; /* saved tty state */
@ -1922,6 +1922,6 @@ extern void tty_close(void);
# undef EXTERN_DEFINED
# undef EXTERN
#endif
#undef I__
#undef E_INIT
#endif /* !MKSH_INCLUDES_ONLY */

24
shf.c
View File

@ -24,7 +24,7 @@
#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() */
#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->wbsize = sflags & SHF_UNBUF ? 0 : bsize;
shf->flags = sflags;
shf->errno_ = 0;
shf->errnosv = 0;
shf->bsize = bsize;
if (sflags & SHF_CLEXEC)
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->wbsize = sflags & SHF_UNBUF ? 0 : bsize;
shf->flags = (shf->flags & (SHF_ALLOCS | SHF_ALLOCB)) | sflags;
shf->errno_ = 0;
shf->errnosv = 0;
if (sflags & SHF_CLEXEC)
fcntl(fd, F_SETFD, FD_CLOEXEC);
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->wbsize = bsize;
shf->flags = sflags | SHF_STRING;
shf->errno_ = 0;
shf->errnosv = 0;
shf->bsize = bsize;
return (shf);
@ -290,7 +290,7 @@ shf_flush(struct shf *shf)
internal_errorf("%s: %s", "shf_flush", "no fd");
if (shf->flags & SHF_ERROR) {
errno = shf->errno_;
errno = shf->errnosv;
return (EOF);
}
@ -321,7 +321,7 @@ shf_emptybuf(struct shf *shf, int flags)
internal_errorf("%s: %s", "shf_emptybuf", "no fd");
if (shf->flags & SHF_ERROR) {
errno = shf->errno_;
errno = shf->errnosv;
return (EOF);
}
@ -363,7 +363,7 @@ shf_emptybuf(struct shf *shf, int flags)
!(shf->flags & SHF_INTERRUPT))
continue;
shf->flags |= SHF_ERROR;
shf->errno_ = errno;
shf->errnosv = errno;
shf->wnleft = 0;
if (buf != shf->buf) {
/*
@ -408,7 +408,7 @@ shf_fillbuf(struct shf *shf)
if (shf->flags & (SHF_EOF | SHF_ERROR)) {
if (shf->flags & SHF_ERROR)
errno = shf->errno_;
errno = shf->errnosv;
return (EOF);
}
@ -426,7 +426,7 @@ shf_fillbuf(struct shf *shf)
}
if (n < 0) {
shf->flags |= SHF_ERROR;
shf->errno_ = errno;
shf->errnosv = errno;
shf->rnleft = 0;
shf->rp = shf->buf;
return (EOF);
@ -585,7 +585,7 @@ shf_putchar(int c, struct shf *shf)
if (shf->fd < 0)
internal_errorf("%s: %s", "shf_putchar", "no fd");
if (shf->flags & SHF_ERROR) {
errno = shf->errno_;
errno = shf->errnosv;
return (EOF);
}
while ((n = write(shf->fd, &cc, 1)) != 1)
@ -594,7 +594,7 @@ shf_putchar(int c, struct shf *shf)
!(shf->flags & SHF_INTERRUPT))
continue;
shf->flags |= SHF_ERROR;
shf->errno_ = errno;
shf->errnosv = errno;
return (EOF);
}
} else {
@ -668,7 +668,7 @@ shf_write(const char *buf, ssize_t nbytes, struct shf *shf)
!(shf->flags & SHF_INTERRUPT))
continue;
shf->flags |= SHF_ERROR;
shf->errno_ = errno;
shf->errnosv = errno;
shf->wnleft = 0;
/*
* Note: fwrite(3) returns 0

16
syn.c
View File

@ -22,7 +22,7 @@
#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 void yyskiputf8bom(void);
@ -420,7 +420,7 @@ get_command(int cf)
t = newtp((c == FOR) ? TFOR : TSELECT);
musthave(LWORD, ARRAYVAR);
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");
strdupx(t->str, ident, ATEMP);
nesting_push(&old_nesting, c);
@ -764,13 +764,13 @@ const struct tokeninfo {
{ "case", CASE, true },
{ "esac", ESAC, true },
{ "for", FOR, true },
{ T_select, SELECT, true },
{ Tselect, SELECT, true },
{ "while", WHILE, true },
{ "until", UNTIL, true },
{ "do", DO, true },
{ "done", DONE, true },
{ "in", IN, true },
{ T_function, FUNCTION, true },
{ Tfunction, FUNCTION, true },
{ "time", TIME, true },
{ "{", '{', true },
{ "}", '}', true },
@ -831,7 +831,7 @@ syntaxerr(const char *what)
goto Again;
}
/* don't quote the EOF */
yyerror("%s: %s %s\n", T_synerr, "unexpected", "EOF");
yyerror("%s: %s %s\n", Tsynerr, "unexpected", "EOF");
/* NOTREACHED */
case LWORD:
@ -858,7 +858,7 @@ syntaxerr(const char *what)
s = redir;
}
}
yyerror("%s: '%s' %s\n", T_synerr, s, what);
yyerror("%s: '%s' %s\n", Tsynerr, s, what);
}
static void
@ -920,10 +920,10 @@ assign_command(char *s)
{
if (!*s)
return (0);
return ((strcmp(s, T_alias) == 0) ||
return ((strcmp(s, Talias) == 0) ||
(strcmp(s, "export") == 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 */

6
tree.c
View File

@ -22,7 +22,7 @@
#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
@ -100,7 +100,7 @@ ptree(struct op *t, int indent, struct shf *shf)
case TSELECT:
case TFOR:
fptreef(shf, indent, "%s %s ",
(t->type == TFOR) ? "for" : T_select, t->str);
(t->type == TFOR) ? "for" : Tselect, t->str);
if (t->vars != NULL) {
shf_puts("in ", shf);
w = (const char **)t->vars;
@ -701,7 +701,7 @@ void
fpFUNCTf(struct shf *shf, int i, bool isksh, const char *k, struct op *v)
{
if (isksh)
fptreef(shf, i, "%s %s %T", T_function, k, v);
fptreef(shf, i, "%s %s %T", Tfunction, k, v);
else
fptreef(shf, i, "%s() %T", k, v);
}

3
var.c
View File

@ -26,7 +26,7 @@
#include <sys/sysctl.h>
#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
@ -1170,6 +1170,7 @@ setspec(struct tbl *vp)
struct stat statb;
s = str_val(vp);
/* LINTED use of access */
if (s[0] == '/' && access(s, W_OK|X_OK) == 0 &&
stat(s, &statb) == 0 && S_ISDIR(statb.st_mode))
strdupx(tmpdir, s, APERM);