On 2018/04/03 20:08, Tobias Stoeckmann wrote:
> Hi,
> 
> this patch increases the number range on 32 bit architectures like
> i386 to 64 bit. These are already supported on 64 bit architectures
> due to using "long".
> 
> The rational behind this patch is to unify test/expr/ksh in allowing
> 64 bit integers, making variable handling more consistent in base
> tools.
> 
> Also, keep in mind that 32 bit architectures also support large files,
> so 64 bit file sizes in variables aren't totally out of the question.
> 
> When this is in, I want to merge the expr integer overflow checks
> into ksh.
> 
> Verification of this patch is rather easy on amd64, because binary
> does not change. I have extended regress tests to show that i386 can
> handle 64 bit integers.
> 
> My i386 system is running with this patch and nothing broke so far.

I don't know if there might be any hidden gotchas, but I have bumped
into this limitation a few times and very much support moving to a
64-bit type.

It is definitely needed before 2038 for timestamp calculations in
shell scripts.

> 
> Tobias
> 
> Index: bin/ksh/c_ksh.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/c_ksh.c,v
> retrieving revision 1.59
> diff -u -p -u -p -r1.59 c_ksh.c
> --- bin/ksh/c_ksh.c   15 Mar 2018 16:51:29 -0000      1.59
> +++ bin/ksh/c_ksh.c   3 Apr 2018 18:00:31 -0000
> @@ -1017,7 +1017,7 @@ int
>  c_let(char **wp)
>  {
>       int rv = 1;
> -     long val;
> +     int64_t val;
>  
>       if (wp[1] == NULL) /* at&t ksh does this */
>               bi_errorf("no arguments");
> Index: bin/ksh/c_sh.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/c_sh.c,v
> retrieving revision 1.62
> diff -u -p -u -p -r1.62 c_sh.c
> --- bin/ksh/c_sh.c    27 Dec 2017 13:02:57 -0000      1.62
> +++ bin/ksh/c_sh.c    3 Apr 2018 18:00:31 -0000
> @@ -33,7 +33,7 @@ c_shift(char **wp)
>  {
>       struct block *l = genv->loc;
>       int n;
> -     long val;
> +     int64_t val;
>       char *arg;
>  
>       if (ksh_getopt(wp, &builtin_opt, null) == '?')
> Index: bin/ksh/c_test.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/c_test.c,v
> retrieving revision 1.24
> diff -u -p -u -p -r1.24 c_test.c
> --- bin/ksh/c_test.c  26 Dec 2017 19:10:31 -0000      1.24
> +++ bin/ksh/c_test.c  3 Apr 2018 18:00:31 -0000
> @@ -308,7 +308,7 @@ test_eval(Test_env *te, Test_op op, cons
>       case TO_INTLE: /* -le */
>       case TO_INTLT: /* -lt */
>               {
> -                     long v1, v2;
> +                     int64_t v1, v2;
>  
>                       if (!evaluate(opnd1, &v1, KSH_RETURN_ERROR, false) ||
>                           !evaluate(opnd2, &v2, KSH_RETURN_ERROR, false)) {
> Index: bin/ksh/c_ulimit.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/c_ulimit.c,v
> retrieving revision 1.27
> diff -u -p -u -p -r1.27 c_ulimit.c
> --- bin/ksh/c_ulimit.c        15 Mar 2018 16:51:29 -0000      1.27
> +++ bin/ksh/c_ulimit.c        3 Apr 2018 18:00:31 -0000
> @@ -22,6 +22,7 @@
>  
>  #include <ctype.h>
>  #include <errno.h>
> +#include <inttypes.h>
>  #include <string.h>
>  
>  #include "sh.h"
> @@ -139,7 +140,7 @@ set_ulimit(const struct limits *l, const
>       if (strcmp(v, "unlimited") == 0)
>               val = RLIM_INFINITY;
>       else {
> -             long rval;
> +             int64_t rval;
>  
>               if (!evaluate(v, &rval, KSH_RETURN_ERROR, false))
>                       return 1;
> @@ -187,6 +188,6 @@ print_ulimit(const struct limits *l, int
>               shprintf("unlimited\n");
>       else {
>               val /= l->factor;
> -             shprintf("%ld\n", (long) val);
> +             shprintf("%" PRIi64 "\n", (int64_t) val);
>       }
>  }
> Index: bin/ksh/edit.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/edit.c,v
> retrieving revision 1.64
> diff -u -p -u -p -r1.64 edit.c
> --- bin/ksh/edit.c    15 Mar 2018 16:51:29 -0000      1.64
> +++ bin/ksh/edit.c    3 Apr 2018 18:00:31 -0000
> @@ -80,10 +80,10 @@ check_sigwinch(void)
>                                   ws.ws_col;
>  
>                               if ((vp = typeset("COLUMNS", 0, 0, 0, 0)))
> -                                     setint(vp, (long) ws.ws_col);
> +                                     setint(vp, (int64_t) ws.ws_col);
>                       }
>                       if (ws.ws_row && (vp = typeset("LINES", 0, 0, 0, 0)))
> -                             setint(vp, (long) ws.ws_row);
> +                             setint(vp, (int64_t) ws.ws_row);
>               }
>       }
>  }
> Index: bin/ksh/eval.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/eval.c,v
> retrieving revision 1.59
> diff -u -p -u -p -r1.59 eval.c
> --- bin/ksh/eval.c    16 Jan 2018 22:52:32 -0000      1.59
> +++ bin/ksh/eval.c    3 Apr 2018 18:00:31 -0000
> @@ -732,7 +732,7 @@ varsub(Expand *xp, char *sp, char *word,
>               if (Flag(FNOUNSET) && c == 0 && !zero_ok)
>                       errorf("%s: parameter not set", sp);
>               *stypep = 0; /* unqualified variable/string substitution */
> -             xp->str = str_save(ulton((unsigned long)c, 10), ATEMP);
> +             xp->str = str_save(u64ton((uint64_t)c, 10), ATEMP);
>               return XSUB;
>       }
>  
> Index: bin/ksh/expr.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/expr.c,v
> retrieving revision 1.32
> diff -u -p -u -p -r1.32 expr.c
> --- bin/ksh/expr.c    30 Dec 2015 09:07:00 -0000      1.32
> +++ bin/ksh/expr.c    3 Apr 2018 18:00:31 -0000
> @@ -148,7 +148,7 @@ static struct tbl *intvar(Expr_state *, 
>   * parse and evaluate expression
>   */
>  int
> -evaluate(const char *expr, long int *rval, int error_ok, bool arith)
> +evaluate(const char *expr, int64_t *rval, int error_ok, bool arith)
>  {
>       struct tbl v;
>       int ret;
> @@ -280,7 +280,7 @@ evalexpr(Expr_state *es, enum prec prec)
>  {
>       struct tbl *vl, *vr = NULL, *vasn;
>       enum token op;
> -     long res = 0;
> +     int64_t res = 0;
>  
>       if (prec == P_PRIMARY) {
>               op = es->tok;
> Index: bin/ksh/mail.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/mail.c,v
> retrieving revision 1.22
> diff -u -p -u -p -r1.22 mail.c
> --- bin/ksh/mail.c    19 Oct 2015 14:42:16 -0000      1.22
> +++ bin/ksh/mail.c    3 Apr 2018 18:00:31 -0000
> @@ -81,7 +81,7 @@ mcheck(void)
>  }
>  
>  void
> -mcset(long int interval)
> +mcset(int64_t interval)
>  {
>       mailcheck_interval = interval;
>  }
> Index: bin/ksh/main.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/main.c,v
> retrieving revision 1.90
> diff -u -p -u -p -r1.90 main.c
> --- bin/ksh/main.c    15 Mar 2018 16:51:29 -0000      1.90
> +++ bin/ksh/main.c    3 Apr 2018 18:00:31 -0000
> @@ -287,7 +287,7 @@ main(int argc, char *argv[])
>                       setstr(pwd_v, current_wd, KSH_RETURN_ERROR);
>       }
>       ppid = getppid();
> -     setint(global("PPID"), (long) ppid);
> +     setint(global("PPID"), (int64_t) ppid);
>       /* setstr can't fail here */
>       setstr(global(version_param), ksh_version, KSH_RETURN_ERROR);
>  
> Index: bin/ksh/misc.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/misc.c,v
> retrieving revision 1.69
> diff -u -p -u -p -r1.69 misc.c
> --- bin/ksh/misc.c    15 Mar 2018 16:51:29 -0000      1.69
> +++ bin/ksh/misc.c    3 Apr 2018 18:00:32 -0000
> @@ -56,10 +56,10 @@ initctypes(void)
>       setctypes(" \n\t\"#$&'()*;<>?[\\`|", C_QUOTE);
>  }
>  
> -/* convert unsigned long to base N string */
> +/* convert uint64_t to base N string */
>  
>  char *
> -ulton(long unsigned int n, int base)
> +u64ton(uint64_t n, int base)
>  {
>       char *p;
>       static char buf [20];
> Index: bin/ksh/sh.h
> ===================================================================
> RCS file: /cvs/src/bin/ksh/sh.h,v
> retrieving revision 1.71
> diff -u -p -u -p -r1.71 sh.h
> --- bin/ksh/sh.h      16 Jan 2018 22:52:32 -0000      1.71
> +++ bin/ksh/sh.h      3 Apr 2018 18:00:32 -0000
> @@ -440,7 +440,7 @@ int       search_access(const char *, int, int
>  int  pr_menu(char *const *);
>  int  pr_list(char *const *);
>  /* expr.c */
> -int  evaluate(const char *, long *, int, bool);
> +int  evaluate(const char *, int64_t *, int, bool);
>  int  v_evaluate(struct tbl *, const char *, volatile int, bool);
>  /* history.c */
>  void init_histvec(void);
> @@ -512,7 +512,7 @@ pid_t     j_async(void);
>  int  j_stopped_running(void);
>  /* mail.c */
>  void mcheck(void);
> -void mcset(long);
> +void mcset(int64_t);
>  void mbset(char *);
>  void mpset(char *);
>  /* main.c */
> @@ -527,7 +527,7 @@ void      cleanup_proc_env(void);
>  /* misc.c */
>  void setctypes(const char *, int);
>  void initctypes(void);
> -char *       ulton(unsigned long, int);
> +char *       u64ton(uint64_t, int);
>  char *       str_save(const char *, Area *);
>  char *       str_nsave(const char *, int, Area *);
>  int  option(const char *);
> @@ -583,11 +583,11 @@ void    initvar(void);
>  struct tbl * global(const char *);
>  struct tbl * local(const char *, bool);
>  char *       str_val(struct tbl *);
> -long intval(struct tbl *);
> +int64_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 *, int64_t);
> +int  getint(struct tbl *, int64_t *, bool);
>  struct tbl *typeset(const char *, int, int, int, int);
>  void unset(struct tbl *, int);
>  char  * skip_varname(const char *, int);
> Index: bin/ksh/table.h
> ===================================================================
> RCS file: /cvs/src/bin/ksh/table.h,v
> retrieving revision 1.13
> diff -u -p -u -p -r1.13 table.h
> --- bin/ksh/table.h   27 Dec 2017 13:02:57 -0000      1.13
> +++ bin/ksh/table.h   3 Apr 2018 18:00:32 -0000
> @@ -19,7 +19,7 @@ struct tbl {                        /* table item */
>       Area    *areap;         /* area to allocate from */
>       union {
>               char *s;        /* string */
> -             long i;         /* integer */
> +             int64_t i;      /* integer */
>               int (*f)(char **);      /* int function */
>               struct op *t;   /* "function" tree */
>       } val;                  /* value */
> Index: bin/ksh/tree.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/tree.c,v
> retrieving revision 1.33
> diff -u -p -u -p -r1.33 tree.c
> --- bin/ksh/tree.c    15 Mar 2018 16:51:29 -0000      1.33
> +++ bin/ksh/tree.c    3 Apr 2018 18:00:32 -0000
> @@ -365,7 +365,7 @@ vfptreef(struct shf *shf, int indent, co
>  
>       while ((c = *fmt++)) {
>               if (c == '%') {
> -                     long n;
> +                     int64_t n;
>                       char *p;
>                       int neg;
>  
> @@ -376,7 +376,7 @@ vfptreef(struct shf *shf, int indent, co
>                       case 'd': /* decimal */
>                               n = va_arg(va, int);
>                               neg = n < 0;
> -                             p = ulton(neg ? -n : n, 10);
> +                             p = u64ton(neg ? -n : n, 10);
>                               if (neg)
>                                       *--p = '-';
>                               while (*p)
> @@ -392,7 +392,7 @@ vfptreef(struct shf *shf, int indent, co
>                               tputS(p, shf);
>                               break;
>                       case 'u': /* unsigned decimal */
> -                             p = ulton(va_arg(va, unsigned int), 10);
> +                             p = u64ton(va_arg(va, unsigned int), 10);
>                               while (*p)
>                                       tputc(*p++, shf);
>                               break;
> Index: bin/ksh/var.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/var.c,v
> retrieving revision 1.66
> diff -u -p -u -p -r1.66 var.c
> --- bin/ksh/var.c     15 Mar 2018 16:51:29 -0000      1.66
> +++ bin/ksh/var.c     3 Apr 2018 18:00:32 -0000
> @@ -4,6 +4,7 @@
>  
>  #include <ctype.h>
>  #include <errno.h>
> +#include <inttypes.h>
>  #include <limits.h>
>  #include <stdlib.h>
>  #include <string.h>
> @@ -136,7 +137,7 @@ array_index_calc(const char *n, bool *ar
>       p = skip_varname(n, false);
>       if (p != n && *p == '[' && (len = array_ref_len(p))) {
>               char *sub, *tmp;
> -             long rval;
> +             int64_t rval;
>  
>               /* Calculate the value of the subscript */
>               *arrayp = true;
> @@ -146,7 +147,8 @@ array_index_calc(const char *n, bool *ar
>               n = str_nsave(n, p - n, ATEMP);
>               evaluate(sub, &rval, KSH_UNWIND_ERROR, true);
>               if (rval < 0 || rval > INT_MAX)
> -                     errorf("%s: subscript %ld out of range", n, rval);
> +                     errorf("%s: subscript %" PRIi64 " out of range",
> +                         n, rval);
>               *valp = rval;
>               afree(sub, ATEMP);
>       }
> @@ -295,18 +297,18 @@ str_val(struct tbl *vp)
>       else if (!(vp->flag&INTEGER))   /* string source */
>               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 + BITS(long) + 1];
> +             /* worst case number length is when base=2, so use
> +              * minus base # number BITS(int64_t) NUL */
> +             char strbuf[1 + 2 + 1 + BITS(int64_t) + 1];
>               const char *digits = (vp->flag & UCASEV_AL) ?
>                   "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" :
>                   "0123456789abcdefghijklmnopqrstuvwxyz";
> -             unsigned long n;
> +             uint64_t n;
>               unsigned int base;
>  
>               s = strbuf + sizeof(strbuf);
>               if (vp->flag & INT_U)
> -                     n = (unsigned long) vp->val.i;
> +                     n = (uint64_t) vp->val.i;
>               else
>                       n = (vp->val.i < 0) ? -vp->val.i : vp->val.i;
>               base = (vp->type == 0) ? 10 : vp->type;
> @@ -335,10 +337,10 @@ str_val(struct tbl *vp)
>  }
>  
>  /* get variable integer value, with error checking */
> -long
> +int64_t
>  intval(struct tbl *vp)
>  {
> -     long num;
> +     int64_t num;
>       int base;
>  
>       base = getint(vp, &num, false);
> @@ -393,7 +395,7 @@ setstr(struct tbl *vq, const char *s, in
>  
>  /* set variable to integer */
>  void
> -setint(struct tbl *vq, long int n)
> +setint(struct tbl *vq, int64_t n)
>  {
>       if (!(vq->flag&INTEGER)) {
>               struct tbl *vp = &vtemp;
> @@ -411,13 +413,13 @@ setint(struct tbl *vq, long int n)
>  }
>  
>  int
> -getint(struct tbl *vp, long int *nump, bool arith)
> +getint(struct tbl *vp, int64_t *nump, bool arith)
>  {
>       char *s;
>       int c;
>       int base, neg;
>       int have_base = 0;
> -     long num;
> +     int64_t num;
>  
>       if (vp->flag&SPECIAL)
>               getspec(vp);
> @@ -483,7 +485,7 @@ struct tbl *
>  setint_v(struct tbl *vq, struct tbl *vp, bool arith)
>  {
>       int base;
> -     long num;
> +     int64_t num;
>  
>       if ((base = getint(vp, &num, arith)) == -1)
>               return NULL;
> @@ -920,27 +922,27 @@ getspec(struct tbl *vp)
>                * (see initcoms[] in main.c).
>                */
>               if (vp->flag & ISSET)
> -                     setint(vp, (long)(time(NULL) - seconds)); /* XXX 2038 */
> +                     setint(vp, (int64_t)(time(NULL) - seconds));
>               vp->flag |= SPECIAL;
>               break;
>       case V_RANDOM:
>               vp->flag &= ~SPECIAL;
> -             setint(vp, (long) (rand() & 0x7fff));
> +             setint(vp, (int64_t) (rand() & 0x7fff));
>               vp->flag |= SPECIAL;
>               break;
>       case V_HISTSIZE:
>               vp->flag &= ~SPECIAL;
> -             setint(vp, (long) histsize);
> +             setint(vp, (int64_t) histsize);
>               vp->flag |= SPECIAL;
>               break;
>       case V_OPTIND:
>               vp->flag &= ~SPECIAL;
> -             setint(vp, (long) user_opt.uoptind);
> +             setint(vp, (int64_t) user_opt.uoptind);
>               vp->flag |= SPECIAL;
>               break;
>       case V_LINENO:
>               vp->flag &= ~SPECIAL;
> -             setint(vp, (long) current_lineno + user_lineno);
> +             setint(vp, (int64_t) current_lineno + user_lineno);
>               vp->flag |= SPECIAL;
>               break;
>       }
> @@ -1004,7 +1006,7 @@ setspec(struct tbl *vp)
>               break;
>       case V_COLUMNS:
>               {
> -                     long l;
> +                     int64_t l;
>  
>                       if (getint(vp, &l, false) == -1) {
>                               x_cols = MIN_COLS;
> @@ -1034,7 +1036,7 @@ setspec(struct tbl *vp)
>               break;
>       case V_SECONDS:
>               vp->flag &= ~SPECIAL;
> -             seconds = time(NULL) - intval(vp); /* XXX 2038 */
> +             seconds = time(NULL) - intval(vp);
>               vp->flag |= SPECIAL;
>               break;
>       case V_TMOUT:
> Index: regress/bin/ksh/integer.t
> ===================================================================
> RCS file: /cvs/src/regress/bin/ksh/integer.t,v
> retrieving revision 1.2
> diff -u -p -u -p -r1.2 integer.t
> --- regress/bin/ksh/integer.t 27 Sep 2016 15:35:34 -0000      1.2
> +++ regress/bin/ksh/integer.t 3 Apr 2018 18:00:32 -0000
> @@ -216,3 +216,14 @@ expected-stdout:
>       64
>  ---
>  
> +name: integer-1
> +description:
> +     Check that 64 bit integers get assigned
> +stdin:
> +     echo $(( zz = 0x7fffffffffffffff))
> +     echo $zz
> +expected-stdout:
> +     9223372036854775807
> +     9223372036854775807
> +---
> +
> 

Reply via email to