diff --git a/check.t b/check.t index 340ae2f..e0f33cc 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.480 2011/08/27 17:30:02 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.481 2011/08/27 18:06:38 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/07/26 + @(#)MIRBSD KSH R40 2011/08/27 description: Check version of shell. stdin: diff --git a/dot.mkshrc b/dot.mkshrc index 488e01e..518f031 100644 --- a/dot.mkshrc +++ b/dot.mkshrc @@ -1,5 +1,5 @@ # $Id$ -# $MirOS: src/bin/mksh/dot.mkshrc,v 1.64 2011/07/18 00:35:45 tg Exp $ +# $MirOS: src/bin/mksh/dot.mkshrc,v 1.65 2011/08/27 18:06:40 tg Exp $ #- # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 # Thorsten Glaser @@ -29,10 +29,11 @@ function precmd { (( e )) && print -n "$e|" } -PS1=' $(precmd)${USER:=$(ulimit -c 0;id -un 2>&-||print \?)}@${HOSTNAME%%.*}:$( - local d=${PWD:-?} n p=~; [[ $p = ?(*/) ]] || d=${d/#$p/~} - (( (${%d}>0 ? ${%d}: ${#d}) > (n = (COLUMNS/3<7 ? 7: COLUMNS/3)) )) && { - d=${d:(-n)}; p=...; } || p=; print -nr -- "$p$d") '"$PS1 " +PS1=$'\001\r''$(precmd)${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \? + )}@${HOSTNAME%%.*}:$(local d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || \ + d=${d/#$p/~}; local m=${%d} n p=...; (( m > 0 )) || m=${#d} + (( m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && d=${d:(-n)} || \ + p=; print -nr -- "$p$d") '"$PS1 " : ${MKSH:=$(whence -p mksh)}; export EDITOR HOSTNAME MKSH TERM USER alias ls=ls unalias ls diff --git a/edit.c b/edit.c index 5d818aa..2164ebe 100644 --- a/edit.c +++ b/edit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: edit.c,v 1.34 2010/05/20 01:13:07 fgsch Exp $ */ +;/* $OpenBSD: edit.c,v 1.34 2010/05/20 01:13:07 fgsch Exp $ */ /* $OpenBSD: edit.h,v 1.9 2011/05/30 17:14:35 martynas Exp $ */ /* $OpenBSD: emacs.c,v 1.43 2011/03/14 21:20:01 okan Exp $ */ /* $OpenBSD: vi.c,v 1.26 2009/06/29 22:50:19 martynas Exp $ */ @@ -25,7 +25,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.219 2011/07/16 18:15:45 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.220 2011/08/27 18:06:41 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -69,10 +69,10 @@ static char holdbuf[LINE]; /* place to hold last edit buffer */ static int x_getc(void); static void x_putcf(int); static void x_mode(bool); -static int x_do_comment(char *, int, int *); +static int x_do_comment(char *, ssize_t, ssize_t *); static void x_print_expansions(int, char *const *, bool); static int x_cf_glob(int *, const char *, int, int, int *, int *, char ***); -static int x_longest_prefix(int, char *const *); +static size_t x_longest_prefix(int, char *const *); static int x_basename(const char *, const char *); static void x_free_words(int, char **); static int x_escape(const char *, size_t, int (*)(const char *, size_t)); @@ -188,9 +188,9 @@ x_putcf(int c) * moved to the start of the line after (un)commenting. */ static int -x_do_comment(char *buf, int bsize, int *lenp) +x_do_comment(char *buf, ssize_t bsize, ssize_t *lenp) { - int i, j, len = *lenp; + ssize_t i, j, len = *lenp; if (len == 0) /* somewhat arbitrary - it's what AT&T ksh does */ @@ -607,10 +607,11 @@ x_cf_glob(int *flagsp, const char *buf, int buflen, int pos, int *startp, /* * Find longest common prefix */ -static int +static size_t x_longest_prefix(int nwords, char * const * words) { - int i, j, prefix_len; + int i; + size_t j, prefix_len; char *p; if (nwords <= 0) @@ -2212,7 +2213,7 @@ x_yank(int c MKSH_A_UNUSED) static int x_meta_yank(int c MKSH_A_UNUSED) { - int len; + size_t len; if ((x_last_command != XFUNC_yank && x_last_command != XFUNC_meta_yank) || killstack[killtp] == 0) { @@ -2907,7 +2908,7 @@ static int x_comment(int c MKSH_A_UNUSED) { int oldsize = x_size_str(xbuf); - int len = xep - xbuf; + ssize_t len = xep - xbuf; int ret = x_do_comment(xbuf, xend - xbuf, &len); if (ret < 0) @@ -2929,7 +2930,8 @@ x_version(int c MKSH_A_UNUSED) { char *o_xbuf = xbuf, *o_xend = xend; char *o_xbp = xbp, *o_xep = xep, *o_xcp = xcp; - int vlen, lim = x_lastcp() - xbp; + int lim = x_lastcp() - xbp; + size_t vlen; char *v; strdupx(v, KSH_VERSION, ATEMP); @@ -2945,7 +2947,7 @@ x_version(int c MKSH_A_UNUSED) xbp = o_xbp; xep = o_xep; xcp = o_xcp; - x_redraw(vlen); + x_redraw((int)vlen); if (c < 0) return (KSTD); @@ -3246,10 +3248,10 @@ x_mode(bool onoff) struct edstate { char *cbuf; - int winleft; - int cbufsize; - int linelen; - int cursor; + ssize_t winleft; + ssize_t cbufsize; + ssize_t linelen; + ssize_t cursor; }; static int vi_hook(int); @@ -3262,7 +3264,7 @@ static void yank_range(int, int); static int bracktype(int); static void save_cbuf(void); static void restore_cbuf(void); -static int putbuf(const char *, int, int); +static int putbuf(const char *, ssize_t, int); static void del_range(int, int); static int findch(int, int, int, int); static int forwword(int); @@ -3402,7 +3404,7 @@ static int state; struct macro_state { unsigned char *p; /* current position in buf */ unsigned char *buf; /* pointer to macro(s) being expanded */ - int len; /* how much data in buffer */ + size_t len; /* how much data in buffer */ }; static struct macro_state macro; @@ -4681,7 +4683,7 @@ x_vi_putbuf(const char *s, size_t len) } static int -putbuf(const char *buf, int len, int repl) +putbuf(const char *buf, ssize_t len, int repl) { if (len == 0) return (0); @@ -4907,7 +4909,7 @@ grabsearch(int save, int start, int fwd, char *pat) start--; anchored = *pat == '^' ? (++pat, 1) : 0; if ((hist = findhist(start, fwd, pat, anchored)) < 0) { - /* if (start != 0 && fwd && match(holdbuf, pat) >= 0) { */ + /* if (start != 0 && fwd && match(holdbuf, pat) >= 0) {} */ /* XXX should strcmp be strncmp? */ if (start != 0 && fwd && strcmp(holdbuf, pat) >= 0) { restore_cbuf(); @@ -5168,7 +5170,8 @@ static int complete_word(int cmd, int count) { static struct edstate *buf; - int rval, nwords, start, end, match_len, flags; + int rval, nwords, start, end, flags; + size_t match_len; char **words; char *match; bool is_unique; diff --git a/eval.c b/eval.c index e8097bc..bbb52f2 100644 --- a/eval.c +++ b/eval.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.106 2011/07/02 17:57:02 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.107 2011/08/27 18:06:42 tg Exp $"); /* * string expansion @@ -67,11 +67,11 @@ static char *tilde(char *); static char *homedir(char *); #endif static void alt_expand(XPtrV *, char *, char *, char *, int); -static size_t utflen(const char *); +static int utflen(const char *); static void utfincptr(const char *, mksh_ari_t *); /* UTFMODE functions */ -static size_t +static int utflen(const char *s) { size_t n; @@ -84,7 +84,10 @@ utflen(const char *s) } } else n = strlen(s); - return (n); + + if (n > 2147483647) + n = 2147483647; + return ((int)n); } static void @@ -581,8 +584,7 @@ expand(const char *cp, /* input word */ */ if (!Flag(FSH)) { *dp++ = MAGIC; - *dp++ = (char)('@' | - 0x80); + *dp++ = '@' | 0x80; } break; case '=': @@ -719,7 +721,7 @@ expand(const char *cp, /* input word */ /* open pattern: *(foo|bar) */ /* Next char is the type of pattern */ make_magic = 1; - c = *sp++ + 0x80; + c = *sp++ | 0x80; break; case SPAT: @@ -1474,8 +1476,7 @@ globit(XString *xs, /* dest string */ DIR *dirp; struct dirent *d; char *name; - int len; - int prefix_len; + size_t len, prefix_len; /* xp = *xpp; copy_non_glob() may have re-alloc'd xs */ *xp = '\0'; diff --git a/exec.c b/exec.c index 486df93..b04bfef 100644 --- a/exec.c +++ b/exec.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.94 2011/07/07 21:24:52 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.95 2011/08/27 18:06:43 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL "/bin/sh" @@ -51,7 +51,7 @@ execute(struct op * volatile t, int i; volatile int rv = 0, dummy = 0; int pv[2]; - const char ** volatile ap; + const char ** volatile ap = NULL; char ** volatile up; const char *s, *ccp; struct ioword **iowp; @@ -1215,7 +1215,7 @@ search(const char *name, const char *lpath, const char *sp, *p; char *xp; XString xs; - int namelen; + size_t namelen; if (errnop) *errnop = 0; @@ -1550,11 +1550,11 @@ struct select_menu_info { int num_width; }; -static char *select_fmt_entry(char *, int, int, const void *); +static char *select_fmt_entry(char *, size_t, int, const void *); /* format a single select menu item */ static char * -select_fmt_entry(char *buf, int buflen, int i, const void *arg) +select_fmt_entry(char *buf, size_t buflen, int i, const void *arg) { const struct select_menu_info *smi = (const struct select_menu_info *)arg; @@ -1572,7 +1572,8 @@ pr_menu(const char * const *ap) { struct select_menu_info smi; const char * const *pp; - int acols = 0, aocts = 0, i, n; + size_t acols = 0, aocts = 0, i; + int n; /* * width/column calculations were done once and saved, but this @@ -1609,10 +1610,10 @@ pr_menu(const char * const *ap) } /* XXX: horrible kludge to fit within the framework */ -static char *plain_fmt_entry(char *, int, int, const void *); +static char *plain_fmt_entry(char *, size_t, int, const void *); static char * -plain_fmt_entry(char *buf, int buflen, int i, const void *arg) +plain_fmt_entry(char *buf, size_t buflen, int i, const void *arg) { strlcpy(buf, ((const char * const *)arg)[i], buflen); return (buf); @@ -1621,7 +1622,8 @@ plain_fmt_entry(char *buf, int buflen, int i, const void *arg) int pr_list(char * const *ap) { - int acols = 0, aocts = 0, i, n; + size_t acols = 0, aocts = 0, i; + int n; char * const *pp; for (n = 0, pp = ap; *pp; n++, pp++) { diff --git a/expr.c b/expr.c index cb9c8db..04b5351 100644 --- a/expr.c +++ b/expr.c @@ -1,7 +1,7 @@ /* $OpenBSD: expr.c,v 1.21 2009/06/01 19:00:57 deraadt Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.47 2010/12/11 16:05:03 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.48 2011/08/27 18:06:44 tg Exp $"); /* The order of these enums is constrained by the order of opinfo[] */ enum token { @@ -141,12 +141,6 @@ struct expr_state { (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) \ - (x)->val.u = op (x)->val.u; \ - else \ - (x)->val.i = op (x)->val.i; \ -} while (/* CONSTCOND */ 0) #define stvui(x, n) do { \ if (es->natural) \ (x)->val.u = (n); \ @@ -315,11 +309,11 @@ evalexpr(Expr_state *es, int prec) exprtoken(es); vl = intvar(es, evalexpr(es, P_PRIMARY)); if (op == O_BNOT) - chvui(vl, ~); + vl->val.i = ~vl->val.i; else if (op == O_LNOT) - chvui(vl, !); + vl->val.i = !vl->val.i; else if (op == O_MINUS) - chvui(vl, -); + vl->val.i = -vl->val.i; /* op == O_PLUS is a no-op */ } else if (op == OPEN_PAREN) { exprtoken(es); @@ -505,7 +499,7 @@ exprtoken(Expr_state *es) for (; ksh_isalnux(c); c = *cp) cp++; if (c == '[') { - int len; + size_t len; len = array_ref_len(cp); if (len == 0) @@ -682,12 +676,12 @@ utf_widthadj(const char *src, const char **dst) return (width); } -int +size_t utf_mbswidth(const char *s) { - size_t len; + size_t len, width = 0; unsigned int wc; - int width = 0, cw; + int cw; if (!UTFMODE) return (strlen(s)); diff --git a/funcs.c b/funcs.c index 9eb61a8..5f8f991 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.195 2011/08/27 17:30:04 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.196 2011/08/27 18:06:44 tg Exp $"); #if HAVE_KILLPG /* @@ -213,7 +213,7 @@ static int test_primary(Test_env *, bool); static Test_op ptest_isa(Test_env *, Test_meta); static const char *ptest_getopnd(Test_env *, Test_op, bool); static void ptest_error(Test_env *, int, const char *); -static char *kill_fmt_entry(char *, int, int, const void *); +static char *kill_fmt_entry(char *, size_t, int, const void *); static void p_time(struct shf *, bool, long, int, int, const char *, const char *) MKSH_A_NONNULL((__nonnull__ (6, 7))); @@ -401,8 +401,7 @@ c_print(const char **wp) /* generic function returned Unicode */ char ts[4]; - c = utf_wctomb(ts, c - 0x100); - ts[c] = 0; + ts[utf_wctomb(ts, c - 0x100)] = 0; for (c = 0; ts[c]; ++c) Xput(xs, xp, ts[c]); continue; @@ -1258,7 +1257,7 @@ c_fgbg(const char **wp) /* format a single kill item */ static char * -kill_fmt_entry(char *buf, int buflen, int i, const void *arg) +kill_fmt_entry(char *buf, size_t buflen, int i, const void *arg) { const struct kill_info *ki = (const struct kill_info *)arg; @@ -1329,7 +1328,8 @@ c_kill(const char **wp) shprintf("%d\n", n); } } else { - int w, j, mess_cols, mess_octs; + ssize_t w, mess_cols, mess_octs; + int j; struct kill_info ki; for (j = NSIG, ki.num_width = 1; j >= 10; j /= 10) diff --git a/histrap.c b/histrap.c index 8edd843..5677ba9 100644 --- a/histrap.c +++ b/histrap.c @@ -26,7 +26,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.109 2011/04/22 12:21:53 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.110 2011/08/27 18:06:45 tg Exp $"); /*- * MirOS: This is the default mapping type, and need not be specified. @@ -63,7 +63,7 @@ static Source *hist_source; /* current history file: name, fd, size */ static char *hname; static int histfd; -static int hsize; +static size_t hsize; #endif static const char T_not_in_history[] = "not in history"; @@ -365,9 +365,9 @@ hist_replace(char **hp, const char *pat, const char *rep, bool globr) strdupx(line, *hp, ATEMP); else { char *s, *s1; - int pat_len = strlen(pat); - int rep_len = strlen(rep); - int len; + size_t pat_len = strlen(pat); + size_t rep_len = strlen(rep); + size_t len; XString xs; char *xp; bool any_subst = false; @@ -509,10 +509,10 @@ histnum(int n) int findhist(int start, int fwd, const char *str, int anchored) { - char **hp; - int maxhist = histptr - history; - int incr = fwd ? 1 : -1; - int len = strlen(str); + char **hp; + int maxhist = histptr - history; + int incr = fwd ? 1 : -1; + size_t len = strlen(str); if (start < 0 || start >= maxhist) start = maxhist; @@ -700,6 +700,7 @@ hist_init(Source *s) #if HAVE_PERSISTENT_HISTORY unsigned char *base; int lines, fd, rv = 0; + off_t hfsize; #endif if (Flag(FTALKING) == 0) @@ -725,7 +726,10 @@ hist_init(Source *s) (void)flock(histfd, LOCK_EX); - hsize = lseek(histfd, (off_t)0, SEEK_END); + hfsize = lseek(histfd, (off_t)0, SEEK_END); + hsize = 1024 * 1048576; + if (hfsize < (off_t)hsize) + hsize = (size_t)hfsize; if (hsize == 0) { /* add magic */ @@ -774,7 +778,10 @@ hist_init(Source *s) munmap((caddr_t)base, hsize); } (void)flock(histfd, LOCK_UN); - hsize = lseek(histfd, (off_t)0, SEEK_END); + hfsize = lseek(histfd, (off_t)0, SEEK_END); + hsize = 1024 * 1048576; + if (hfsize < (off_t)hsize) + hsize = hfsize; #endif } @@ -970,36 +977,34 @@ histinsert(Source *s, int lno, const char *line) static void writehistfile(int lno, char *cmd) { - int sizenow; - unsigned char *base; - unsigned char *news; - int bytes; - unsigned char hdr[5]; + off_t sizenow; + ssize_t bytes; + unsigned char *base, *news, hdr[5]; (void)flock(histfd, LOCK_EX); sizenow = lseek(histfd, (off_t)0, SEEK_END); - if (sizenow != hsize) { + if ((sizenow <= (1024 * 1048576)) && ((size_t)sizenow != hsize)) { /* * Things have changed */ - if (sizenow > hsize) { + if ((size_t)sizenow > hsize) { /* someone has added some lines */ - bytes = sizenow - hsize; - base = (void *)mmap(NULL, sizenow, PROT_READ, + bytes = (size_t)sizenow - hsize; + base = (void *)mmap(NULL, (size_t)sizenow, PROT_READ, MAP_FILE | MAP_PRIVATE, histfd, (off_t)0); if (base == (unsigned char *)MAP_FAILED) goto bad; news = base + hsize; if (*news != COMMAND) { - munmap((caddr_t)base, sizenow); + munmap((caddr_t)base, (size_t)sizenow); goto bad; } hist_source->line--; histload(hist_source, news, bytes); hist_source->line++; lno = hist_source->line; - munmap((caddr_t)base, sizenow); - hsize = sizenow; + munmap((caddr_t)base, (size_t)sizenow); + hsize = (size_t)sizenow; } else { /* it has shrunk */ /* but to what? */ @@ -1020,7 +1025,10 @@ writehistfile(int lno, char *cmd) if ((write(histfd, hdr, 5) != 5) || (write(histfd, cmd, bytes) != bytes)) goto bad; - hsize = lseek(histfd, (off_t)0, SEEK_END); + sizenow = lseek(histfd, (off_t)0, SEEK_END); + hsize = 1024 * 1048576; + if (sizenow < (off_t)hsize) + hsize = (size_t)sizenow; } (void)flock(histfd, LOCK_UN); return; diff --git a/jobs.c b/jobs.c index 4b58a92..0b5df4e 100644 --- a/jobs.c +++ b/jobs.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.80 2011/07/16 23:37:58 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.81 2011/08/27 18:06:46 tg Exp $"); #if HAVE_KILLPG #define mksh_killpg killpg @@ -1059,7 +1059,7 @@ j_waitj(Job *j, int flags, const char *where) { - int rv; + int rv; /* * No auto-notify on the job we are waiting on. @@ -1177,7 +1177,7 @@ j_waitj(Job *j, rv = j->status; if ((flags & JW_PIPEST) && (j->proc_list != NULL)) { - size_t num = 0; + uint32_t num = 0; Proc *p = j->proc_list; struct tbl *vp; @@ -1542,9 +1542,10 @@ j_print(Job *j, int how, struct shf *shf) static Job * j_lookup(const char *cp, int *ecodep) { - Job *j, *last_match; - Proc *p; - int len, job = 0; + Job *j, *last_match; + Proc *p; + size_t len; + int job = 0; if (ksh_isdigit(*cp)) { getn(cp, &job); diff --git a/lalloc.c b/lalloc.c index f32d600..d5e6ebb 100644 --- a/lalloc.c +++ b/lalloc.c @@ -20,7 +20,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.17 2011/03/13 10:50:44 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.18 2011/08/27 18:06:47 tg Exp $"); /* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */ #if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0) @@ -62,13 +62,12 @@ findptr(ALLOC_ITEM **lpp, char *ptr, Area *ap) fail: #endif #ifdef DEBUG - internal_warningf("rogue pointer %lX in ap %lX", - (long)(ptrdiff_t)ptr, (long)(ptrdiff_t)ap); + internal_warningf("rogue pointer %zX in ap %zX", + (size_t)ptr, (size_t)ap); /* try to get a coredump */ abort(); #else - internal_errorf("rogue pointer %lX", - (long)(ptrdiff_t)ptr); + internal_errorf("rogue pointer %zX", (size_t)ptr); #endif } return (ap); @@ -78,8 +77,7 @@ void * aresize2(void *ptr, size_t fac1, size_t fac2, Area *ap) { if (notoktomul(fac1, fac2)) - internal_errorf(T_intovfl, (unsigned long)fac1, '*', - (unsigned long)fac2); + internal_errorf(T_intovfl, fac1, '*', fac2); return (aresize(ptr, fac1 * fac2, ap)); } diff --git a/lex.c b/lex.c index 4ade37e..982b283 100644 --- a/lex.c +++ b/lex.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.154 2011/07/26 16:57:27 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.155 2011/08/27 18:06:47 tg Exp $"); /* * states while lexing word @@ -197,6 +197,7 @@ yylex(int cf) Lex_state states[STATE_BSIZE], *statep, *s2, *base; State_info state_info; int c, c2, state; + size_t cz; XString ws; /* expandable output word */ char *wp; /* output word pointer */ char *sp, *dp; @@ -394,11 +395,11 @@ yylex(int cf) ungetsc(c); subst_command: sp = yyrecursive(); - c2 = strlen(sp) + 1; - XcheckN(ws, wp, c2); + cz = strlen(sp) + 1; + XcheckN(ws, wp, cz); *wp++ = COMSUB; - memcpy(wp, sp, c2); - wp += c2; + memcpy(wp, sp, cz); + wp += cz; } } else if (c == '{') /*}*/ { *wp++ = OSUBST; @@ -580,11 +581,11 @@ yylex(int cf) *wp++ = QCHAR; *wp++ = c2; } else { - c = utf_wctomb(ts, c2 - 0x100); - ts[c] = 0; - for (c = 0; ts[c]; ++c) { + cz = utf_wctomb(ts, c2 - 0x100); + ts[cz] = 0; + for (cz = 0; ts[cz]; ++cz) { *wp++ = QCHAR; - *wp++ = ts[c]; + *wp++ = ts[cz]; } } } @@ -625,10 +626,10 @@ yylex(int cf) POP_STATE(); if ((c2 = getsc()) == /*(*/ ')') { - c = strlen(sp) - 2; - XcheckN(ws, wp, c); - memcpy(wp, sp + 1, c); - wp += c; + cz = strlen(sp) - 2; + XcheckN(ws, wp, cz); + memcpy(wp, sp + 1, cz); + wp += cz; afree(sp, ATEMP); *wp++ = '\0'; break; @@ -1138,9 +1139,9 @@ readhere(struct ioword *iop) if (iop->flag & IOHERESTR) { /* process the here string */ iop->heredoc = xp = evalstr(iop->delim, DOBLANK); - c = strlen(xp) - 1; - memmove(xp, xp + 1, c); - xp[c] = '\n'; + xpos = strlen(xp) - 1; + memmove(xp, xp + 1, xpos); + xp[xpos] = '\n'; return; } diff --git a/main.c b/main.c index 5aa4cd6..a4323c8 100644 --- a/main.c +++ b/main.c @@ -33,7 +33,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.197 2011/08/27 17:30:06 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.198 2011/08/27 18:06:48 tg Exp $"); extern char **environ; @@ -377,6 +377,44 @@ main(int argc, const char *argv[]) return (1); } +#ifdef DEBUG + /* test wraparound of arithmetic types */ + { + volatile long xl; + volatile unsigned long xul; + volatile int xi; + volatile unsigned int xui; + volatile mksh_ari_t xa; + volatile mksh_uari_t xua, xua2; + volatile uint8_t xc; + + xa = 2147483647; + xua = 2147483647; + ++xa; + ++xua; + xua2 = xa; + xl = xa; + xul = xua; + xa = 0; + xua = 0; + --xa; + --xua; + xi = xa; + xui = xua; + xa = -1; + xua = xa; + ++xa; + ++xua; + xc = 0; + --xc; + if ((xua2 != 2147483648UL) || + (xl != -2147483648L) || (xul != 2147483648UL) || + (xi != -1) || (xui != 4294967295U) || + (xa != 0) || (xua != 0) || (xc != 255)) + errorf("integer wraparound test failed"); + } +#endif + /* process this later only, default to off (hysterical raisins) */ utf_flag = UTFMODE; UTFMODE = 0; @@ -561,6 +599,7 @@ main(int argc, const char *argv[]) /* doesn't return */ shell(s, true); + /* NOTREACHED */ return (0); } @@ -1395,7 +1434,7 @@ struct temp * maketemp(Area *ap, Temp_type type, struct temp **tlist) { struct temp *tp; - int len; + size_t len; int fd; char *pathname; const char *dir; @@ -1457,7 +1496,7 @@ tgrow(struct table *tp) internal_errorf("hash table size limit reached"); /* calculate old size, new shift and new size */ - osize = 1 << (tp->tshift++); + osize = (size_t)1 << (tp->tshift++); i = osize << 1; ntblp = alloc2(i, sizeof(struct tbl *), tp->areap); @@ -1511,7 +1550,7 @@ ktscan(struct table *tp, const char *name, uint32_t h, struct tbl ***ppp) size_t j, perturb, mask; struct tbl **pp, *p; - mask = (1 << (tp->tshift)) - 1; + mask = ((size_t)1 << (tp->tshift)) - 1; /* search for hash table slot matching name */ j = (perturb = h) & mask; goto find_first_slot; @@ -1567,7 +1606,7 @@ ktenter(struct table *tp, const char *n, uint32_t h) void ktwalk(struct tstate *ts, struct table *tp) { - ts->left = 1 << (tp->tshift); + ts->left = (size_t)1 << (tp->tshift); ts->next = tp->tbls; } @@ -1601,7 +1640,7 @@ ktsort(struct table *tp) * since the table is never entirely full, no need to reserve * additional space for the trailing NULL appended below */ - i = 1 << (tp->tshift); + i = (size_t)1 << (tp->tshift); p = alloc2(i, sizeof(struct tbl *), ATEMP); sp = tp->tbls; /* source */ dp = p; /* dest */ diff --git a/misc.c b/misc.c index f24473e..e503738 100644 --- a/misc.c +++ b/misc.c @@ -29,7 +29,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.170 2011/08/27 17:30:07 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.171 2011/08/27 18:06:49 tg Exp $"); /* type bits for unsigned char */ unsigned char chtypes[UCHAR_MAX + 1]; @@ -141,12 +141,12 @@ struct options_info { int opts[NELEM(options)]; }; -static char *options_fmt_entry(char *, int, int, const void *); +static char *options_fmt_entry(char *, size_t, int, const void *); static void printoptions(bool); /* format a single select menu item */ static char * -options_fmt_entry(char *buf, int buflen, int i, const void *arg) +options_fmt_entry(char *buf, size_t buflen, int i, const void *arg) { const struct options_info *oi = (const struct options_info *)arg; @@ -159,17 +159,17 @@ options_fmt_entry(char *buf, int buflen, int i, const void *arg) static void printoptions(bool verbose) { - int i = 0; + size_t i = 0; if (verbose) { - int n = 0, len, octs = 0; + ssize_t n = 0, len, octs = 0; struct options_info oi; /* verbose version */ shf_puts("Current option settings\n", shl_stdout); oi.opt_width = 0; - while (i < (int)NELEM(options)) { + while (i < NELEM(options)) { if (options[i].name) { oi.opts[n++] = i; len = strlen(options[i].name); @@ -199,7 +199,7 @@ printoptions(bool verbose) char * getoptions(void) { - unsigned int i; + size_t i; char m[(int)FNFLAGS + 1]; char *cp = m; @@ -1073,10 +1073,10 @@ print_value_quoted(const char *s) */ void print_columns(struct shf *shf, int n, - char *(*func)(char *, int, int, const void *), - const void *arg, int max_oct, int max_col, bool prefcol) + char *(*func)(char *, size_t, int, const void *), + const void *arg, size_t max_oct, size_t max_col_, bool prefcol) { - int i, r, c, rows, cols, nspace; + int i, r, c, rows, cols, nspace, max_col; char *str; if (n <= 0) { @@ -1086,6 +1086,14 @@ print_columns(struct shf *shf, int n, return; } + if (max_col_ > 2147483647) { +#ifndef MKSH_SMALL + internal_warningf("print_columns called with max_col=%zu > INT_MAX", max_col_); +#endif + return; + } + max_col = (int)max_col_; + ++max_oct; str = alloc(max_oct, ATEMP); @@ -1449,7 +1457,7 @@ make_path(const char *cwd, const char *file, int rval = 0; bool use_cdpath = true; char *plist; - int len, plen = 0; + size_t len, plen = 0; char *xp = Xstring(*xsp, xp); if (!file) @@ -1877,12 +1885,18 @@ chvt(const char *fn) #endif #ifdef DEBUG -char intsize_is_okay[sizeof(int) >= 4 ? 1 : -1]; -char intsizes_are_okay[sizeof(int) == sizeof(unsigned int) ? 1 : -1]; -char longsize_is_okay[sizeof(long) >= sizeof(int) ? 1 : -1]; -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]; +#define assert_eq(name, a, b) char name[a == b ? 1 : -1] +#define assert_ge(name, a, b) char name[a >= b ? 1 : -1] +assert_ge(intsize_is_okay, sizeof(int), 4); +assert_eq(intsizes_are_okay, sizeof(int), sizeof(unsigned int)); +assert_ge(longsize_is_okay, sizeof(long), sizeof(int)); +assert_eq(arisize_is_okay, sizeof(mksh_ari_t), 4); +assert_eq(uarisize_is_okay, sizeof(mksh_uari_t), 4); +assert_eq(sizesizes_are_okay, sizeof(size_t), sizeof(ssize_t)); +assert_eq(ptrsizes_are_okay, sizeof(ptrdiff_t), sizeof(void *)); +assert_eq(ptrsize_is_sizet, sizeof(ptrdiff_t), sizeof(size_t)); +/* formatting routines assume this */ +assert_ge(ptr_fits_in_long, sizeof(long), sizeof(size_t)); char * strchr(char *p, int ch) diff --git a/sh.h b/sh.h index cd16803..bbdec8d 100644 --- a/sh.h +++ b/sh.h @@ -151,9 +151,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.492 2011/08/27 17:30:07 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.493 2011/08/27 18:06:50 tg Exp $"); #endif -#define MKSH_VERSION "R40 2011/07/26" +#define MKSH_VERSION "R40 2011/08/27" #ifndef MKSH_INCLUDES_ONLY @@ -654,7 +654,7 @@ extern const struct shoption options[]; /* null value for variable; comparison pointer for unset */ EXTERN char null[] I__(""); /* helpers for string pooling */ -EXTERN const char T_intovfl[] I__("integer overflow %lu %c %lu prevented"); +EXTERN const char T_intovfl[] I__("integer overflow %zu %c %zu prevented"); EXTERN const char T_oomem[] I__("can't allocate %lu data bytes"); #if defined(__GNUC__) /* trust this to have string pooling; -Wformat bitches otherwise */ @@ -804,6 +804,10 @@ EXTERN int ifs0 I__(' '); /* for "$*" */ #define GI_PLUS BIT(1) /* an option started with +... */ #define GI_MINUSMINUS BIT(2) /* arguments were ended with -- */ +/* in case some OS defines these */ +#undef optarg +#undef optind + typedef struct { const char *optarg; int optind; @@ -930,14 +934,14 @@ struct shf { unsigned char *rp; /* read: current position in buffer */ unsigned char *wp; /* write: current position in buffer */ unsigned char *buf; /* buffer */ + ssize_t bsize; /* actual size of buf */ + ssize_t rbsize; /* size of buffer (1 if SHF_UNBUF) */ + ssize_t rnleft; /* read: how much data left in buffer */ + ssize_t wbsize; /* size of buffer (0 if SHF_UNBUF) */ + ssize_t wnleft; /* write: how much space left in buffer */ int flags; /* see SHF_* */ - int rbsize; /* size of buffer (1 if SHF_UNBUF) */ - int rnleft; /* read: how much data left in buffer */ - int wbsize; /* size of buffer (0 if SHF_UNBUF) */ - int wnleft; /* write: how much space left in buffer */ int fd; /* file descriptor */ int errno_; /* saved value of errno after error */ - int bsize; /* actual size of buf */ }; extern struct shf shf_iob[]; @@ -945,7 +949,7 @@ extern struct shf shf_iob[]; struct table { Area *areap; /* area to allocate entries */ struct tbl **tbls; /* hashed table items */ - uint32_t nfree; /* free table entries */ + size_t nfree; /* free table entries */ uint8_t tshift; /* table size (2^tshift) */ }; @@ -1291,9 +1295,9 @@ typedef char *XStringP; /* check if there are at least n bytes left */ #define XcheckN(xs, xp, n) do { \ - int more = ((xp) + (n)) - (xs).end; \ + ssize_t more = ((xp) + (n)) - (xs).end; \ if (more > 0) \ - (xp) = Xcheck_grow_(&(xs), (xp), (size_t)more); \ + (xp) = Xcheck_grow_(&(xs), (xp), more); \ } while (/* CONSTCOND */ 0) /* check for overflow, expand string */ @@ -1449,9 +1453,9 @@ typedef union { #define UNCTRL(x) ((x) ^ 0x40) /* ASCII */ EXTERN Source *source; /* yyparse/yylex source */ -EXTERN YYSTYPE yylval; /* result from yylex */ -EXTERN struct ioword *heres [HERES], **herep; -EXTERN char ident [IDENT+1]; +EXTERN YYSTYPE yylval; /* result from yylex */ +EXTERN struct ioword *heres[HERES], **herep; +EXTERN char ident[IDENT+1]; #define HISTORYSIZE 500 /* size of saved history */ @@ -1467,8 +1471,8 @@ 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, (unsigned long)(val), \ - '+', (unsigned long)(cnst)); \ + internal_errorf(T_intovfl, (size_t)(val), \ + '+', (size_t)(cnst)); \ } while (/* CONSTCOND */ 0) @@ -1568,7 +1572,7 @@ int v_evaluate(struct tbl *, const char *, volatile int, bool); size_t utf_mbtowc(unsigned int *, const char *); size_t utf_wctomb(char *, unsigned int); int utf_widthadj(const char *, const char **); -int utf_mbswidth(const char *); +size_t utf_mbswidth(const char *); const char *utf_skipcols(const char *, int); size_t utf_ptradj(const char *); #ifndef MKSH_mirbsd_wcwidth @@ -1756,8 +1760,8 @@ int ksh_getopt(const char **, Getopt *, const char *); void print_value_quoted(const char *); char *quote_value(const char *); void print_columns(struct shf *, int, - char *(*)(char *, int, int, const void *), - const void *, int, int, bool); + char *(*)(char *, size_t, int, const void *), + const void *, size_t, size_t, bool); void strip_nuls(char *, int); ssize_t blocking_read(int, char *, size_t) MKSH_A_BOUNDED(__buffer__, 2, 3); @@ -1776,13 +1780,13 @@ int unbksl(bool, int (*)(void), void (*)(int)); struct shf *shf_open(const char *, int, int, int); struct shf *shf_fdopen(int, int, struct shf *); struct shf *shf_reopen(int, int, struct shf *); -struct shf *shf_sopen(char *, int, int, struct shf *); +struct shf *shf_sopen(char *, ssize_t, int, struct shf *); int shf_close(struct shf *); int shf_fdclose(struct shf *); char *shf_sclose(struct shf *); int shf_flush(struct shf *); -int shf_read(char *, int, struct shf *); -char *shf_getse(char *, int, struct shf *); +ssize_t shf_read(char *, ssize_t, struct shf *); +char *shf_getse(char *, ssize_t, struct shf *); int shf_getchar(struct shf *s); int shf_ungetc(int, struct shf *); #ifdef MKSH_SMALL @@ -1793,16 +1797,16 @@ int shf_putc(int, struct shf *); #define shf_putc shf_putc_ #endif int shf_putchar(int, struct shf *); -int shf_puts(const char *, struct shf *); -int shf_write(const char *, int, struct shf *); -int shf_fprintf(struct shf *, const char *, ...) +ssize_t shf_puts(const char *, struct shf *); +ssize_t shf_write(const char *, ssize_t, struct shf *); +ssize_t shf_fprintf(struct shf *, const char *, ...) MKSH_A_FORMAT(__printf__, 2, 3); -int shf_snprintf(char *, int, const char *, ...) +ssize_t shf_snprintf(char *, ssize_t, const char *, ...) MKSH_A_FORMAT(__printf__, 3, 4) MKSH_A_BOUNDED(__string__, 1, 2); char *shf_smprintf(const char *, ...) MKSH_A_FORMAT(__printf__, 1, 2); -int shf_vfprintf(struct shf *, const char *, va_list) +ssize_t shf_vfprintf(struct shf *, const char *, va_list) MKSH_A_FORMAT(__printf__, 2, 0); /* syn.c */ void initkeywords(void); @@ -1811,7 +1815,7 @@ bool parse_usec(const char *, struct timeval *); char *yyrecursive(void); /* tree.c */ void fptreef(struct shf *, int, const char *, ...); -char *snptreef(char *, int, const char *, ...); +char *snptreef(char *, ssize_t, const char *, ...); struct op *tcopy(struct op *, Area *); char *wdcopy(const char *, Area *); const char *wdscan(const char *, int); @@ -1847,7 +1851,7 @@ int is_wdvarassign(const char *); struct tbl *arraysearch(struct tbl *, uint32_t); char **makenv(void); void change_winsz(void); -int array_ref_len(const char *); +size_t array_ref_len(const char *); char *arrayname(const char *); mksh_uari_t set_array(const char *, bool, const char **); uint32_t hash(const void *); diff --git a/shf.c b/shf.c index 4e7b46f..30bd2d2 100644 --- a/shf.c +++ b/shf.c @@ -1,7 +1,7 @@ /* $OpenBSD: shf.c,v 1.15 2006/04/02 00:48:33 deraadt Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -19,12 +19,12 @@ * damage or existence of a defect, except proven that it results out * of said person's immediate fault when using the work as intended. *- - * Use %lX instead of %p and floating point isn't supported at all. + * Use %zX instead of %p and floating point isn't supported at all. */ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.42 2011/07/16 17:07:35 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.43 2011/08/27 18:06:51 tg Exp $"); /* flags to shf_emptybuf() */ #define EB_READSW 0x01 /* about to switch to reading */ @@ -39,7 +39,8 @@ __RCSID("$MirOS: src/bin/mksh/shf.c,v 1.42 2011/07/16 17:07:35 tg Exp $"); static int shf_fillbuf(struct shf *); static int shf_emptybuf(struct shf *, int); -/* Open a file. First three args are for open(), last arg is flags for +/* + * Open a file. First three args are for open(), last arg is flags for * this package. Returns NULL if file could not be opened, or if a dup * fails. */ @@ -47,7 +48,8 @@ struct shf * shf_open(const char *name, int oflags, int mode, int sflags) { struct shf *shf; - int bsize = /* at most 512 */ + ssize_t bsize = + /* at most 512 */ sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE; int fd; @@ -82,12 +84,11 @@ shf_open(const char *name, int oflags, int mode, int sflags) return (shf_reopen(fd, sflags, shf)); } -/* Set up the shf structure for a file descriptor. Doesn't fail. */ -struct shf * -shf_fdopen(int fd, int sflags, struct shf *shf) +/* helper function for shf_fdopen and shf_reopen */ +static void +shf_open_hlp(int fd, int *sflagsp, const char *where) { - int bsize = /* at most 512 */ - sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE; + int sflags = *sflagsp; /* use fcntl() to figure out correct read/write flags */ if (sflags & SHF_GETFL) { @@ -109,11 +110,22 @@ shf_fdopen(int fd, int sflags, struct shf *shf) break; } } + *sflagsp = sflags; } if (!(sflags & (SHF_RD | SHF_WR))) - internal_errorf("%s: %s", "shf_fdopen", "missing read/write"); + internal_errorf("%s: %s", where, "missing read/write"); +} +/* Set up the shf structure for a file descriptor. Doesn't fail. */ +struct shf * +shf_fdopen(int fd, int sflags, struct shf *shf) +{ + ssize_t bsize = + /* at most 512 */ + sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE; + + shf_open_hlp(fd, &sflags, "shf_fdopen"); if (shf) { if (bsize) { shf->buf = alloc(bsize, ATEMP); @@ -144,33 +156,11 @@ shf_fdopen(int fd, int sflags, struct shf *shf) struct shf * shf_reopen(int fd, int sflags, struct shf *shf) { - int bsize = /* at most 512 */ + ssize_t bsize = + /* at most 512 */ sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE; - /* use fcntl() to figure out correct read/write flags */ - if (sflags & SHF_GETFL) { - int flags = fcntl(fd, F_GETFL, 0); - - if (flags < 0) - /* will get an error on first read/write */ - sflags |= SHF_RDWR; - else { - switch (flags & O_ACCMODE) { - case O_RDONLY: - sflags |= SHF_RD; - break; - case O_WRONLY: - sflags |= SHF_WR; - break; - case O_RDWR: - sflags |= SHF_RDWR; - break; - } - } - } - - if (!(sflags & (SHF_RD | SHF_WR))) - internal_errorf("%s: %s", "shf_reopen", "missing read/write"); + shf_open_hlp(fd, &sflags, "shf_reopen"); if (!shf || !shf->buf || shf->bsize < bsize) internal_errorf("%s: %s", "shf_reopen", "bad shf/buf/bsize"); @@ -188,16 +178,17 @@ shf_reopen(int fd, int sflags, struct shf *shf) return (shf); } -/* Open a string for reading or writing. If reading, bsize is the number +/* + * Open a string for reading or writing. If reading, bsize is the number * of bytes that can be read. If writing, bsize is the maximum number of - * bytes that can be written. If shf is not null, it is filled in and - * returned, if it is null, shf is allocated. If writing and buf is null + * bytes that can be written. If shf is not NULL, it is filled in and + * returned, if it is NULL, shf is allocated. If writing and buf is NULL * and SHF_DYNAMIC is set, the buffer is allocated (if bsize > 0, it is * used for the initial size). Doesn't fail. - * When writing, a byte is reserved for a trailing null - see shf_sclose(). + * When writing, a byte is reserved for a trailing NUL - see shf_sclose(). */ struct shf * -shf_sopen(char *buf, int bsize, int sflags, struct shf *shf) +shf_sopen(char *buf, ssize_t bsize, int sflags, struct shf *shf) { /* can't have a read+write string */ if (!(!(sflags & SHF_RD) ^ !(sflags & SHF_WR))) @@ -265,7 +256,8 @@ shf_fdclose(struct shf *shf) return (ret); } -/* Close a string - if it was opened for writing, it is null terminated; +/* + * Close a string - if it was opened for writing, it is NUL terminated; * returns a pointer to the string and frees shf if it was allocated * (does not free string if it was allocated). */ @@ -274,7 +266,7 @@ shf_sclose(struct shf *shf) { unsigned char *s = shf->buf; - /* null terminate */ + /* NUL terminate */ if (shf->flags & SHF_WR) { shf->wnleft++; shf_putc('\0', shf); @@ -284,7 +276,8 @@ shf_sclose(struct shf *shf) return ((char *)s); } -/* Un-read what has been read but not examined, or write what has been +/* + * Un-read what has been read but not examined, or write what has been * buffered. Returns 0 for success, EOF for (write) error. */ int @@ -315,7 +308,8 @@ shf_flush(struct shf *shf) return (0); } -/* Write out any buffered data. If currently reading, flushes the read +/* + * Write out any buffered data. If currently reading, flushes the read * buffer. Returns 0 for success, EOF for (write) error. */ static int @@ -332,7 +326,8 @@ shf_emptybuf(struct shf *shf, int flags) } if (shf->flags & SHF_READING) { - if (flags & EB_READSW) /* doesn't happen */ + if (flags & EB_READSW) + /* doesn't happen */ return (0); ret = shf_flush(shf); shf->flags &= ~SHF_READING; @@ -340,8 +335,10 @@ shf_emptybuf(struct shf *shf, int flags) if (shf->flags & SHF_STRING) { unsigned char *nbuf; - /* Note that we assume SHF_ALLOCS is not set if SHF_ALLOCB - * is set... (changing the shf pointer could cause problems) + /* + * Note that we assume SHF_ALLOCS is not set if + * SHF_ALLOCB is set... (changing the shf pointer could + * cause problems) */ if (!(flags & EB_GROW) || !(shf->flags & SHF_DYNAMIC) || !(shf->flags & SHF_ALLOCB)) @@ -352,13 +349,12 @@ shf_emptybuf(struct shf *shf, int flags) shf->wp = nbuf + (shf->wp - shf->buf); shf->rbsize += shf->wbsize; shf->wnleft += shf->wbsize; - shf->wbsize *= 2; + shf->wbsize <<= 1; shf->buf = nbuf; } else { if (shf->flags & SHF_WRITING) { - int ntowrite = shf->wp - shf->buf; + ssize_t n, ntowrite = shf->wp - shf->buf; unsigned char *buf = shf->buf; - int n; while (ntowrite > 0) { n = write(shf->fd, buf, ntowrite); @@ -370,8 +366,10 @@ shf_emptybuf(struct shf *shf, int flags) shf->errno_ = errno; shf->wnleft = 0; if (buf != shf->buf) { - /* allow a second flush - * to work */ + /* + * allow a second flush + * to work + */ memmove(shf->buf, buf, ntowrite); shf->wp = shf->buf + ntowrite; @@ -438,21 +436,21 @@ shf_fillbuf(struct shf *shf) return (0); } -/* Read a buffer from shf. Returns the number of bytes read into buf, - * if no bytes were read, returns 0 if end of file was seen, EOF if - * a read error occurred. +/* + * Read a buffer from shf. Returns the number of bytes read into buf, if + * no bytes were read, returns 0 if end of file was seen, EOF if a read + * error occurred. */ -int -shf_read(char *buf, int bsize, struct shf *shf) +ssize_t +shf_read(char *buf, ssize_t bsize, struct shf *shf) { - int orig_bsize = bsize; - int ncopy; + ssize_t ncopy, orig_bsize = bsize; if (!(shf->flags & SHF_RD)) internal_errorf("%s: flags 0x%X", "shf_read", shf->flags); if (bsize <= 0) - internal_errorf("%s: %s %d", "shf_write", "bsize", bsize); + internal_errorf("%s: %s %zd", "shf_write", "bsize", bsize); while (bsize > 0) { if (shf->rnleft == 0 && @@ -472,15 +470,17 @@ shf_read(char *buf, int bsize, struct shf *shf) orig_bsize - bsize); } -/* Read up to a newline or EOF. The newline is put in buf; buf is always - * null terminated. Returns NULL on read error or if nothing was read before - * end of file, returns a pointer to the null byte in buf otherwise. +/* + * Read up to a newline or EOF. The newline is put in buf; buf is always + * NUL terminated. Returns NULL on read error or if nothing was read + * before end of file, returns a pointer to the NUL byte in buf + * otherwise. */ char * -shf_getse(char *buf, int bsize, struct shf *shf) +shf_getse(char *buf, ssize_t bsize, struct shf *shf) { unsigned char *end; - int ncopy; + ssize_t ncopy; char *orig_buf = buf; if (!(shf->flags & SHF_RD)) @@ -489,7 +489,8 @@ shf_getse(char *buf, int bsize, struct shf *shf) if (bsize <= 0) return (NULL); - --bsize; /* save room for null */ + /* save room for NUL */ + --bsize; do { if (shf->rnleft == 0) { if (shf_fillbuf(shf) == EOF) @@ -499,7 +500,7 @@ shf_getse(char *buf, int bsize, struct shf *shf) return (buf == orig_buf ? NULL : buf); } } - end = (unsigned char *)memchr((char *) shf->rp, '\n', + end = (unsigned char *)memchr((char *)shf->rp, '\n', shf->rnleft); ncopy = end ? end - shf->rp + 1 : shf->rnleft; if (ncopy > bsize) @@ -527,7 +528,8 @@ shf_getchar(struct shf *shf) return (*shf->rp++); } -/* Put a character back in the input stream. Returns the character if +/* + * Put a character back in the input stream. Returns the character if * successful, EOF if there is no room. */ int @@ -546,8 +548,9 @@ shf_ungetc(int c, struct shf *shf) if (shf->rp == shf->buf) shf->rp = shf->buf + shf->rbsize; if (shf->flags & SHF_STRING) { - /* Can unget what was read, but not something different - we - * don't want to modify a string. + /* + * Can unget what was read, but not something different; + * we don't want to modify a string. */ if (shf->rp[-1] != c) return (EOF); @@ -562,8 +565,9 @@ shf_ungetc(int c, struct shf *shf) return (c); } -/* Write a character. Returns the character if successful, EOF if - * the char could not be written. +/* + * Write a character. Returns the character if successful, EOF if the + * char could not be written. */ int shf_putchar(int c, struct shf *shf) @@ -576,7 +580,7 @@ shf_putchar(int c, struct shf *shf) if (shf->flags & SHF_UNBUF) { unsigned char cc = (unsigned char)c; - int n; + ssize_t n; if (shf->fd < 0) internal_errorf("%s: %s", "shf_putchar", "no fd"); @@ -604,10 +608,11 @@ shf_putchar(int c, struct shf *shf) return (c); } -/* Write a string. Returns the length of the string if successful, EOF if - * the string could not be written. +/* + * Write a string. Returns the length of the string if successful, EOF + * if the string could not be written. */ -int +ssize_t shf_puts(const char *s, struct shf *shf) { if (!s) @@ -617,16 +622,16 @@ shf_puts(const char *s, struct shf *shf) } /* Write a buffer. Returns nbytes if successful, EOF if there is an error. */ -int -shf_write(const char *buf, int nbytes, struct shf *shf) +ssize_t +shf_write(const char *buf, ssize_t nbytes, struct shf *shf) { - int n, ncopy, orig_nbytes = nbytes; + ssize_t n, ncopy, orig_nbytes = nbytes; if (!(shf->flags & SHF_WR)) internal_errorf("%s: flags 0x%X", "shf_write", shf->flags); if (nbytes < 0) - internal_errorf("%s: %s %d", "shf_write", "nbytes", nbytes); + internal_errorf("%s: %s %zd", "shf_write", "nbytes", nbytes); /* Don't buffer if buffer is empty and we're writting a large amount. */ if ((ncopy = shf->wnleft) && @@ -688,11 +693,11 @@ shf_write(const char *buf, int nbytes, struct shf *shf) return (orig_nbytes); } -int +ssize_t shf_fprintf(struct shf *shf, const char *fmt, ...) { va_list args; - int n; + ssize_t n; va_start(args, fmt); n = shf_vfprintf(shf, fmt, args); @@ -701,22 +706,23 @@ shf_fprintf(struct shf *shf, const char *fmt, ...) return (n); } -int -shf_snprintf(char *buf, int bsize, const char *fmt, ...) +ssize_t +shf_snprintf(char *buf, ssize_t bsize, const char *fmt, ...) { struct shf shf; va_list args; - int n; + ssize_t n; if (!buf || bsize <= 0) - internal_errorf("shf_snprintf: buf %lX, bsize %d", - (long)(ptrdiff_t)buf, bsize); + internal_errorf("shf_snprintf: buf %zX, bsize %zd", + (size_t)buf, bsize); shf_sopen(buf, bsize, SHF_WR, &shf); va_start(args, fmt); n = shf_vfprintf(&shf, fmt, args); va_end(args); - shf_sclose(&shf); /* null terminates */ + /* NUL terminates */ + shf_sclose(&shf); return (n); } @@ -730,20 +736,11 @@ shf_smprintf(const char *fmt, ...) va_start(args, fmt); shf_vfprintf(&shf, fmt, args); va_end(args); - return (shf_sclose(&shf)); /* null terminates */ + /* NUL terminates */ + return (shf_sclose(&shf)); } -#undef FP /* if you want floating point stuff */ - -#ifndef DMAXEXP -# define DMAXEXP 128 /* should be big enough */ -#endif - #define BUF_SIZE 128 -/* must be > MAX(DMAXEXP, log10(pow(2, DSIGNIF))) + ceil(log10(DMAXEXP)) + 8 - * (I think); since it's hard to express as a constant, just use a large buffer - */ -#define FPBUF_SIZE (DMAXEXP+16) #define FL_HASH 0x001 /* '#' seen */ #define FL_PLUS 0x002 /* '+' seen */ @@ -755,19 +752,23 @@ shf_smprintf(const char *fmt, ...) #define FL_DOT 0x080 /* '.' seen */ #define FL_UPPER 0x100 /* format character was uppercase */ #define FL_NUMBER 0x200 /* a number was formated %[douxefg] */ +#define FL_SIZET 0x400 /* 'z' seen */ +#define FM_SIZES 0x430 /* h/l/z mask */ - -int +ssize_t shf_vfprintf(struct shf *shf, const char *fmt, va_list args) { const char *s; char c, *cp; - int tmp = 0, field, precision, len, flags; + int tmp = 0, flags; + ssize_t field, precision, len; unsigned long lnum; /* %#o produces the longest output */ char numbuf[(8 * sizeof(long) + 2) / 3 + 1]; /* this stuff for dealing with the buffer */ - int nwritten = 0; + ssize_t nwritten = 0; + +#define VA(type) va_arg(args, type) if (!fmt) return (0); @@ -779,13 +780,14 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args) continue; } /* - * This will accept flags/fields in any order - not - * just the order specified in printf(3), but this is - * the way _doprnt() seems to work (on bsd and sysV). - * The only restriction is that the format character must - * come last :-). + * This will accept flags/fields in any order - not just + * the order specified in printf(3), but this is the way + * _doprnt() seems to work (on BSD and SYSV). The only + * restriction is that the format character must come + * last :-). */ - flags = field = precision = 0; + flags = 0; + field = precision = 0; for ( ; (c = *fmt++) ; ) { switch (c) { case '#': @@ -815,7 +817,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args) continue; case '*': - tmp = va_arg(args, int); + tmp = VA(int); if (flags & FL_DOT) precision = tmp; else if ((field = tmp) < 0) { @@ -825,19 +827,27 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args) continue; case 'l': + flags &= ~FM_SIZES; flags |= FL_LONG; continue; case 'h': + flags &= ~FM_SIZES; flags |= FL_SHORT; continue; + + case 'z': + flags &= ~FM_SIZES; + flags |= FL_SIZET; + continue; } if (ksh_isdigit(c)) { tmp = c - '0'; while (c = *fmt++, ksh_isdigit(c)) tmp = tmp * 10 + c - '0'; --fmt; - if (tmp < 0) /* overflow? */ + if (tmp < 0) + /* overflow? */ tmp = 0; if (flags & FL_DOT) precision = tmp; @@ -851,7 +861,8 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args) if (precision < 0) precision = 0; - if (!c) /* nasty format */ + if (!c) + /* nasty format */ break; if (c >= 'A' && c <= 'Z') { @@ -862,26 +873,32 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args) switch (c) { case 'd': case 'i': + if (flags & FL_SIZET) + lnum = (long)VA(ssize_t); + else if (flags & FL_LONG) + lnum = VA(long); + else if (flags & FL_SHORT) + lnum = (long)(short)VA(int); + else + lnum = (long)VA(int); + goto integral; + case 'o': case 'u': case 'x': + if (flags & FL_SIZET) + lnum = VA(size_t); + else if (flags & FL_LONG) + lnum = VA(unsigned long); + else if (flags & FL_SHORT) + lnum = (unsigned long)(unsigned short)VA(int); + else + lnum = (unsigned long)VA(unsigned int); + + integral: flags |= FL_NUMBER; cp = numbuf + sizeof(numbuf); - /*- - * XXX any better way to do this? - * XXX hopefully the compiler optimises this out - * - * For shorts, we want sign extend for %d but not - * for %[oxu] - on 16 bit machines it doesn't matter. - * Assumes C compiler has converted shorts to ints - * before pushing them. XXX optimise this -tg - */ - if (flags & FL_LONG) - lnum = va_arg(args, unsigned long); - else if ((sizeof(int) < sizeof(long)) && (c == 'd')) - lnum = (long)va_arg(args, int); - else - lnum = va_arg(args, unsigned int); + switch (c) { case 'd': case 'i': @@ -937,19 +954,20 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args) field = precision; flags |= FL_ZERO; } else - precision = len; /* no loss */ + /* no loss */ + precision = len; } break; case 's': - if (!(s = va_arg(args, const char *))) + if ((s = VA(const char *)) == NULL) s = "(null)"; len = utf_mbswidth(s); break; case 'c': flags &= ~FL_DOT; - numbuf[0] = (char)(va_arg(args, int)); + numbuf[0] = (char)(VA(int)); s = numbuf; len = 1; break; diff --git a/syn.c b/syn.c index 8ace2ce..554710e 100644 --- a/syn.c +++ b/syn.c @@ -22,9 +22,10 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.67 2011/06/05 19:58:20 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.68 2011/08/27 18:06:51 tg Exp $"); extern short subshell_nesting_level; +extern void yyskiputf8bom(void); struct nesting_state { int start_token; /* token than began nesting (eg, FOR) */ @@ -893,8 +894,6 @@ newtp(int type) struct op * compile(Source *s, bool skiputf8bom) { - extern void yyskiputf8bom(void); - nesting.start_token = 0; nesting.start_line = 0; herep = heres; diff --git a/tree.c b/tree.c index c4b5003..482eb88 100644 --- a/tree.c +++ b/tree.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.49 2011/05/29 02:18:57 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.50 2011/08/27 18:06:51 tg Exp $"); #define INDENT 8 @@ -386,7 +386,7 @@ fptreef(struct shf *shf, int indent, const char *fmt, ...) /* VARARGS */ char * -snptreef(char *s, int n, const char *fmt, ...) +snptreef(char *s, ssize_t n, const char *fmt, ...) { va_list va; struct shf shf; diff --git a/var.c b/var.c index 13769e9..27205bd 100644 --- a/var.c +++ b/var.c @@ -26,7 +26,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.130 2011/07/07 20:24:53 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.131 2011/08/27 18:06:52 tg Exp $"); /*- * Variables @@ -170,7 +170,7 @@ static const char * array_index_calc(const char *n, bool *arrayp, uint32_t *valp) { const char *p; - int len; + size_t len; char *ap = NULL; *arrayp = false; @@ -585,7 +585,7 @@ formatstr(struct tbl *vp, const char *s) char *p, *q; size_t psiz; - olen = utf_mbswidth(s); + olen = (int)utf_mbswidth(s); if (vp->flag & (RJUST|LJUST)) { if (!vp->u2.field) @@ -693,7 +693,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base) struct tbl *vpbase, *t; char *tvar; const char *val; - int len; + size_t len; bool vappend = false; /* check for valid variable name, search for value */ @@ -717,7 +717,8 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base) * would be a major security hole. */ if (set & IMPORT) { - int i; + size_t i; + for (i = 1; i < len - 1; i++) if (!ksh_isdigit(val[i])) return (NULL); @@ -738,9 +739,9 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base) val = NULL; /* handle foo[*] => foo (whole array) mapping for R39b */ len = strlen(tvar); - if (len > 3 && tvar[len-3] == '[' && tvar[len-2] == '*' && - tvar[len-1] == ']') - tvar[len-3] = '\0'; + if (len > 3 && tvar[len - 3] == '[' && tvar[len - 2] == '*' && + tvar[len - 1] == ']') + tvar[len - 3] = '\0'; } if (set_refflag == SRF_ENABLE) { @@ -944,7 +945,7 @@ unset(struct tbl *vp, int flags) const char * skip_varname(const char *s, int aok) { - int alen; + size_t alen; if (s && ksh_isalphx(*s)) { while (*++s && ksh_isalnux(*s)) @@ -1336,11 +1337,11 @@ arraysearch(struct tbl *vp, uint32_t val) * to point to the open bracket. Returns 0 if there is no matching * closing bracket. */ -int +size_t array_ref_len(const char *cp) { const char *s = cp; - int c; + char c; int depth = 0; while ((c = *s++) && (c != ']' || --depth)) @@ -1374,19 +1375,20 @@ mksh_uari_t set_array(const char *var, bool reset, const char **vals) { struct tbl *vp, *vq; - mksh_uari_t i, j = 0; + mksh_uari_t i = 0, j = 0; const char *ccp; #ifndef MKSH_SMALL char *cp = NULL; + size_t n; #endif /* to get local array, use "typeset foo; set -A foo" */ #ifndef MKSH_SMALL - i = strlen(var); - if (i > 0 && var[i - 1] == '+') { + n = strlen(var); + if (n > 0 && var[n - 1] == '+') { /* append mode */ reset = false; - strndupx(cp, var, i - 1, ATEMP); + strndupx(cp, var, n - 1, ATEMP); } #define CPORVAR (cp ? cp : var) #else @@ -1406,7 +1408,6 @@ set_array(const char *var, bool reset, const char **vals) * completely fail. Only really effects integer arrays: * evaluation of some of vals[] may fail... */ - i = 0; #ifndef MKSH_SMALL if (cp != NULL) { /* find out where to set when appending */