/* $OpenBSD: shf.c,v 1.15 2006/04/02 00:48:33 deraadt Exp $ */
/*-
- * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011
+ * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
#include "sh.h"
-__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.44 2011/09/07 15:24:20 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.56 2013/01/01 03:32:44 tg Exp $");
/* flags to shf_emptybuf() */
#define EB_READSW 0x01 /* about to switch to reading */
return (NULL);
/* save room for NUL */
- --bsize;
+ --bsize;
do {
if (shf->rnleft == 0) {
if (shf_fillbuf(shf) == EOF)
* Can unget what was read, but not something different;
* we don't want to modify a string.
*/
- if (shf->rp[-1] != c)
+ if ((int)(shf->rp[-1]) != c)
return (EOF);
shf->flags &= ~SHF_EOF;
shf->rp--;
n = shf_vfprintf(&shf, fmt, args);
va_end(args);
/* NUL terminates */
- shf_sclose(&shf);
+ shf_sclose(&shf);
return (n);
}
ssize_t field, precision, len;
unsigned long lnum;
/* %#o produces the longest output */
- char numbuf[(8 * sizeof(long) + 2) / 3 + 1];
+ char numbuf[(8 * sizeof(long) + 2) / 3 + 1
+#ifdef DEBUG
+ /* a NUL for LLVM/Clang scan-build */
+ + 1
+#endif
+ ];
/* this stuff for dealing with the buffer */
ssize_t nwritten = 0;
continue;
}
if (ksh_isdigit(c)) {
+ bool overflowed = false;
+
tmp = c - '0';
- while (c = *fmt++, ksh_isdigit(c))
+ while (c = *fmt++, ksh_isdigit(c)) {
+ if (notok2mul(2147483647, tmp, 10))
+ overflowed = true;
tmp = tmp * 10 + c - '0';
+ }
--fmt;
- if (tmp < 0)
- /* overflow? */
+ if (overflowed)
tmp = 0;
if (flags & FL_DOT)
precision = tmp;
integral:
flags |= FL_NUMBER;
cp = numbuf + sizeof(numbuf);
+#ifdef DEBUG
+ /*
+ * this is necessary so Clang 3.2 realises
+ * utf_skipcols/shf_putc in the output loop
+ * terminate; these values are always ASCII
+ * so an out-of-bounds access cannot happen
+ * but Clang doesn't know that
+ */
+ *--cp = '\0';
+#endif
switch (c) {
case 'd':
}
}
len = numbuf + sizeof(numbuf) - (s = cp);
+#ifdef DEBUG
+ /* see above comment for Clang 3.2 */
+ --len;
+#endif
if (flags & FL_DOT) {
if (precision > len) {
field = precision;
case 'c':
flags &= ~FL_DOT;
- numbuf[0] = (char)(VA(int));
- s = numbuf;
- len = 1;
- break;
+ c = (char)(VA(int));
+ /* FALLTHROUGH */
case '%':
default:
numbuf[0] = c;
+ numbuf[1] = 0;
s = numbuf;
len = 1;
break;
return (shf_error(shf) ? EOF : nwritten);
}
-#ifdef MKSH_SMALL
+#if defined(MKSH_SMALL) && !defined(MKSH_SMALL_BUT_FAST)
int
shf_getc(struct shf *shf)
{
- return (shf_getc_(shf));
+ return (shf_getc_i(shf));
}
int
shf_putc(int c, struct shf *shf)
{
- return (shf_putc_(c, shf));
+ return (shf_putc_i(c, shf));
+}
+#endif
+
+#ifdef DEBUG
+const char *
+cstrerror(int errnum)
+{
+#undef strerror
+ return (strerror(errnum));
+#define strerror dontuse_strerror /* poisoned */
+}
+#elif !HAVE_STRERROR
+
+#if HAVE_SYS_ERRLIST
+#if !HAVE_SYS_ERRLIST_DECL
+extern const int sys_nerr;
+extern const char * const sys_errlist[];
+#endif
+#endif
+
+const char *
+cstrerror(int errnum)
+{
+ /* "Unknown error: " + sign + rough estimate + NUL */
+ static char errbuf[15 + 1 + (8 * sizeof(int) + 2) / 3 + 1];
+
+#if HAVE_SYS_ERRLIST
+ if (errnum > 0 && errnum < sys_nerr && sys_errlist[errnum])
+ return (sys_errlist[errnum]);
+#endif
+
+ switch (errnum) {
+ case 0:
+ return ("Undefined error: 0");
+#ifdef EPERM
+ case EPERM:
+ return ("Operation not permitted");
+#endif
+#ifdef ENOENT
+ case ENOENT:
+ return ("No such file or directory");
+#endif
+#ifdef ESRCH
+ case ESRCH:
+ return ("No such process");
+#endif
+#ifdef E2BIG
+ case E2BIG:
+ return ("Argument list too long");
+#endif
+#ifdef ENOEXEC
+ case ENOEXEC:
+ return ("Exec format error");
+#endif
+#ifdef ENOMEM
+ case ENOMEM:
+ return ("Cannot allocate memory");
+#endif
+#ifdef EACCES
+ case EACCES:
+ return ("Permission denied");
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR:
+ return ("Not a directory");
+#endif
+#ifdef EINVAL
+ case EINVAL:
+ return ("Invalid argument");
+#endif
+#ifdef ELOOP
+ case ELOOP:
+ return ("Too many levels of symbolic links");
+#endif
+ default:
+ shf_snprintf(errbuf, sizeof(errbuf),
+ "Unknown error: %d", errnum);
+ return (errbuf);
+ }
}
#endif