• bring back test -H ifdef S_ISCDF (for HP-UX)

• whitespace, etc.
• bump version for tonight, I’m not gonna hack on c_cd,
  all this pathname stuff is mind-boggling…
This commit is contained in:
tg 2011-03-26 21:46:06 +00:00
parent a55de5f840
commit 5f31b8c97a
5 changed files with 111 additions and 47 deletions

View File

@ -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: 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 R39 2011/03/23 @(#)MIRBSD KSH R39 2011/03/26
description: description:
Check version of shell. Check version of shell.
stdin: stdin:

139
funcs.c
View File

@ -38,7 +38,7 @@
#endif #endif
#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 #if HAVE_KILLPG
/* /*
@ -2615,132 +2615,180 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
if (!do_eval) if (!do_eval)
return (0); return (0);
switch ((int)op) { switch (op) {
/* /*
* Unary Operators * Unary Operators
*/ */
/* -n */
case TO_STNZE: case TO_STNZE:
/* -n */
return (*opnd1 != '\0'); return (*opnd1 != '\0');
/* -z */
case TO_STZER: case TO_STZER:
/* -z */
return (*opnd1 == '\0'); return (*opnd1 == '\0');
/* -o */
case TO_OPTION: case TO_OPTION:
/* -o */
if ((i = *opnd1) == '!' || i == '?') if ((i = *opnd1) == '!' || i == '?')
opnd1++; opnd1++;
if ((k = option(opnd1)) == (size_t)-1) if ((k = option(opnd1)) == (size_t)-1)
return (0); return (0);
return (i == '?' ? 1 : i == '!' ? !Flag(k) : Flag(k)); return (i == '?' ? 1 : i == '!' ? !Flag(k) : Flag(k));
/* -r */
case TO_FILRD: case TO_FILRD:
/* -r */
return (test_eaccess(opnd1, R_OK) == 0); return (test_eaccess(opnd1, R_OK) == 0);
/* -w */
case TO_FILWR: case TO_FILWR:
/* -w */
return (test_eaccess(opnd1, W_OK) == 0); return (test_eaccess(opnd1, W_OK) == 0);
/* -x */
case TO_FILEX: case TO_FILEX:
/* -x */
return (test_eaccess(opnd1, X_OK) == 0); return (test_eaccess(opnd1, X_OK) == 0);
/* -a */
case TO_FILAXST: case TO_FILAXST:
/* -a */ /* -e */
case TO_FILEXST: case TO_FILEXST:
/* -e */
return (stat(opnd1, &b1) == 0); return (stat(opnd1, &b1) == 0);
/* -r */
case TO_FILREG: case TO_FILREG:
/* -r */
return (stat(opnd1, &b1) == 0 && S_ISREG(b1.st_mode)); return (stat(opnd1, &b1) == 0 && S_ISREG(b1.st_mode));
/* -d */
case TO_FILID: case TO_FILID:
/* -d */
return (stat(opnd1, &b1) == 0 && S_ISDIR(b1.st_mode)); return (stat(opnd1, &b1) == 0 && S_ISDIR(b1.st_mode));
/* -c */
case TO_FILCDEV: case TO_FILCDEV:
/* -c */
return (stat(opnd1, &b1) == 0 && S_ISCHR(b1.st_mode)); return (stat(opnd1, &b1) == 0 && S_ISCHR(b1.st_mode));
/* -b */
case TO_FILBDEV: case TO_FILBDEV:
/* -b */
return (stat(opnd1, &b1) == 0 && S_ISBLK(b1.st_mode)); return (stat(opnd1, &b1) == 0 && S_ISBLK(b1.st_mode));
/* -p */
case TO_FILFIFO: case TO_FILFIFO:
/* -p */
return (stat(opnd1, &b1) == 0 && S_ISFIFO(b1.st_mode)); return (stat(opnd1, &b1) == 0 && S_ISFIFO(b1.st_mode));
/* -h or -L */
case TO_FILSYM: case TO_FILSYM:
/* -h -L */
return (lstat(opnd1, &b1) == 0 && S_ISLNK(b1.st_mode)); return (lstat(opnd1, &b1) == 0 && S_ISLNK(b1.st_mode));
/* -S */
case TO_FILSOCK: case TO_FILSOCK:
/* -S */
return (stat(opnd1, &b1) == 0 && S_ISSOCK(b1.st_mode)); return (stat(opnd1, &b1) == 0 && S_ISSOCK(b1.st_mode));
/* -H => HP context dependent files (directories) */
case TO_FILCDF: 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); return (0);
#endif
/* -u */
case TO_FILSETU: case TO_FILSETU:
/* -u */
return (stat(opnd1, &b1) == 0 && return (stat(opnd1, &b1) == 0 &&
(b1.st_mode & S_ISUID) == S_ISUID); (b1.st_mode & S_ISUID) == S_ISUID);
/* -g */
case TO_FILSETG: case TO_FILSETG:
/* -g */
return (stat(opnd1, &b1) == 0 && return (stat(opnd1, &b1) == 0 &&
(b1.st_mode & S_ISGID) == S_ISGID); (b1.st_mode & S_ISGID) == S_ISGID);
/* -k */
case TO_FILSTCK: case TO_FILSTCK:
/* -k */
#ifdef S_ISVTX #ifdef S_ISVTX
return (stat(opnd1, &b1) == 0 && return (stat(opnd1, &b1) == 0 &&
(b1.st_mode & S_ISVTX) == S_ISVTX); (b1.st_mode & S_ISVTX) == S_ISVTX);
#else #else
return (0); return (0);
#endif #endif
/* -s */
case TO_FILGZ: case TO_FILGZ:
/* -s */
return (stat(opnd1, &b1) == 0 && b1.st_size > 0L); return (stat(opnd1, &b1) == 0 && b1.st_size > 0L);
/* -t */
case TO_FILTT: case TO_FILTT:
/* -t */
if (opnd1 && !bi_getn(opnd1, &i)) { if (opnd1 && !bi_getn(opnd1, &i)) {
te->flags |= TEF_ERROR; te->flags |= TEF_ERROR;
i = 0; i = 0;
} else } else
i = isatty(opnd1 ? i : 0); i = isatty(opnd1 ? i : 0);
return (i); return (i);
/* -O */
case TO_FILUID: case TO_FILUID:
/* -O */
return (stat(opnd1, &b1) == 0 && b1.st_uid == ksheuid); return (stat(opnd1, &b1) == 0 && b1.st_uid == ksheuid);
/* -G */
case TO_FILGID: case TO_FILGID:
/* -G */
return (stat(opnd1, &b1) == 0 && b1.st_gid == getegid()); return (stat(opnd1, &b1) == 0 && b1.st_gid == getegid());
/* /*
* Binary Operators * Binary Operators
*/ */
/* = */
case TO_STEQL: case TO_STEQL:
/* = */
if (te->flags & TEF_DBRACKET) if (te->flags & TEF_DBRACKET)
return (gmatchx(opnd1, opnd2, false)); return (gmatchx(opnd1, opnd2, false));
return (strcmp(opnd1, opnd2) == 0); return (strcmp(opnd1, opnd2) == 0);
/* != */
case TO_STNEQ: case TO_STNEQ:
/* != */
if (te->flags & TEF_DBRACKET) if (te->flags & TEF_DBRACKET)
return (!gmatchx(opnd1, opnd2, false)); return (!gmatchx(opnd1, opnd2, false));
return (strcmp(opnd1, opnd2) != 0); return (strcmp(opnd1, opnd2) != 0);
/* < */
case TO_STLT: case TO_STLT:
/* < */
return (strcmp(opnd1, opnd2) < 0); return (strcmp(opnd1, opnd2) < 0);
/* > */
case TO_STGT: case TO_STGT:
/* > */
return (strcmp(opnd1, opnd2) > 0); return (strcmp(opnd1, opnd2) > 0);
/* -eq */
case TO_INTEQ: case TO_INTEQ:
/* -eq */ /* -ne */
case TO_INTNE: case TO_INTNE:
/* -ne */ /* -ge */
case TO_INTGE: case TO_INTGE:
/* -ge */ /* -gt */
case TO_INTGT: case TO_INTGT:
/* -gt */ /* -le */
case TO_INTLE: case TO_INTLE:
/* -le */ /* -lt */
case TO_INTLT: case TO_INTLT:
/* -lt */
if (!evaluate(opnd1, &v1, KSH_RETURN_ERROR, false) || if (!evaluate(opnd1, &v1, KSH_RETURN_ERROR, false) ||
!evaluate(opnd2, &v2, KSH_RETURN_ERROR, false)) { !evaluate(opnd2, &v2, KSH_RETURN_ERROR, false)) {
/* error already printed.. */ /* error already printed.. */
te->flags |= TEF_ERROR; te->flags |= TEF_ERROR;
return (1); return (1);
} }
switch ((int)op) { switch (op) {
case TO_INTEQ: case TO_INTEQ:
return (v1 == v2); return (v1 == v2);
case TO_INTNE: case TO_INTNE:
@ -2753,9 +2801,14 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
return (v1 <= v2); return (v1 <= v2);
case TO_INTLT: case TO_INTLT:
return (v1 < v2); return (v1 < v2);
default:
/* NOTREACHED */
break;
} }
/* NOTREACHED */
/* -nt */
case TO_FILNT: case TO_FILNT:
/* -nt */
/* /*
* ksh88/ksh93 succeed if file2 can't be stated * ksh88/ksh93 succeed if file2 can't be stated
* (subtly different from 'does not exist'). * (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 && return (stat(opnd1, &b1) == 0 &&
(((s = stat(opnd2, &b2)) == 0 && (((s = stat(opnd2, &b2)) == 0 &&
b1.st_mtime > b2.st_mtime) || s < 0)); b1.st_mtime > b2.st_mtime) || s < 0));
/* -ot */
case TO_FILOT: case TO_FILOT:
/* -ot */
/* /*
* ksh88/ksh93 succeed if file1 can't be stated * ksh88/ksh93 succeed if file1 can't be stated
* (subtly different from 'does not exist'). * (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 && return (stat(opnd2, &b2) == 0 &&
(((s = stat(opnd1, &b1)) == 0 && (((s = stat(opnd1, &b1)) == 0 &&
b1.st_mtime < b2.st_mtime) || s < 0)); b1.st_mtime < b2.st_mtime) || s < 0));
/* -ef */
case TO_FILEQ: case TO_FILEQ:
/* -ef */
return (stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 && return (stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 &&
b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino); 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"); (*te->error)(te, 0, "internal error: unknown op");
return (1); return (1);

4
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.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 */ /* type bits for unsigned char */
unsigned char chtypes[UCHAR_MAX + 1]; unsigned char chtypes[UCHAR_MAX + 1];
@ -200,7 +200,7 @@ char *
getoptions(void) getoptions(void)
{ {
unsigned int i; unsigned int i;
char m[(int) FNFLAGS + 1]; char m[(int)FNFLAGS + 1];
char *cp = m; char *cp = m;
for (i = 0; i < NELEM(options); i++) for (i = 0; i < NELEM(options); i++)

7
mksh.1
View File

@ -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 $ .\" $OpenBSD: ksh.1,v 1.139 2011/03/09 09:30:39 okan Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
@ -72,7 +72,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" 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 .\" Check which macro package we use
.\" .\"
@ -4140,6 +4140,9 @@ group is the shell's effective group ID.
.It Fl g Ar file .It Fl g Ar file
.Ar file Ns 's .Ar file Ns 's
mode has the setgid bit set. 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 .It Fl h Ar file
.Ar file .Ar file
is a symbolic link. is a symbolic link.

4
sh.h
View File

@ -154,9 +154,9 @@
#endif #endif
#ifdef EXTERN #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 #endif
#define MKSH_VERSION "R39 2011/03/23" #define MKSH_VERSION "R39 2011/03/26"
#ifndef MKSH_INCLUDES_ONLY #ifndef MKSH_INCLUDES_ONLY