aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2017-02-11 15:30:37 +0000
committerTomasz Kramkowski <tk@the-tk.com>2017-02-11 15:30:37 +0000
commitb8ede3c284299173f3981aa85dcbd16806a57f55 (patch)
tree31beb63b99f1840472da304de628e6114ba61f8e
parent99778c999c364ad3e5967f7a9a0a3e484c279716 (diff)
parent0fc0c19e4dc2b4ec2f175744e1ac468643b6da71 (diff)
downloadhktool-b8ede3c284299173f3981aa85dcbd16806a57f55.tar.gz
hktool-b8ede3c284299173f3981aa85dcbd16806a57f55.tar.xz
hktool-b8ede3c284299173f3981aa85dcbd16806a57f55.zip
Merge branch 'halfkay-error-handling'
-rw-r--r--Makefile2
-rw-r--r--eprintf.c21
-rw-r--r--eprintf.h9
-rw-r--r--halfkay.c70
-rw-r--r--hktool.c12
-rw-r--r--log.c99
-rw-r--r--log.h42
-rw-r--r--util.c88
-rw-r--r--util.h6
9 files changed, 78 insertions, 271 deletions
diff --git a/Makefile b/Makefile
index ec647c4..3663579 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/eprintf.c b/eprintf.c
index 7a885b3..2aea355 100644
--- a/eprintf.c
+++ b/eprintf.c
@@ -1,9 +1,10 @@
+#include <assert.h>
#include <errno.h>
#include <stdarg.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdint.h>
#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);
@@ -76,6 +83,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 */
diff --git a/halfkay.c b/halfkay.c
index 6c41971..8158888 100644
--- a/halfkay.c
+++ b/halfkay.c
@@ -28,7 +28,7 @@
#include <unistd.h>
#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);
diff --git a/hktool.c b/hktool.c
index a9bef02..76e6b75 100644
--- a/hktool.c
+++ b/hktool.c
@@ -24,7 +24,6 @@
#include <unistd.h>
#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) {
@@ -97,18 +95,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;
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 <tk@the-tk.com>
- *
- * 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 <assert.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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 <tk@the-tk.com>
- *
- * 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 <stdnoreturn.h>
-
-#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 a8c3729..33c5bee 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 <otto@drijf.net>
- *
- * 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 <assert.h>
#include <errno.h>
@@ -41,81 +24,18 @@
#include <string.h>
#include <ctype.h>
-#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)
- 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);
+ if (size == SIZE_MAX)
+ eprintf("xstrmalloc(%zu) failed: %zu == SIZE_MAX", size, size);
- 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 <stdbool.h>
#include <stddef.h>
-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 */