diff --git a/check.t b/check.t index f7ae5c3..a61f816 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.436 2011/03/26 21:09:06 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.437 2011/03/26 21:46:00 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -25,7 +25,7 @@ # http://www.research.att.com/~gsf/public/ifs.sh expected-stdout: - @(#)MIRBSD KSH R39 2011/03/23 + @(#)MIRBSD KSH R39 2011/03/26 description: Check version of shell. stdin: diff --git a/funcs.c b/funcs.c index 17a8631..87c3e57 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.179 2011/03/24 19:05:47 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.180 2011/03/26 21:46:02 tg Exp $"); #if HAVE_KILLPG /* @@ -2615,132 +2615,180 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2, if (!do_eval) return (0); - switch ((int)op) { + switch (op) { + /* * Unary Operators */ + + /* -n */ case TO_STNZE: - /* -n */ return (*opnd1 != '\0'); + + /* -z */ case TO_STZER: - /* -z */ return (*opnd1 == '\0'); + + /* -o */ case TO_OPTION: - /* -o */ if ((i = *opnd1) == '!' || i == '?') opnd1++; if ((k = option(opnd1)) == (size_t)-1) return (0); return (i == '?' ? 1 : i == '!' ? !Flag(k) : Flag(k)); + + /* -r */ case TO_FILRD: - /* -r */ return (test_eaccess(opnd1, R_OK) == 0); + + /* -w */ case TO_FILWR: - /* -w */ return (test_eaccess(opnd1, W_OK) == 0); + + /* -x */ case TO_FILEX: - /* -x */ return (test_eaccess(opnd1, X_OK) == 0); + + /* -a */ case TO_FILAXST: - /* -a */ + /* -e */ case TO_FILEXST: - /* -e */ return (stat(opnd1, &b1) == 0); + + /* -r */ case TO_FILREG: - /* -r */ return (stat(opnd1, &b1) == 0 && S_ISREG(b1.st_mode)); + + /* -d */ case TO_FILID: - /* -d */ return (stat(opnd1, &b1) == 0 && S_ISDIR(b1.st_mode)); + + /* -c */ case TO_FILCDEV: - /* -c */ return (stat(opnd1, &b1) == 0 && S_ISCHR(b1.st_mode)); + + /* -b */ case TO_FILBDEV: - /* -b */ return (stat(opnd1, &b1) == 0 && S_ISBLK(b1.st_mode)); + + /* -p */ case TO_FILFIFO: - /* -p */ return (stat(opnd1, &b1) == 0 && S_ISFIFO(b1.st_mode)); + + /* -h or -L */ case TO_FILSYM: - /* -h -L */ return (lstat(opnd1, &b1) == 0 && S_ISLNK(b1.st_mode)); + + /* -S */ case TO_FILSOCK: - /* -S */ return (stat(opnd1, &b1) == 0 && S_ISSOCK(b1.st_mode)); + + /* -H => HP context dependent files (directories) */ case TO_FILCDF: - /* -H HP context dependent files (directories) */ +#ifdef S_ISCDF + { + char *nv; + + /* + * Append a + to filename and check to see if result is + * a setuid directory. CDF stuff in general is hookey, + * since it breaks for, e.g., the following sequence: + * echo hi >foo+; mkdir foo; echo bye >foo/default; + * chmod u+s foo (foo+ refers to the file with hi in it, + * there is no way to get at the file with bye in it; + * please correct me if I'm wrong about this). + */ + + nv = shf_smprintf("%s+", opnd1); + return (stat(nv, &b1) == 0 && S_ISCDF(b1.st_mode)); + } +#else return (0); +#endif + + /* -u */ case TO_FILSETU: - /* -u */ return (stat(opnd1, &b1) == 0 && (b1.st_mode & S_ISUID) == S_ISUID); + + /* -g */ case TO_FILSETG: - /* -g */ return (stat(opnd1, &b1) == 0 && (b1.st_mode & S_ISGID) == S_ISGID); + + /* -k */ case TO_FILSTCK: - /* -k */ #ifdef S_ISVTX return (stat(opnd1, &b1) == 0 && (b1.st_mode & S_ISVTX) == S_ISVTX); #else return (0); #endif + + /* -s */ case TO_FILGZ: - /* -s */ return (stat(opnd1, &b1) == 0 && b1.st_size > 0L); + + /* -t */ case TO_FILTT: - /* -t */ if (opnd1 && !bi_getn(opnd1, &i)) { te->flags |= TEF_ERROR; i = 0; } else i = isatty(opnd1 ? i : 0); return (i); + + /* -O */ case TO_FILUID: - /* -O */ return (stat(opnd1, &b1) == 0 && b1.st_uid == ksheuid); + + /* -G */ case TO_FILGID: - /* -G */ return (stat(opnd1, &b1) == 0 && b1.st_gid == getegid()); + /* * Binary Operators */ + + /* = */ case TO_STEQL: - /* = */ if (te->flags & TEF_DBRACKET) return (gmatchx(opnd1, opnd2, false)); return (strcmp(opnd1, opnd2) == 0); + + /* != */ case TO_STNEQ: - /* != */ if (te->flags & TEF_DBRACKET) return (!gmatchx(opnd1, opnd2, false)); return (strcmp(opnd1, opnd2) != 0); + + /* < */ case TO_STLT: - /* < */ return (strcmp(opnd1, opnd2) < 0); + + /* > */ case TO_STGT: - /* > */ return (strcmp(opnd1, opnd2) > 0); + + /* -eq */ case TO_INTEQ: - /* -eq */ + /* -ne */ case TO_INTNE: - /* -ne */ + /* -ge */ case TO_INTGE: - /* -ge */ + /* -gt */ case TO_INTGT: - /* -gt */ + /* -le */ case TO_INTLE: - /* -le */ + /* -lt */ case TO_INTLT: - /* -lt */ if (!evaluate(opnd1, &v1, KSH_RETURN_ERROR, false) || !evaluate(opnd2, &v2, KSH_RETURN_ERROR, false)) { /* error already printed.. */ te->flags |= TEF_ERROR; return (1); } - switch ((int)op) { + switch (op) { case TO_INTEQ: return (v1 == v2); case TO_INTNE: @@ -2753,9 +2801,14 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2, return (v1 <= v2); case TO_INTLT: return (v1 < v2); + default: + /* NOTREACHED */ + break; } + /* NOTREACHED */ + + /* -nt */ case TO_FILNT: - /* -nt */ /* * ksh88/ksh93 succeed if file2 can't be stated * (subtly different from 'does not exist'). @@ -2763,8 +2816,9 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2, return (stat(opnd1, &b1) == 0 && (((s = stat(opnd2, &b2)) == 0 && b1.st_mtime > b2.st_mtime) || s < 0)); + + /* -ot */ case TO_FILOT: - /* -ot */ /* * ksh88/ksh93 succeed if file1 can't be stated * (subtly different from 'does not exist'). @@ -2772,10 +2826,17 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2, return (stat(opnd2, &b2) == 0 && (((s = stat(opnd1, &b1)) == 0 && b1.st_mtime < b2.st_mtime) || s < 0)); + + /* -ef */ case TO_FILEQ: - /* -ef */ return (stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 && b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino); + + /* all other cases */ + case TO_NONOP: + case TO_NONNULL: + /* throw the error */ + break; } (*te->error)(te, 0, "internal error: unknown op"); return (1); diff --git a/misc.c b/misc.c index bd0b988..b2b3039 100644 --- a/misc.c +++ b/misc.c @@ -29,7 +29,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.162 2011/03/26 21:09:09 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.163 2011/03/26 21:46:03 tg Exp $"); /* type bits for unsigned char */ unsigned char chtypes[UCHAR_MAX + 1]; @@ -200,7 +200,7 @@ char * getoptions(void) { unsigned int i; - char m[(int) FNFLAGS + 1]; + char m[(int)FNFLAGS + 1]; char *cp = m; for (i = 0; i < NELEM(options); i++) diff --git a/mksh.1 b/mksh.1 index 9a0f12a..5a43bcd 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.253 2011/03/13 16:35:54 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.254 2011/03/26 21:46:04 tg Exp $ .\" $OpenBSD: ksh.1,v 1.139 2011/03/09 09:30:39 okan Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -72,7 +72,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: March 13 2011 $ +.Dd $Mdocdate: March 26 2011 $ .\" .\" Check which macro package we use .\" @@ -4140,6 +4140,9 @@ group is the shell's effective group ID. .It Fl g Ar file .Ar file Ns 's mode has the setgid bit set. +.It Fl H Ar file +.Ar file +is a context dependent directory (only useful on HP-UX). .It Fl h Ar file .Ar file is a symbolic link. diff --git a/sh.h b/sh.h index 688245f..fe86eff 100644 --- a/sh.h +++ b/sh.h @@ -154,9 +154,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.453 2011/03/26 19:43:49 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.454 2011/03/26 21:46:06 tg Exp $"); #endif -#define MKSH_VERSION "R39 2011/03/23" +#define MKSH_VERSION "R39 2011/03/26" #ifndef MKSH_INCLUDES_ONLY