sprinkle mksh_ari_t to limit arithmetics to 32 bit even

on Debian Lenny/amd64 (XXX need more verification; this
can be used for 64 bit arithmetics later too)

PPID, PGRP, RANDOM, USER_ID are now unsigned by default
This commit is contained in:
tg 2009-03-14 18:12:55 +00:00
parent 1552bf1576
commit 32bc1dc40e
10 changed files with 102 additions and 65 deletions

31
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.256 2009/02/22 18:02:30 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.257 2009/03/14 18:12:50 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 $
@ -7,7 +7,7 @@
# http://www.research.att.com/~gsf/public/ifs.sh
expected-stdout:
@(#)MIRBSD KSH R36 2009/02/22
@(#)MIRBSD KSH R36 2009/03/14
description:
Check version of shell.
stdin:
@ -277,6 +277,33 @@ expected-stdout:
x6 1975973142 1975973142
x7 right
---
name: arith-limit32-1
description:
Check if arithmetics are 32 bit
stdin:
# signed vs unsigned
print x1 $((-1)) $((#-1))
# calculating
typeset -i vs
typeset -Ui vu
vs=2147483647; vu=2147483647
print x2 $vs $vu
let vs++ vu++
print x3 $vs $vu
vs=4294967295; vu=4294967295
print x4 $vs $vu
let vs++ vu++
print x5 $vs $vu
let vs++ vu++
print x6 $vs $vu
expected-stdout:
x1 -1 4294967295
x2 2147483647 2147483647
x3 -2147483648 2147483648
x4 -1 4294967295
x5 0 0
x6 1 1
---
name: bksl-nl-ign-1
description:
Check that \newline is not collasped after #

4
eval.c
View File

@ -2,7 +2,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.51 2008/12/13 17:02:13 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.52 2009/03/14 18:12:51 tg Exp $");
#ifdef MKSH_SMALL
#define MKSH_NOPWNAM
@ -314,7 +314,7 @@ expand(const char *cp, /* input word */
switch (stype & 0x7f) {
case '0': {
char *beg, *mid, *end, *stg;
long from = 0, num = -1, flen;
mksh_ari_t from = 0, num = -1, flen;
/* ! DOBLANK,DOBRACE_,DOTILDE */
f = DOPAT | (f&DONTRUNCOMMAND) |

14
expr.c
View File

@ -2,7 +2,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.22 2008/12/17 19:39:21 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.23 2009/03/14 18:12:52 tg Exp $");
/* The order of these enums is constrained by the order of opinfo[] */
enum token {
@ -117,9 +117,9 @@ struct expr_state {
bool natural; /* unsigned arithmetic calculation */
};
#define bivui(x, op, y) (es->natural ? \
(long)((x)->val.u op (y)->val.u) : \
(long)((x)->val.i op (y)->val.i) \
#define bivui(x, op, y) (es->natural ? \
(mksh_ari_t)((x)->val.u op (y)->val.u) : \
(mksh_ari_t)((x)->val.i op (y)->val.i) \
)
#define chvui(x, op) do { \
if (es->natural) \
@ -152,7 +152,7 @@ static struct tbl *intvar(Expr_state *, struct tbl *);
* parse and evaluate expression
*/
int
evaluate(const char *expr, long int *rval, int error_ok, bool arith)
evaluate(const char *expr, mksh_ari_t *rval, int error_ok, bool arith)
{
struct tbl v;
int ret;
@ -284,7 +284,7 @@ evalexpr(Expr_state *es, int prec)
{
struct tbl *vl, *vr = NULL, *vasn;
enum token op;
long res = 0;
mksh_ari_t res = 0;
if (prec == P_PRIMARY) {
op = es->tok;
@ -542,7 +542,7 @@ static struct tbl *
do_ppmm(Expr_state *es, enum token op, struct tbl *vasn, bool is_prefix)
{
struct tbl *vl;
long oval;
mksh_ari_t oval;
assign_check(es, op, vasn);

10
funcs.c
View File

@ -5,7 +5,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.93 2008/12/13 17:02:14 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.94 2009/03/14 18:12:52 tg Exp $");
/* A leading = means assignments before command are kept;
* a leading * means a POSIX special builtin;
@ -1183,7 +1183,7 @@ int
c_let(const char **wp)
{
int rv = 1;
long val;
mksh_ari_t val;
if (wp[1] == NULL) /* at&t ksh does this */
bi_errorf("no arguments");
@ -1524,7 +1524,7 @@ c_shift(const char **wp)
{
struct block *l = e->loc;
int n;
long val;
mksh_ari_t val;
const char *arg;
if (ksh_getopt(wp, &builtin_opt, null) == '?')
@ -2533,7 +2533,7 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
int i, s;
size_t k;
struct stat b1, b2;
long v1, v2;
mksh_ari_t v1, v2;
if (!do_eval)
return 0;
@ -2965,7 +2965,7 @@ set_ulimit(const struct limits *l, const char *v, int how)
if (strcmp(v, "unlimited") == 0)
val = (rlim_t)RLIM_INFINITY;
else {
long rval;
mksh_ari_t rval;
if (!evaluate(v, &rval, KSH_RETURN_ERROR, false))
return (1);

12
main.c
View File

@ -13,7 +13,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.119 2008/12/29 21:34:20 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.120 2009/03/14 18:12:53 tg Exp $");
extern char **environ;
@ -32,8 +32,8 @@ static const char initsubs[] = "${PS2=> } ${PS3=#? } ${PS4=+ }";
static const char *initcoms[] = {
"typeset", "-r", initvsn, NULL,
"typeset", "-x", "SHELL", "PATH", "HOME", NULL,
"typeset", "-i10", "COLUMNS=0", "LINES=0", "OPTIND=1", "PGRP", "PPID",
"RANDOM", "USER_ID", NULL,
"typeset", "-i10", "COLUMNS=0", "LINES=0", "OPTIND=1", NULL,
"typeset", "-Ui10", "PGRP", "PPID", "RANDOM", "USER_ID", NULL,
"eval", "typeset -i10 SECONDS=\"${SECONDS-0}\" TMOUT=\"${TMOUT-0}\"",
NULL,
"alias", "integer=typeset -i", "local=typeset", NULL,
@ -250,9 +250,9 @@ main(int argc, const char *argv[])
(!ksheuid && !strchr(str_val(vp), '#')))
/* setstr can't fail here */
setstr(vp, safe_prompt, KSH_RETURN_ERROR);
setint(global("PGRP"), (long)(kshpgrp = getpgrp()));
setint(global("PPID"), (long)ppid);
setint(global("USER_ID"), (long)ksheuid);
setint(global("PGRP"), (mksh_uari_t)(kshpgrp = getpgrp()));
setint(global("PPID"), (mksh_uari_t)ppid);
setint(global("USER_ID"), (mksh_uari_t)ksheuid);
/* Set this before parsing arguments */
#if HAVE_SETRESUGID

4
misc.c
View File

@ -6,7 +6,7 @@
#include <grp.h>
#endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.96 2009/02/22 18:53:03 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.97 2009/03/14 18:12:53 tg Exp $");
#undef USE_CHVT
#if defined(TIOCSCTTY) && !defined(MKSH_SMALL)
@ -1390,6 +1390,8 @@ chvt(const char *fn)
#ifdef DEBUG
char longsizes_are_okay[sizeof (long) == sizeof (unsigned long) ? 1 : -1];
char arisize_is_okay[sizeof (mksh_ari_t) == 4 ? 1 : -1];
char uarisize_is_okay[sizeof (mksh_uari_t) == 4 ? 1 : -1];
char *
strchr(char *p, int ch)

22
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.149 2008/12/29 21:34:20 tg Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.150 2009/03/14 18:12:53 tg Exp $
.\" $OpenBSD: ksh.1,v 1.122 2008/05/17 23:31:52 sobrado Exp $
.\"-
.\" Try to make GNU groff and AT&T nroff more compatible
@ -30,7 +30,7 @@
.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
..
.\"-
.Dd $Mdocdate: December 29 2008 $
.Dd $Mdocdate: March 14 2009 $
.Dt MKSH 1
.Os MirBSD
.Sh NAME
@ -2098,11 +2098,12 @@ as numeric arguments to the
command, and as the value of an assignment to an integer parameter.
.Pp
Expressions are calculated using signed arithmetic and the
.Vt long
host type, unless they begin with a sole
.Vt mksh_ari_t
type (a 32-bit signed integer), unless they begin with a sole
.Sq #
character, in which case they use
.Vt unsigned long .
.Vt mksh_uari_t
.Po a 32-bit unsigned integer Pc .
.Pp
Expressions may contain alpha-numeric parameter identifiers, array references,
and integer constants and may be combined with the following C operators
@ -2139,10 +2140,13 @@ Grouping operators:
( )
.Ed
.Pp
Currently, integer constants and expressions are calculated using the host
.Vt long
type, although some places, such as array indices, may limit them to 32 bits.
They can be signed or unsigned.
Integer constants and expressions are calculated using the
.Vt mksh_ari_t
.Po if signed Pc
or
.Vt mksh_uari_t
.Po if unsigned Pc
type, and are limited to 32 bits.
Overflows wrap silently.
Integer constants may be specified with arbitrary bases using the notation
.Ar base Ns # Ns Ar number ,

20
sh.h
View File

@ -102,9 +102,9 @@
#define __SCCSID(x) __IDSTRING(sccsid,x)
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.274 2009/02/22 18:02:31 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.275 2009/03/14 18:12:54 tg Exp $");
#endif
#define MKSH_VERSION "R36 2009/02/22"
#define MKSH_VERSION "R36 2009/03/14"
#ifndef MKSH_INCLUDES_ONLY
@ -262,6 +262,10 @@ extern int __cdecl setegid(gid_t);
/* Table flag type - needs > 16 and < 32 bits */
typedef int32_t Tflag;
/* arithmetics types */
typedef int32_t mksh_ari_t;
typedef uint32_t mksh_uari_t;
/* these shall be smaller than 100 */
#ifdef MKSH_SMALL
#define NUFILE 32 /* Number of user-accessible files */
@ -775,8 +779,8 @@ struct tbl { /* table item */
Area *areap; /* area to allocate from */
union {
char *s; /* string */
long i; /* integer */
unsigned long u; /* unsigned integer */
mksh_ari_t i; /* integer */
mksh_uari_t u; /* unsigned integer */
int (*f)(const char **);/* int function */
struct op *t; /* "function" tree */
} val; /* value */
@ -1297,7 +1301,7 @@ int search_access(const char *, int, int *);
int pr_menu(const char *const *);
int pr_list(char *const *);
/* expr.c */
int evaluate(const char *, long *, int, bool);
int evaluate(const char *, mksh_ari_t *, int, bool);
int v_evaluate(struct tbl *, const char *, volatile int, bool);
/* funcs.c */
int c_hash(const char **);
@ -1528,11 +1532,11 @@ void initvar(void);
struct tbl *global(const char *);
struct tbl *local(const char *, bool);
char *str_val(struct tbl *);
long intval(struct tbl *);
mksh_ari_t intval(struct tbl *);
int setstr(struct tbl *, const char *, int);
struct tbl *setint_v(struct tbl *, struct tbl *, bool);
void setint(struct tbl *, long);
int getint(struct tbl *, long *, bool);
void setint(struct tbl *, mksh_ari_t);
int getint(struct tbl *, mksh_ari_t *, bool);
struct tbl *typeset(const char *, Tflag, Tflag, int, int);
void unset(struct tbl *, int);
const char *skip_varname(const char *, int);

16
shf.c
View File

@ -2,7 +2,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.24 2008/12/13 17:02:17 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.25 2009/03/14 18:12:55 tg Exp $");
/* flags to shf_emptybuf() */
#define EB_READSW 0x01 /* about to switch to reading */
@ -728,7 +728,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
int tmp = 0, field, precision, len, flags;
unsigned long lnum;
/* %#o produces the longest output */
char numbuf[(8 * sizeof(long) + 2) / 3 + 1];
char numbuf[(8 * sizeof (long) + 2) / 3 + 1];
/* this stuff for dealing with the buffer */
int nwritten = 0;
@ -847,18 +847,18 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
if (flags & FL_LONG)
lnum = va_arg(args, unsigned long);
else if ((sizeof (int) < sizeof (long)) && (c == 'd'))
lnum = (long) va_arg(args, int);
lnum = (long)va_arg(args, int);
else
lnum = va_arg(args, unsigned int);
switch (c) {
case 'd':
case 'i':
if (0 > (long) lnum)
lnum = - (long) lnum, tmp = 1;
else
if (0 > (long)lnum) {
lnum = -(long)lnum;
tmp = 1;
} else
tmp = 0;
/* aaahhhh..... */
/* FALLTHROUGH */
case 'u':
do {
*--cp = lnum % 10 + '0';

34
var.c
View File

@ -2,7 +2,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.68 2008/12/29 21:34:22 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.69 2009/03/14 18:12:55 tg Exp $");
/*
* Variables
@ -127,7 +127,7 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
p = skip_varname(n, false);
if (p != n && *p == '[' && (len = array_ref_len(p))) {
char *sub, *tmp;
long rval;
mksh_ari_t rval;
/* Calculate the value of the subscript */
*arrayp = true;
@ -284,17 +284,17 @@ str_val(struct tbl *vp)
s = vp->val.s + vp->type;
else { /* integer source */
/* worst case number length is when base=2, so use BITS(long) */
/* minus base # number null */
char strbuf[1 + 2 + 1 + 8 * sizeof(long) + 1];
/* minus base # number NUL */
char strbuf[1 + 2 + 1 + 8 * sizeof (mksh_uari_t) + 1];
const char *digits = (vp->flag & UCASEV_AL) ?
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" :
"0123456789abcdefghijklmnopqrstuvwxyz";
unsigned long n;
mksh_uari_t n;
int base;
s = strbuf + sizeof(strbuf);
if (vp->flag & INT_U)
n = (unsigned long) vp->val.i;
n = vp->val.u;
else
n = (vp->val.i < 0) ? -vp->val.i : vp->val.i;
base = (vp->type == 0) ? 10 : vp->type;
@ -333,17 +333,17 @@ str_val(struct tbl *vp)
}
/* get variable integer value, with error checking */
long
mksh_ari_t
intval(struct tbl *vp)
{
long num;
mksh_ari_t num;
int base;
base = getint(vp, &num, false);
if (base == -1)
/* XXX check calls - is error here ok by POSIX? */
errorf("%s: bad number", str_val(vp));
return num;
return (num);
}
/* set variable to string value */
@ -393,7 +393,7 @@ setstr(struct tbl *vq, const char *s, int error_ok)
/* set variable to integer */
void
setint(struct tbl *vq, long int n)
setint(struct tbl *vq, mksh_ari_t n)
{
if (!(vq->flag&INTEGER)) {
struct tbl *vp = &vtemp;
@ -411,12 +411,12 @@ setint(struct tbl *vq, long int n)
}
int
getint(struct tbl *vp, long int *nump, bool arith)
getint(struct tbl *vp, mksh_ari_t *nump, bool arith)
{
char *s;
int c, base, neg;
bool have_base = false;
long num;
mksh_ari_t num;
if (vp->flag&SPECIAL)
getspec(vp);
@ -460,7 +460,7 @@ getint(struct tbl *vp, long int *nump, bool arith)
wc = *(unsigned char *)s;
else if (utf_mbtowc(&wc, s) == (size_t)-1)
wc = 0xEF00 + *(unsigned char *)s;
*nump = (long)wc;
*nump = (mksh_ari_t)wc;
return (1);
}
num = 0;
@ -491,7 +491,7 @@ struct tbl *
setint_v(struct tbl *vq, struct tbl *vp, bool arith)
{
int base;
long num;
mksh_ari_t num;
if ((base = getint(vp, &num, arith)) == -1)
return NULL;
@ -1051,17 +1051,17 @@ getspec(struct tbl *vp)
break;
case V_HISTSIZE:
vp->flag &= ~SPECIAL;
setint(vp, (long)histsize);
setint(vp, (mksh_ari_t)histsize);
vp->flag |= SPECIAL;
break;
case V_OPTIND:
vp->flag &= ~SPECIAL;
setint(vp, (long)user_opt.uoptind);
setint(vp, (mksh_ari_t)user_opt.uoptind);
vp->flag |= SPECIAL;
break;
case V_LINENO:
vp->flag &= ~SPECIAL;
setint(vp, (long)current_lineno + user_lineno);
setint(vp, (mksh_ari_t)current_lineno + user_lineno);
vp->flag |= SPECIAL;
break;
case V_COLUMNS: