From 04be5b1456b381303709fdc90385fe74dad1bd10 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 22 Dec 2016 14:18:38 +0100 Subject: eprintf: add ecalloc Add ecalloc as an error handling calloc wrapper. --- eprintf.c | 12 ++++++++++++ eprintf.h | 9 +++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/eprintf.c b/eprintf.c index 7a885b3..41c043f 100644 --- a/eprintf.c +++ b/eprintf.c @@ -76,6 +76,18 @@ void *emalloc(size_t n) return p; } +/* ecalloc: attempt to allocate memory or exit on error */ +void *ecalloc(size_t nmemb, size_t size) +{ + void *p; + + p = calloc(nmemb, size); + if (p == NULL) + eprintf("ecalloc(%zu, %zu) failed:", nmemb, size); + + return p; +} + /* erealloc: attempt to reallocate memory or exit on error */ void *erealloc(void *p, size_t n) { diff --git a/eprintf.h b/eprintf.h index aecc3a6..bfe4ca8 100644 --- a/eprintf.h +++ b/eprintf.h @@ -6,10 +6,11 @@ noreturn void eprintf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void weprintf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); -char *estrdup(const char *); -void *emalloc(size_t); -void *erealloc(void *, size_t); +char *estrdup(const char *str); +void *emalloc(size_t size); +void *ecalloc(size_t nmemb, size_t size); +void *erealloc(void *p, size_t size); char *progname(void); -void setprogname(const char *); +void setprogname(const char *name); #endif /* !EPRINTF_H */ -- cgit v1.2.3-54-g00ecf From 27f76df4d35ec26bb7a1571a38cd27d978cd85e2 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 22 Dec 2016 14:24:13 +0100 Subject: halfkay: overhaul error handling Errors now handled by eprintf.h instead of log.h. --- halfkay.c | 70 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/halfkay.c b/halfkay.c index 6c41971..8158888 100644 --- a/halfkay.c +++ b/halfkay.c @@ -28,7 +28,7 @@ #include #include "halfkay.h" -#include "log.h" +#include "eprintf.h" enum { HK_USB_VID = 0x16c0, @@ -40,28 +40,33 @@ enum { HK_USB_VAL = 0x200, TIMEOUT = 2000, TIMEOUT_FIRST = 3000, - TRANS_DELAY = 4000, - TRANS_ATTEMPTS = 10, + SEND_DELAY = 4000, + SEND_ATTEMPTS = 10, + REBOOTCMD_WIDTH = 3, + REBOOTCMD_FILL = 0xff, }; libusb_device_handle *hk_usb_hnd; static inline void libusb_err(const char *action, int code) { - error(0, "libusb %s failed: %s", action, libusb_strerror(code)); + eprintf("libusb %s failed: %s", action, libusb_strerror(code)); } static void usbopen(void) { int rc; + if (hk_usb_hnd != NULL) + return; + rc = libusb_init(NULL); if (libusb_init(NULL) != LIBUSB_SUCCESS) libusb_err("init", rc); hk_usb_hnd = libusb_open_device_with_vid_pid(NULL, HK_USB_VID, HK_USB_PID); if (!hk_usb_hnd) - error(0, "HalfKay device not found"); + eprintf("HalfKay device not found"); libusb_set_auto_detach_kernel_driver(hk_usb_hnd, 1); rc = libusb_claim_interface(hk_usb_hnd, 0); @@ -71,23 +76,28 @@ static void usbopen(void) static void usbclose(void) { + if (hk_usb_hnd == NULL) + return; + libusb_release_interface(hk_usb_hnd, 0); libusb_close(hk_usb_hnd); libusb_exit(NULL); + + hk_usb_hnd = NULL; } static void usbsendcmd(void *data, size_t size, bool firstxfer) { unsigned int timeout = firstxfer ? TIMEOUT_FIRST : TIMEOUT; int rc, attempt = 0; - useconds_t delay = TRANS_DELAY; + useconds_t delay = SEND_DELAY; do { rc = libusb_control_transfer(hk_usb_hnd, HK_USB_REQTYP, HK_USB_REQ, HK_USB_VAL, 0, data, size, timeout); usleep(delay); delay *= 2; - } while (rc == LIBUSB_ERROR_PIPE && ++attempt < TRANS_ATTEMPTS); + } while (rc == LIBUSB_ERROR_PIPE && ++attempt < SEND_ATTEMPTS); if (rc < 0) libusb_err("transfer", rc); @@ -98,6 +108,9 @@ static void fmtcmd(void *_dest, const struct flashparams *fp, size_t addr) static const size_t MAX_SHIFT = sizeof addr * CHAR_BIT / 8; unsigned char *dest = _dest; + assert(dest); + assert(fp); + addr >>= fp->addrshft; for (size_t i = 0; i < fp->cmdsz && i < MAX_SHIFT; i++) dest[i] = (addr >> (i * 8)) & 0xFF; @@ -109,24 +122,18 @@ int flash(const struct flashparams *fp, const char *file) unsigned char *cmd; size_t tsize; + assert(fp); + assert(fp->blksz && (fp->blksz & (fp->blksz - 1)) == 0); + assert(fp->memsz % fp->blksz == 0); + assert(SIZE_MAX - fp->blksz >= fp->cmdsz); assert(file); - /* TODO: move checks to parser */ - /*if (!fp->blksz || !(fp->blksz & fp->blksz - 1))*/ - /*error(0, "Block size is not a power of 2");*/ - /*if (fp->memsz % fp->blksz)*/ - /*error(0, "Memory size is not divisible by block size");*/ - - tsize = fp->blksz + fp->cmdsz; - f = fopen(file, "rb"); if (!f) - error(errno, EMSG_OPEN, file); + eprintf("Could not open '%s':", file); - /* TODO: precalc and check ovf */ - cmd = malloc(tsize); - if (!cmd) - error(errno, EMSG_ALLOC); + tsize = fp->blksz + fp->cmdsz; + cmd = emalloc(tsize); usbopen(); @@ -135,17 +142,18 @@ int flash(const struct flashparams *fp, const char *file) fmtcmd(cmd, fp, blkaddr); count = fread(cmd + fp->cmdsz, 1, fp->blksz, f); + if (count != fp->blksz && ferror(f)) + eprintf("Error while reading '%s', short read", file); if (count == 0) break; - if (count < fp->blksz) { + if (count < fp->blksz) memset(cmd + fp->cmdsz + count, 0, fp->blksz - count); - } usbsendcmd(cmd, tsize, blkaddr == 0); } if (!feof(f)) - fprintf(stderr, "Device ran out of space during writing!"); + weprintf("Device ran out of space during writing!"); usbclose(); @@ -157,10 +165,18 @@ int flash(const struct flashparams *fp, const char *file) int reboot(const struct flashparams *fp) { - size_t tsize = fp->blksz + fp->cmdsz; - unsigned char *cmd = malloc(tsize); - memset(cmd, 0x00, tsize - 3); - memset(cmd, 0xff, 3); + size_t tsize; + unsigned char *cmd; + + assert(fp); + assert(fp->blksz && (fp->blksz & (fp->blksz - 1)) == 0); + assert(fp->memsz % fp->blksz == 0); + assert(SIZE_MAX - fp->blksz >= fp->cmdsz); + + tsize = fp->blksz + fp->cmdsz; + cmd = ecalloc(tsize, 1); + + memset(cmd, REBOOTCMD_FILL, REBOOTCMD_WIDTH); usbopen(); usbsendcmd(cmd, tsize, true); -- cgit v1.2.3-54-g00ecf From da3b7ca6b023ea2dadcf15542dcc9a1bc57a3d47 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 22 Dec 2016 16:24:58 +0100 Subject: hktool: overhaul error handing Switch from log.h to eprintf.h --- hktool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hktool.c b/hktool.c index a9bef02..e95b556 100644 --- a/hktool.c +++ b/hktool.c @@ -97,18 +97,18 @@ int main(int argc, char **argv) return EXIT_FAILURE; break; default: - error(0, "getopt returned unexpected value"); + eprintf("getopt returned unexpected value"); } } if (optind >= argc) - error(0, "No MCU specified\nUsage: %s " USAGE, argv[0]); + eprintf("No MCU specified\nUsage: %s " USAGE, argv[0]); if (!doflash && !doreboot) - error(0, "Nothing to do"); + eprintf("Nothing to do"); if (argc - optind > 1) - error(0, "Invalid number of arguments\nUsage: %s " USAGE, argv[0]); + eprintf("Invalid number of arguments\nUsage: %s " USAGE, argv[0]); if (getparams(&fp, argv[optind]) != 0) return EXIT_FAILURE; -- cgit v1.2.3-54-g00ecf From eee1fedc3a69e503fab74248937e35e71dee4992 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 22 Dec 2016 16:31:28 +0100 Subject: util: remove unused functions Removed: xstrmalloc, xmalloc, xrealloc, xstrcut, szadd, szmul. --- util.c | 85 +++--------------------------------------------------------------- util.h | 6 ----- 2 files changed, 3 insertions(+), 88 deletions(-) diff --git a/util.c b/util.c index a8c3729..9f8e23e 100644 --- a/util.c +++ b/util.c @@ -15,23 +15,6 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Some contents of this file (indicated below) are based on work covered by - * the following copyright and permission notice: - * - * Copyright (c) 2008 Otto Moerbeek - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include @@ -42,80 +25,18 @@ #include #include "log.h" +#include "eprintf.h" #include "util.h" -/* szadd: checked size_t addition */ -size_t szadd(size_t a, size_t b) -{ - if (SIZE_MAX - a < b) - error(0, EMSG_SZOP); - - return a + b; -} - -/* szmul: checked size_t multiplication - * License information can be found at the top of this file */ -size_t szmul(size_t a, size_t b) -{ -#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof (size_t) * 4)) - if ((a >= MUL_NO_OVERFLOW || b >= MUL_NO_OVERFLOW) && - a > 0 && SIZE_MAX / a < b) - error(0, EMSG_SZOP); -#undef MUL_NO_OVERFLOW - - return a * b; -} - /* xstrmalloc: allocate for a string (+1) or exit with error */ void *xstrmalloc(size_t size) { size_t nsize; - nsize = size + 1; - if (nsize < size) + if (size == SIZE_MAX) error(0, EMSG_ALLOC); - return xmalloc(nsize); -} - -/* xstrdup: duplicae string or exit with error */ -char *xstrdup(const char *s) -{ - char *ret; - - assert(s); - - ret = xstrmalloc(strlen(s)); - strcpy(ret, s); - - return ret; -} - -/* xrealloc: reallocate or exit with error */ -void *xrealloc(void *p, size_t size) -{ - p = realloc(p, size); - if (!p) - error(errno, EMSG_ALLOC); - - return p; -} - -/* xmalloc: allocate or exit with error */ -void *xmalloc(size_t size) -{ - return xrealloc(NULL, size); -} - -/* xstrcut: cut out a bit of a string into a new string */ -char *xstrcut(const char *s, size_t offt, size_t len) -{ - char *ret; - - ret = xstrmalloc(len); - strncpy(ret, s + offt, len + 1); - - return ret; + return emalloc(nsize); } /* xstrcasecmp: case insensitive strcmp */ diff --git a/util.h b/util.h index 356366c..d1f459a 100644 --- a/util.h +++ b/util.h @@ -22,13 +22,7 @@ #include #include -size_t szadd(size_t a, size_t b); -size_t szmul(size_t a, size_t b); void *xstrmalloc(size_t size); -char *xstrdup(const char *s); -void *xmalloc(size_t size); -void *xrealloc(void *p, size_t size); -char *xstrcut(const char *s, size_t offt, size_t len); int xstrcasecmp(const char *s1, const char *s2); #endif /* UTIL_H */ -- cgit v1.2.3-54-g00ecf From cb4a70a049f2df4b6ffaa5f7fb5f920910bd1d68 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 22 Dec 2016 18:38:59 +0100 Subject: log: removal of log.{c,h} --- Makefile | 2 +- hktool.c | 4 +-- log.c | 99 ---------------------------------------------------------------- log.h | 42 --------------------------- util.c | 3 +- 5 files changed, 3 insertions(+), 147 deletions(-) delete mode 100644 log.c delete mode 100644 log.h diff --git a/Makefile b/Makefile index 3c203df..40acd65 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ CFLAGS = -std=c11 -O2 -flto $(WARNINGS) -MMD -MP $(shell $(PKG_CONFIG) --cflags LDFLAGS = -Wl,--as-needed -O2 -flto LDLIBS = $(shell $(PKG_CONFIG) --libs $(LIBS)) -OBJ := hktool.o halfkay.o log.o params.o util.o eprintf.o +OBJ := hktool.o halfkay.o params.o util.o eprintf.o PREFIX ?= /usr/local diff --git a/hktool.c b/hktool.c index e95b556..76e6b75 100644 --- a/hktool.c +++ b/hktool.c @@ -24,7 +24,6 @@ #include #include "halfkay.h" -#include "log.h" #include "eprintf.h" #include "params.h" @@ -67,8 +66,7 @@ int main(int argc, char **argv) int opt; struct flashparams fp; - argv0 = argv[0] != NULL ? argv[0] : "hktool"; - setprogname(argv0); + setprogname(argv[0] != NULL ? argv[0] : "hktool"); while (opt = getopt(argc, argv, "f:h-lvr"), opt != -1) { switch (opt) { diff --git a/log.c b/log.c deleted file mode 100644 index 39730bf..0000000 --- a/log.c +++ /dev/null @@ -1,99 +0,0 @@ -/* log.c -- Error and warning messages. - * - * Copyright (C) 2016 Tomasz Kramkowski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include -#include -#include -#include -#include - -#include "log.h" - -const char *argv0; - -void error(int errnum, const char *fmt, ...) -{ - assert(fmt); - - va_list va; - - fprintf(stderr, "%s: error: ", argv0); - - va_start(va, fmt); - vfprintf(stderr, fmt, va); - va_end(va); - - if (errnum) - fprintf(stderr, ": %s", strerror(errnum)); - - fputc('\n', stderr); - - exit(EXIT_FAILURE); -} - -void errorat(int errnum, const char *file, long line, const char *fmt, ...) -{ - assert(file && fmt); - - va_list va; - - fprintf(stderr, "%s:%s:%ld: error: ", argv0, file, line); - - va_start(va, fmt); - vfprintf(stderr, fmt, va); - va_end(va); - - if (errnum) - fprintf(stderr, ": %s", strerror(errnum)); - - fputc('\n', stderr); - - exit(EXIT_FAILURE); -} - -void warning(int errnum, const char *fmt, ...) -{ - va_list ap; - - fprintf(stderr, "%s: warning: ", argv0); - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if (errnum) - fprintf(stderr, ": %s", strerror(errnum)); - - fputc('\n', stderr); -} - -void warningat(int errnum, const char *file, long line, const char *fmt, ...) -{ - va_list ap; - - fprintf(stderr, "%s:%s:%ld: warning: ", argv0, file, line); - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if (errnum) - fprintf(stderr, ": %s", strerror(errnum)); - - fputc('\n', stderr); -} diff --git a/log.h b/log.h deleted file mode 100644 index d6ae299..0000000 --- a/log.h +++ /dev/null @@ -1,42 +0,0 @@ -/* log.h -- Error and warning messages. - * - * Copyright (C) 2016 Tomasz Kramkowski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef LOG_H -#define LOG_H - -#include - -#define EMSG_ALLOC "Could not allocate memory" -#define EMSG_OPEN "Could not open '%s'" -#define EMSG_READ "Could not read '%s'" -#define EMSG_SZOP "Arithmetic operation on size_t would wrap" -#define EMSG_GNOMEM "A call to glob ran out of memory" - -extern const char *argv0; - -noreturn void error(int errnum, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); -noreturn void errorat(int errnum, const char *file, long line, const char *fmt, ...) - __attribute__ ((format(printf, 4, 5))); - -void warning(int errnum, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); -void warningat(int errnum, const char *file, long line, const char *fmt, ...) - __attribute__ ((format(printf, 4, 5))); - -#endif /* LOG_H */ diff --git a/util.c b/util.c index 9f8e23e..33c5bee 100644 --- a/util.c +++ b/util.c @@ -24,7 +24,6 @@ #include #include -#include "log.h" #include "eprintf.h" #include "util.h" @@ -34,7 +33,7 @@ void *xstrmalloc(size_t size) size_t nsize; if (size == SIZE_MAX) - error(0, EMSG_ALLOC); + eprintf("xstrmalloc(%zu) failed: %zu == SIZE_MAX", size, size); return emalloc(nsize); } -- cgit v1.2.3-54-g00ecf From 0fc0c19e4dc2b4ec2f175744e1ac468643b6da71 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 29 Dec 2016 14:46:34 +0100 Subject: eprintf: Add asserts --- eprintf.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/eprintf.c b/eprintf.c index 41c043f..2aea355 100644 --- a/eprintf.c +++ b/eprintf.c @@ -1,9 +1,10 @@ +#include #include #include +#include #include #include #include -#include #include "eprintf.h" @@ -15,6 +16,8 @@ void eprintf(const char *fmt, ...) int errnum = errno; va_list va; + assert(fmt); + if (progname() != NULL) fprintf(stderr, "%s: ", progname()); @@ -35,6 +38,8 @@ void weprintf(const char *fmt, ...) int errnum = errno; va_list va; + assert(fmt); + if (progname() != NULL) fprintf(stderr, "%s: ", progname()); @@ -53,6 +58,8 @@ char *estrdup(const char *s) size_t len; char *dup; + assert(s); + len = strlen(s); if (len == SIZE_MAX) eprintf("estrdup(\"%.20s\") failed: Too long", s); -- cgit v1.2.3-54-g00ecf