From 18d4d5dcc02f5fcd297f9ffaa057c2ecc386ece9 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 12 Oct 2015 19:46:00 +0200 Subject: [PATCH] Switch to goto style error handling. With the goto error handling, all cleanup code can be moved to a central location and no longer needs to be duplicated multiple times. --- src/atomics_cobalt.c | 37 +++++++++++++++++++------------- src/citizen_aqualand.c | 25 ++++++++++++++-------- src/cressi_edy.c | 35 ++++++++++++++++++------------- src/cressi_leonardo.c | 30 +++++++++++++++----------- src/diverite_nitekq.c | 32 +++++++++++++++------------- src/divesystem_idive.c | 25 ++++++++++++++-------- src/hw_frog.c | 31 +++++++++++++++------------ src/hw_ostc.c | 25 ++++++++++++++-------- src/hw_ostc3.c | 25 ++++++++++++++-------- src/irda.c | 21 ++++++++++--------- src/mares_darwin.c | 30 +++++++++++++++----------- src/mares_iconhd.c | 36 ++++++++++++++++++-------------- src/mares_nemo.c | 30 +++++++++++++++----------- src/mares_puck.c | 36 ++++++++++++++++++-------------- src/oceanic_atom2.c | 32 +++++++++++++++------------- src/oceanic_veo250.c | 40 ++++++++++++++++++----------------- src/oceanic_vtpro.c | 44 +++++++++++++++++++-------------------- src/reefnet_sensus.c | 25 ++++++++++++++-------- src/reefnet_sensuspro.c | 25 ++++++++++++++-------- src/reefnet_sensusultra.c | 25 ++++++++++++++-------- src/serial_posix.c | 17 ++++++++------- src/serial_win32.c | 13 +++++++----- src/shearwater_common.c | 14 +++++++++---- src/shearwater_petrel.c | 16 ++++++++------ src/shearwater_predator.c | 16 ++++++++------ src/suunto_d9.c | 36 ++++++++++++++++++-------------- src/suunto_eon.c | 30 +++++++++++++++----------- src/suunto_eonsteel.c | 24 +++++++++++++-------- src/suunto_solution.c | 30 +++++++++++++++----------- src/suunto_vyper.c | 30 +++++++++++++++----------- src/suunto_vyper2.c | 36 ++++++++++++++++++-------------- src/uwatec_aladin.c | 30 +++++++++++++++----------- src/uwatec_memomouse.c | 30 +++++++++++++++----------- src/uwatec_meridian.c | 25 ++++++++++++++-------- src/uwatec_smart.c | 30 +++++++++++++++----------- src/uwatec_smart_parser.c | 13 +++++++++--- src/zeagle_n2ition3.c | 25 ++++++++++++++-------- 37 files changed, 608 insertions(+), 416 deletions(-) diff --git a/src/atomics_cobalt.c b/src/atomics_cobalt.c index aec412d..b901f5b 100644 --- a/src/atomics_cobalt.c +++ b/src/atomics_cobalt.c @@ -82,12 +82,17 @@ static const dc_device_vtable_t atomics_cobalt_device_vtable = { dc_status_t atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context) { +#ifdef HAVE_LIBUSB + dc_status_t status = DC_STATUS_SUCCESS; + atomics_cobalt_device_t *device = NULL; +#endif + if (out == NULL) return DC_STATUS_INVALIDARGS; #ifdef HAVE_LIBUSB // Allocate memory. - atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) malloc (sizeof (atomics_cobalt_device_t)); + device = (atomics_cobalt_device_t *) malloc (sizeof (atomics_cobalt_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -105,39 +110,41 @@ atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context) int rc = libusb_init (&device->context); if (rc < 0) { ERROR (context, "Failed to initialize usb support."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } device->handle = libusb_open_device_with_vid_pid (device->context, VID, PID); if (device->handle == NULL) { ERROR (context, "Failed to open the usb device."); - libusb_exit (device->context); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_usb_exit; } rc = libusb_claim_interface (device->handle, 0); if (rc < 0) { ERROR (context, "Failed to claim the usb interface."); - libusb_close (device->handle); - libusb_exit (device->context); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_usb_close; } - dc_status_t status = atomics_cobalt_device_version ((dc_device_t *) device, device->version, sizeof (device->version)); + status = atomics_cobalt_device_version ((dc_device_t *) device, device->version, sizeof (device->version)); if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to identify the dive computer."); - libusb_close (device->handle); - libusb_exit (device->context); - free (device); - return status; + goto error_usb_close; } *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_usb_close: + libusb_close (device->handle); +error_usb_exit: + libusb_exit (device->context); +error_free: + free (device); + return status; #else return DC_STATUS_UNSUPPORTED; #endif diff --git a/src/citizen_aqualand.c b/src/citizen_aqualand.c index dc291b4..9a2812d 100644 --- a/src/citizen_aqualand.c +++ b/src/citizen_aqualand.c @@ -63,11 +63,14 @@ static const dc_device_vtable_t citizen_aqualand_device_vtable = { dc_status_t citizen_aqualand_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + citizen_aqualand_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - citizen_aqualand_device_t *device = (citizen_aqualand_device_t *) malloc (sizeof (citizen_aqualand_device_t)); + device = (citizen_aqualand_device_t *) malloc (sizeof (citizen_aqualand_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -84,25 +87,23 @@ citizen_aqualand_device_open (dc_device_t **out, dc_context_t *context, const ch int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (4800 8N1). rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -112,6 +113,12 @@ citizen_aqualand_device_open (dc_device_t **out, dc_context_t *context, const ch *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/cressi_edy.c b/src/cressi_edy.c index 2a7b271..602ca0d 100644 --- a/src/cressi_edy.c +++ b/src/cressi_edy.c @@ -236,11 +236,14 @@ cressi_edy_quit (cressi_edy_device_t *device) dc_status_t cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + cressi_edy_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - cressi_edy_device_t *device = (cressi_edy_device_t *) malloc (sizeof (cressi_edy_device_t)); + device = (cressi_edy_device_t *) malloc (sizeof (cressi_edy_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -259,34 +262,31 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (1200 8N1). rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR and clear the RTS line. if (serial_set_dtr (device->port, 1) == -1 || serial_set_rts (device->port, 0) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -308,9 +308,8 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -320,6 +319,12 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/cressi_leonardo.c b/src/cressi_leonardo.c index 2d6d177..c02bea7 100644 --- a/src/cressi_leonardo.c +++ b/src/cressi_leonardo.c @@ -74,11 +74,14 @@ static const dc_device_vtable_t cressi_leonardo_device_vtable = { dc_status_t cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + cressi_leonardo_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - cressi_leonardo_device_t *device = (cressi_leonardo_device_t *) malloc (sizeof (cressi_leonardo_device_t)); + device = (cressi_leonardo_device_t *) malloc (sizeof (cressi_leonardo_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -95,34 +98,31 @@ cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const cha int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Clear the DTR and set the RTS line. if (serial_set_dtr (device->port, 0) == -1 || serial_set_rts (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } serial_sleep (device->port, 100); @@ -131,6 +131,12 @@ cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const cha *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } static dc_status_t diff --git a/src/diverite_nitekq.c b/src/diverite_nitekq.c index 6ca5356..2a7c4b4 100644 --- a/src/diverite_nitekq.c +++ b/src/diverite_nitekq.c @@ -149,11 +149,14 @@ diverite_nitekq_handshake (diverite_nitekq_device_t *device) dc_status_t diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + diverite_nitekq_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - diverite_nitekq_device_t *device = (diverite_nitekq_device_t *) malloc (sizeof (diverite_nitekq_device_t)); + device = (diverite_nitekq_device_t *) malloc (sizeof (diverite_nitekq_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -170,25 +173,23 @@ diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const cha int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -196,18 +197,21 @@ diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const cha serial_flush (device->port, SERIAL_QUEUE_BOTH); // Perform the handshaking. - dc_status_t status = diverite_nitekq_handshake (device); + status = diverite_nitekq_handshake (device); if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to handshake."); - serial_close (device->port); - free (device); - return status; + goto error_close; } - *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/divesystem_idive.c b/src/divesystem_idive.c index 585bd58..af36cd0 100644 --- a/src/divesystem_idive.c +++ b/src/divesystem_idive.c @@ -110,11 +110,14 @@ divesystem_idive_device_open (dc_device_t **out, dc_context_t *context, const ch dc_status_t divesystem_idive_device_open2 (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) { + dc_status_t status = DC_STATUS_SUCCESS; + divesystem_idive_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - divesystem_idive_device_t *device = (divesystem_idive_device_t *) malloc (sizeof (divesystem_idive_device_t)); + device = (divesystem_idive_device_t *) malloc (sizeof (divesystem_idive_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -132,25 +135,23 @@ divesystem_idive_device_open2 (dc_device_t **out, dc_context_t *context, const c int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -160,6 +161,12 @@ divesystem_idive_device_open2 (dc_device_t **out, dc_context_t *context, const c *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/hw_frog.c b/src/hw_frog.c index 43bc307..7c7b45a 100644 --- a/src/hw_frog.c +++ b/src/hw_frog.c @@ -202,11 +202,14 @@ hw_frog_transfer (hw_frog_device_t *device, dc_status_t hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + hw_frog_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - hw_frog_device_t *device = (hw_frog_device_t *) malloc (sizeof (hw_frog_device_t)); + device = (hw_frog_device_t *) malloc (sizeof (hw_frog_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -223,25 +226,23 @@ hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name) int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -249,17 +250,21 @@ hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name) serial_flush (device->port, SERIAL_QUEUE_BOTH); // Send the init command. - dc_status_t status = hw_frog_transfer (device, NULL, INIT, NULL, 0, NULL, 0); + status = hw_frog_transfer (device, NULL, INIT, NULL, 0, NULL, 0); if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to send the command."); - serial_close (device->port); - free (device); - return status; + goto error_close; } *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/hw_ostc.c b/src/hw_ostc.c index d994d38..d62466e 100644 --- a/src/hw_ostc.c +++ b/src/hw_ostc.c @@ -125,11 +125,14 @@ hw_ostc_send (hw_ostc_device_t *device, unsigned char cmd, unsigned int echo) dc_status_t hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + hw_ostc_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - hw_ostc_device_t *device = (hw_ostc_device_t *) malloc (sizeof (hw_ostc_device_t)); + device = (hw_ostc_device_t *) malloc (sizeof (hw_ostc_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -146,25 +149,23 @@ hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name) int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data. if (serial_set_timeout (device->port, 4000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -174,6 +175,12 @@ hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name) *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index fa0ec79..a7bc9a3 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -275,11 +275,14 @@ hw_ostc3_transfer (hw_ostc3_device_t *device, dc_status_t hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + hw_ostc3_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - hw_ostc3_device_t *device = (hw_ostc3_device_t *) malloc (sizeof (hw_ostc3_device_t)); + device = (hw_ostc3_device_t *) malloc (sizeof (hw_ostc3_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -296,25 +299,23 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -326,6 +327,12 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/irda.c b/src/irda.c index b15d09f..3903b7b 100644 --- a/src/irda.c +++ b/src/irda.c @@ -92,8 +92,7 @@ irda_socket_open (irda_t **out, dc_context_t *context) WORD wVersionRequested = MAKEWORD (2, 2); if (WSAStartup (wVersionRequested, &wsaData) != 0) { SYSERROR (context, ERRNO); - free (device); - return -1; + goto error_free; } // Confirm that the winsock dll supports version 2.2. @@ -102,9 +101,7 @@ irda_socket_open (irda_t **out, dc_context_t *context) if (LOBYTE (wsaData.wVersion) != 2 || HIBYTE (wsaData.wVersion) != 2) { ERROR (context, "Incorrect winsock version."); - WSACleanup (); - free (device); - return -1; + goto error_wsacleanup; } #endif @@ -116,16 +113,20 @@ irda_socket_open (irda_t **out, dc_context_t *context) if (device->fd == -1) { #endif SYSERROR (context, ERRNO); -#ifdef _WIN32 - WSACleanup (); -#endif - free (device); - return -1; + goto error_wsacleanup; } *out = device; return 0; + +error_wsacleanup: +#ifdef _WIN32 + WSACleanup (); +error_free: +#endif + free (device); + return -1; } diff --git a/src/mares_darwin.c b/src/mares_darwin.c index 957e7d9..1113a46 100644 --- a/src/mares_darwin.c +++ b/src/mares_darwin.c @@ -96,11 +96,14 @@ static const mares_darwin_layout_t mares_darwinair_layout = { dc_status_t mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) { + dc_status_t status = DC_STATUS_SUCCESS; + mares_darwin_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - mares_darwin_device_t *device = (mares_darwin_device_t *) malloc (sizeof (mares_darwin_device_t)); + device = (mares_darwin_device_t *) malloc (sizeof (mares_darwin_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -121,34 +124,31 @@ mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char * int rc = serial_open (&device->base.port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->base.port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->base.port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->base.port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->base.port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR/RTS lines. if (serial_set_dtr (device->base.port, 1) == -1 || serial_set_rts (device->base.port, 1) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->base.port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -162,6 +162,12 @@ mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char * *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->base.port); +error_free: + free (device); + return status; } static dc_status_t diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 02a13ad..af6b1de 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -214,11 +214,14 @@ mares_iconhd_transfer (mares_iconhd_device_t *device, dc_status_t mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) { + dc_status_t status = DC_STATUS_SUCCESS; + mares_iconhd_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - mares_iconhd_device_t *device = (mares_iconhd_device_t *) malloc (sizeof (mares_iconhd_device_t)); + device = (mares_iconhd_device_t *) malloc (sizeof (mares_iconhd_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -239,25 +242,23 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (115200 8E1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR/RTS lines. @@ -265,9 +266,8 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * serial_set_rts (device->port, 0) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -275,12 +275,10 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * // Send the version command. unsigned char command[] = {0xC2, 0x67}; - dc_status_t status = mares_iconhd_transfer (device, command, sizeof (command), + status = mares_iconhd_transfer (device, command, sizeof (command), device->version, sizeof (device->version)); if (status != DC_STATUS_SUCCESS) { - serial_close (device->port); - free (device); - return status; + goto error_close; } // Autodetect the model using the version packet. @@ -314,6 +312,12 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/mares_nemo.c b/src/mares_nemo.c index e479b02..840c27e 100644 --- a/src/mares_nemo.c +++ b/src/mares_nemo.c @@ -90,11 +90,14 @@ static const mares_common_layout_t mares_nemo_apneist_layout = { dc_status_t mares_nemo_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + mares_nemo_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - mares_nemo_device_t *device = (mares_nemo_device_t *) malloc (sizeof (mares_nemo_device_t)); + device = (mares_nemo_device_t *) malloc (sizeof (mares_nemo_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -111,34 +114,31 @@ mares_nemo_device_open (dc_device_t **out, dc_context_t *context, const char *na int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR/RTS lines. if (serial_set_dtr (device->port, 1) == -1 || serial_set_rts (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -147,6 +147,12 @@ mares_nemo_device_open (dc_device_t **out, dc_context_t *context, const char *na *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/mares_puck.c b/src/mares_puck.c index 361a753..2b85b9f 100644 --- a/src/mares_puck.c +++ b/src/mares_puck.c @@ -88,11 +88,14 @@ static const mares_common_layout_t mares_nemowide_layout = { dc_status_t mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + mares_puck_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - mares_puck_device_t *device = (mares_puck_device_t *) malloc (sizeof (mares_puck_device_t)); + device = (mares_puck_device_t *) malloc (sizeof (mares_puck_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -109,34 +112,31 @@ mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *na int rc = serial_open (&device->base.port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (38400 8N1). rc = serial_configure (device->base.port, 38400, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->base.port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->base.port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->base.port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Clear the DTR/RTS lines. if (serial_set_dtr (device->base.port, 0) == -1 || serial_set_rts (device->base.port, 0) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->base.port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -144,11 +144,9 @@ mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *na // Identify the model number. unsigned char header[PACKETSIZE] = {0}; - dc_status_t status = mares_common_device_read ((dc_device_t *) device, 0, header, sizeof (header)); + status = mares_common_device_read ((dc_device_t *) device, 0, header, sizeof (header)); if (status != DC_STATUS_SUCCESS) { - serial_close (device->base.port); - free (device); - return status; + goto error_close; } // Override the base class values. @@ -171,6 +169,12 @@ mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *na *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->base.port); +error_free: + free (device); + return status; } diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 98a8273..c009ab1 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -520,13 +520,15 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char dc_status_t oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) - { + dc_status_t status = DC_STATUS_SUCCESS; + oceanic_atom2_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - oceanic_atom2_device_t *device = (oceanic_atom2_device_t *) malloc (sizeof (oceanic_atom2_device_t)); + device = (oceanic_atom2_device_t *) malloc (sizeof (oceanic_atom2_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -546,8 +548,8 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Get the correct baudrate. @@ -560,17 +562,15 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char rc = serial_configure (device->port, baudrate, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Give the interface 100 ms to settle and draw power up. @@ -586,11 +586,9 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char // Switch the device from surface mode into download mode. Before sending // this command, the device needs to be in PC mode (automatically activated // by connecting the device), or already in download mode. - dc_status_t status = oceanic_atom2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); + status = oceanic_atom2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); if (status != DC_STATUS_SUCCESS) { - serial_close (device->port); - free (device); - return status; + goto error_close; } // Override the base class values. @@ -641,6 +639,12 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/oceanic_veo250.c b/src/oceanic_veo250.c index c7828e4..b21f6a0 100644 --- a/src/oceanic_veo250.c +++ b/src/oceanic_veo250.c @@ -221,11 +221,14 @@ oceanic_veo250_quit (oceanic_veo250_device_t *device) dc_status_t oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + oceanic_veo250_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - oceanic_veo250_device_t *device = (oceanic_veo250_device_t *) malloc (sizeof (oceanic_veo250_device_t)); + device = (oceanic_veo250_device_t *) malloc (sizeof (oceanic_veo250_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -246,34 +249,31 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000 ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR and RTS lines. if (serial_set_dtr (device->port, 1) == -1 || serial_set_rts (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Give the interface 100 ms to settle and draw power up. @@ -283,11 +283,9 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char serial_flush (device->port, SERIAL_QUEUE_BOTH); // Initialize the data cable (PPS mode). - dc_status_t status = oceanic_veo250_init (device); + status = oceanic_veo250_init (device); if (status != DC_STATUS_SUCCESS) { - serial_close (device->port); - free (device); - return status; + goto error_close; } // Delay the sending of the version command. @@ -298,14 +296,18 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char // the user), or already in download mode. status = oceanic_veo250_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); if (status != DC_STATUS_SUCCESS) { - serial_close (device->port); - free (device); - return status; + goto error_close; } *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/oceanic_vtpro.c b/src/oceanic_vtpro.c index 5696045..92faf7a 100644 --- a/src/oceanic_vtpro.c +++ b/src/oceanic_vtpro.c @@ -254,11 +254,14 @@ oceanic_vtpro_calibrate (oceanic_vtpro_device_t *device) dc_status_t oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + oceanic_vtpro_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - oceanic_vtpro_device_t *device = (oceanic_vtpro_device_t *) malloc (sizeof (oceanic_vtpro_device_t)); + device = (oceanic_vtpro_device_t *) malloc (sizeof (oceanic_vtpro_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -277,34 +280,31 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000 ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR and RTS lines. if (serial_set_dtr (device->port, 1) == -1 || serial_set_rts (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Give the interface 100 ms to settle and draw power up. @@ -314,11 +314,9 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char serial_flush (device->port, SERIAL_QUEUE_BOTH); // Initialize the data cable (MOD mode). - dc_status_t status = oceanic_vtpro_init (device); + status = oceanic_vtpro_init (device); if (status != DC_STATUS_SUCCESS) { - serial_close (device->port); - free (device); - return status; + goto error_close; } // Switch the device from surface mode into download mode. Before sending @@ -326,9 +324,7 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char // the user), or already in download mode. status = oceanic_vtpro_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); if (status != DC_STATUS_SUCCESS) { - serial_close (device->port); - free (device); - return status; + goto error_close; } // Calibrate the device. Although calibration is optional, it's highly @@ -336,9 +332,7 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char // when processing the command itself is quite slow. status = oceanic_vtpro_calibrate (device); if (status != DC_STATUS_SUCCESS) { - serial_close (device->port); - free (device); - return status; + goto error_close; } // Override the base class values. @@ -351,6 +345,12 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/reefnet_sensus.c b/src/reefnet_sensus.c index 6504342..ec0ee07 100644 --- a/src/reefnet_sensus.c +++ b/src/reefnet_sensus.c @@ -89,11 +89,14 @@ reefnet_sensus_cancel (reefnet_sensus_device_t *device) dc_status_t reefnet_sensus_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + reefnet_sensus_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - reefnet_sensus_device_t *device = (reefnet_sensus_device_t *) malloc (sizeof (reefnet_sensus_device_t)); + device = (reefnet_sensus_device_t *) malloc (sizeof (reefnet_sensus_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -114,25 +117,23 @@ reefnet_sensus_device_open (dc_device_t **out, dc_context_t *context, const char int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (19200 8N1). rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000 ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -141,6 +142,12 @@ reefnet_sensus_device_open (dc_device_t **out, dc_context_t *context, const char *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/reefnet_sensuspro.c b/src/reefnet_sensuspro.c index b462f55..d20f432 100644 --- a/src/reefnet_sensuspro.c +++ b/src/reefnet_sensuspro.c @@ -68,11 +68,14 @@ static const dc_device_vtable_t reefnet_sensuspro_device_vtable = { dc_status_t reefnet_sensuspro_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + reefnet_sensuspro_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - reefnet_sensuspro_device_t *device = (reefnet_sensuspro_device_t *) malloc (sizeof (reefnet_sensuspro_device_t)); + device = (reefnet_sensuspro_device_t *) malloc (sizeof (reefnet_sensuspro_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -92,25 +95,23 @@ reefnet_sensuspro_device_open (dc_device_t **out, dc_context_t *context, const c int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (19200 8N1). rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -119,6 +120,12 @@ reefnet_sensuspro_device_open (dc_device_t **out, dc_context_t *context, const c *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/reefnet_sensusultra.c b/src/reefnet_sensusultra.c index 6405830..f16c535 100644 --- a/src/reefnet_sensusultra.c +++ b/src/reefnet_sensusultra.c @@ -77,11 +77,14 @@ static const dc_device_vtable_t reefnet_sensusultra_device_vtable = { dc_status_t reefnet_sensusultra_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + reefnet_sensusultra_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t *) malloc (sizeof (reefnet_sensusultra_device_t)); + device = (reefnet_sensusultra_device_t *) malloc (sizeof (reefnet_sensusultra_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -101,25 +104,23 @@ reefnet_sensusultra_device_open (dc_device_t **out, dc_context_t *context, const int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -128,6 +129,12 @@ reefnet_sensusultra_device_open (dc_device_t **out, dc_context_t *context, const *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/serial_posix.c b/src/serial_posix.c index af4beba..ee9312f 100644 --- a/src/serial_posix.c +++ b/src/serial_posix.c @@ -157,17 +157,14 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) device->fd = open (name, O_RDWR | O_NOCTTY | O_NONBLOCK); if (device->fd == -1) { SYSERROR (context, errno); - free (device); - return -1; // Error during open call. + goto error_free; } #ifndef ENABLE_PTY // Enable exclusive access mode. if (ioctl (device->fd, TIOCEXCL, NULL) != 0) { SYSERROR (context, errno); - close (device->fd); - free (device); - return -1; + goto error_close; } #endif @@ -177,14 +174,18 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) // file descriptor represents a terminal device. if (tcgetattr (device->fd, &device->tty) != 0) { SYSERROR (context, errno); - close (device->fd); - free (device); - return -1; + goto error_close; } *out = device; return 0; + +error_close: + close (device->fd); +error_free: + free (device); + return -1; } // diff --git a/src/serial_win32.c b/src/serial_win32.c index 9d5572c..00aeb4d 100644 --- a/src/serial_win32.c +++ b/src/serial_win32.c @@ -150,8 +150,7 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) NULL); if (device->hFile == INVALID_HANDLE_VALUE) { SYSERROR (context, GetLastError ()); - free (device); - return -1; + goto error_free; } // Retrieve the current communication settings and timeouts, @@ -161,14 +160,18 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) if (!GetCommState (device->hFile, &device->dcb) || !GetCommTimeouts (device->hFile, &device->timeouts)) { SYSERROR (context, GetLastError ()); - CloseHandle (device->hFile); - free (device); - return -1; + goto error_close; } *out = device; return 0; + +error_close: + CloseHandle (device->hFile); +error_free: + free (device); + return -1; } // diff --git a/src/shearwater_common.c b/src/shearwater_common.c index eabed11..ac53a7e 100644 --- a/src/shearwater_common.c +++ b/src/shearwater_common.c @@ -40,6 +40,8 @@ dc_status_t shearwater_common_open (shearwater_common_device_t *device, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + // Open the device. int rc = serial_open (&device->port, context, name); if (rc == -1) { @@ -51,15 +53,15 @@ shearwater_common_open (shearwater_common_device_t *device, dc_context_t *contex rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -67,6 +69,10 @@ shearwater_common_open (shearwater_common_device_t *device, dc_context_t *contex serial_flush (device->port, SERIAL_QUEUE_BOTH); return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); + return status; } diff --git a/src/shearwater_petrel.c b/src/shearwater_petrel.c index 3534a26..1bf98f5 100644 --- a/src/shearwater_petrel.c +++ b/src/shearwater_petrel.c @@ -79,13 +79,14 @@ str2num (unsigned char data[], unsigned int size, unsigned int offset) dc_status_t shearwater_petrel_device_open (dc_device_t **out, dc_context_t *context, const char *name) { - dc_status_t rc = DC_STATUS_SUCCESS; + dc_status_t status = DC_STATUS_SUCCESS; + shearwater_petrel_device_t *device = NULL; if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - shearwater_petrel_device_t *device = (shearwater_petrel_device_t *) malloc (sizeof (shearwater_petrel_device_t)); + device = (shearwater_petrel_device_t *) malloc (sizeof (shearwater_petrel_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -98,15 +99,18 @@ shearwater_petrel_device_open (dc_device_t **out, dc_context_t *context, const c memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - rc = shearwater_common_open (&device->base, context, name); - if (rc != DC_STATUS_SUCCESS) { - free (device); - return rc; + status = shearwater_common_open (&device->base, context, name); + if (status != DC_STATUS_SUCCESS) { + goto error_free; } *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_free: + free (device); + return status; } diff --git a/src/shearwater_predator.c b/src/shearwater_predator.c index e8a44ac..7fa6f83 100644 --- a/src/shearwater_predator.c +++ b/src/shearwater_predator.c @@ -65,13 +65,14 @@ static const dc_device_vtable_t shearwater_predator_device_vtable = { dc_status_t shearwater_predator_device_open (dc_device_t **out, dc_context_t *context, const char *name) { - dc_status_t rc = DC_STATUS_SUCCESS; + dc_status_t status = DC_STATUS_SUCCESS; + shearwater_predator_device_t *device = NULL; if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - shearwater_predator_device_t *device = (shearwater_predator_device_t *) malloc (sizeof (shearwater_predator_device_t)); + device = (shearwater_predator_device_t *) malloc (sizeof (shearwater_predator_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -84,15 +85,18 @@ shearwater_predator_device_open (dc_device_t **out, dc_context_t *context, const memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - rc = shearwater_common_open (&device->base, context, name); - if (rc != DC_STATUS_SUCCESS) { - free (device); - return rc; + status = shearwater_common_open (&device->base, context, name); + if (status != DC_STATUS_SUCCESS) { + goto error_free; } *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_free: + free (device); + return status; } diff --git a/src/suunto_d9.c b/src/suunto_d9.c index fa4a263..c0903bb 100644 --- a/src/suunto_d9.c +++ b/src/suunto_d9.c @@ -129,11 +129,14 @@ suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model) dc_status_t suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) { + dc_status_t status = DC_STATUS_SUCCESS; + suunto_d9_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - suunto_d9_device_t *device = (suunto_d9_device_t *) malloc (sizeof (suunto_d9_device_t)); + device = (suunto_d9_device_t *) malloc (sizeof (suunto_d9_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -149,33 +152,30 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000 ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR line (power supply for the interface). if (serial_set_dtr (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Give the interface 100 ms to settle and draw power up. @@ -185,12 +185,10 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam serial_flush (device->port, SERIAL_QUEUE_BOTH); // Try to autodetect the protocol variant. - dc_status_t status = suunto_d9_device_autodetect (device, model); + status = suunto_d9_device_autodetect (device, model); if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to identify the protocol variant."); - serial_close (device->port); - free (device); - return status; + goto error_close; } // Override the base class values. @@ -205,6 +203,12 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/suunto_eon.c b/src/suunto_eon.c index c9c78d2..e71e315 100644 --- a/src/suunto_eon.c +++ b/src/suunto_eon.c @@ -71,11 +71,14 @@ static const suunto_common_layout_t suunto_eon_layout = { dc_status_t suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + suunto_eon_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - suunto_eon_device_t *device = (suunto_eon_device_t *) malloc (sizeof (suunto_eon_device_t)); + device = (suunto_eon_device_t *) malloc (sizeof (suunto_eon_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -91,38 +94,41 @@ suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *na int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (1200 8N2). rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Clear the RTS line. if (serial_set_rts (device->port, 0)) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index feb01a3..8bd0350 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -556,6 +556,7 @@ static int initialize_eonsteel(suunto_eonsteel_device_t *eon) dc_status_t suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) { + dc_status_t status = DC_STATUS_SUCCESS; suunto_eonsteel_device_t *eon; if (out == NULL) @@ -574,16 +575,15 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char if (libusb_init(&eon->ctx)) { ERROR(context, "libusb_init() failed"); - free(eon); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } eon->handle = libusb_open_device_with_vid_pid(eon->ctx, 0x1493, 0x0030); if (!eon->handle) { ERROR(context, "unable to open device"); - libusb_exit(eon->ctx); - free(eon); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_usb_exit; } #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) @@ -594,15 +594,21 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char if (initialize_eonsteel(eon) < 0) { ERROR(context, "unable to initialize device"); - libusb_close(eon->handle); - libusb_exit(eon->ctx); - free(eon); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_usb_close; } *out = (dc_device_t *) eon; return DC_STATUS_SUCCESS; + +error_usb_close: + libusb_close(eon->handle); +error_usb_exit: + libusb_exit(eon->ctx); +error_free: + free(eon); + return status; } static int count_dir_entries(struct directory_entry *de) diff --git a/src/suunto_solution.c b/src/suunto_solution.c index 1d7b227..421a090 100644 --- a/src/suunto_solution.c +++ b/src/suunto_solution.c @@ -65,11 +65,14 @@ static const dc_device_vtable_t suunto_solution_device_vtable = { dc_status_t suunto_solution_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + suunto_solution_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - suunto_solution_device_t *device = (suunto_solution_device_t *) malloc (sizeof (suunto_solution_device_t)); + device = (suunto_solution_device_t *) malloc (sizeof (suunto_solution_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -85,38 +88,41 @@ suunto_solution_device_open (dc_device_t **out, dc_context_t *context, const cha int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (1200 8N2). rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Clear the RTS line. if (serial_set_rts (device->port, 0)) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/suunto_vyper.c b/src/suunto_vyper.c index b259259..03fbc4a 100644 --- a/src/suunto_vyper.c +++ b/src/suunto_vyper.c @@ -91,11 +91,14 @@ static const suunto_common_layout_t suunto_spyder_layout = { dc_status_t suunto_vyper_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + suunto_vyper_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - suunto_vyper_device_t *device = (suunto_vyper_device_t *) malloc (sizeof (suunto_vyper_device_t)); + device = (suunto_vyper_device_t *) malloc (sizeof (suunto_vyper_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -111,33 +114,30 @@ suunto_vyper_device_open (dc_device_t **out, dc_context_t *context, const char * int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status= DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (2400 8O1). rc = serial_configure (device->port, 2400, 8, SERIAL_PARITY_ODD, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR line (power supply for the interface). if (serial_set_dtr (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Give the interface 100 ms to settle and draw power up. @@ -149,6 +149,12 @@ suunto_vyper_device_open (dc_device_t **out, dc_context_t *context, const char * *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/suunto_vyper2.c b/src/suunto_vyper2.c index e6dbd27..efba846 100644 --- a/src/suunto_vyper2.c +++ b/src/suunto_vyper2.c @@ -80,11 +80,14 @@ static const suunto_common2_layout_t suunto_helo2_layout = { dc_status_t suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + suunto_vyper2_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - suunto_vyper2_device_t *device = (suunto_vyper2_device_t *) malloc (sizeof (suunto_vyper2_device_t)); + device = (suunto_vyper2_device_t *) malloc (sizeof (suunto_vyper2_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -100,33 +103,30 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000 ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the DTR line (power supply for the interface). if (serial_set_dtr (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Give the interface 100 ms to settle and draw power up. @@ -139,12 +139,10 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char serial_set_halfduplex (device->port, 1); // Read the version info. - dc_status_t status = suunto_common2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); + status = suunto_common2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to read the version info."); - serial_close (device->port); - free (device); - return status; + goto error_close; } // Override the base class values. @@ -157,6 +155,12 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/uwatec_aladin.c b/src/uwatec_aladin.c index d01a92a..796e867 100644 --- a/src/uwatec_aladin.c +++ b/src/uwatec_aladin.c @@ -74,11 +74,14 @@ static const dc_device_vtable_t uwatec_aladin_device_vtable = { dc_status_t uwatec_aladin_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + uwatec_aladin_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - uwatec_aladin_device_t *device = (uwatec_aladin_device_t *) malloc (sizeof (uwatec_aladin_device_t)); + device = (uwatec_aladin_device_t *) malloc (sizeof (uwatec_aladin_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -97,39 +100,42 @@ uwatec_aladin_device_open (dc_device_t **out, dc_context_t *context, const char int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (19200 8N1). rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (INFINITE). if (serial_set_timeout (device->port, -1) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Clear the RTS line and set the DTR line. if (serial_set_dtr (device->port, 1) == -1 || serial_set_rts (device->port, 0) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/uwatec_memomouse.c b/src/uwatec_memomouse.c index 101ff19..9608cb5 100644 --- a/src/uwatec_memomouse.c +++ b/src/uwatec_memomouse.c @@ -70,11 +70,14 @@ static const dc_device_vtable_t uwatec_memomouse_device_vtable = { dc_status_t uwatec_memomouse_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + uwatec_memomouse_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - uwatec_memomouse_device_t *device = (uwatec_memomouse_device_t *) malloc (sizeof (uwatec_memomouse_device_t)); + device = (uwatec_memomouse_device_t *) malloc (sizeof (uwatec_memomouse_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -93,34 +96,31 @@ uwatec_memomouse_device_open (dc_device_t **out, dc_context_t *context, const ch int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Clear the RTS and DTR lines. if (serial_set_rts (device->port, 0) == -1 || serial_set_dtr (device->port, 0) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -129,6 +129,12 @@ uwatec_memomouse_device_open (dc_device_t **out, dc_context_t *context, const ch *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/uwatec_meridian.c b/src/uwatec_meridian.c index fbf26c7..4828a32 100644 --- a/src/uwatec_meridian.c +++ b/src/uwatec_meridian.c @@ -186,11 +186,14 @@ uwatec_meridian_handshake (uwatec_meridian_device_t *device) dc_status_t uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + uwatec_meridian_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - uwatec_meridian_device_t *device = (uwatec_meridian_device_t *) malloc (sizeof (uwatec_meridian_device_t)); + device = (uwatec_meridian_device_t *) malloc (sizeof (uwatec_meridian_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -209,25 +212,23 @@ uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const cha int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (57600 8N1). rc = serial_configure (device->port, 57600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (3000ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -239,6 +240,12 @@ uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const cha *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; } diff --git a/src/uwatec_smart.c b/src/uwatec_smart.c index 124ffca..2b327ba 100644 --- a/src/uwatec_smart.c +++ b/src/uwatec_smart.c @@ -145,11 +145,14 @@ uwatec_smart_handshake (uwatec_smart_device_t *device) dc_status_t uwatec_smart_device_open (dc_device_t **out, dc_context_t *context) { + dc_status_t status = DC_STATUS_SUCCESS; + uwatec_smart_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - uwatec_smart_device_t *device = (uwatec_smart_device_t *) malloc (sizeof (uwatec_smart_device_t)); + device = (uwatec_smart_device_t *) malloc (sizeof (uwatec_smart_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -169,33 +172,30 @@ uwatec_smart_device_open (dc_device_t **out, dc_context_t *context) int rc = irda_socket_open (&device->socket, context); if (rc == -1) { ERROR (context, "Failed to open the irda socket."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Discover the device. rc = irda_socket_discover (device->socket, uwatec_smart_discovery, device); if (rc == -1) { ERROR (context, "Failed to discover the device."); - irda_socket_close (device->socket); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } if (device->address == 0) { ERROR (context, "No dive computer found."); - irda_socket_close (device->socket); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Connect the device. rc = irda_socket_connect_lsap (device->socket, device->address, 1); if (rc == -1) { ERROR (context, "Failed to connect the device."); - irda_socket_close (device->socket); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Perform the handshaking. @@ -204,6 +204,12 @@ uwatec_smart_device_open (dc_device_t **out, dc_context_t *context) *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; + +error_close: + irda_socket_close (device->socket); +error_free: + free (device); + return status; } diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index 9009fbe..c06e5e2 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -512,11 +512,14 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) dc_status_t uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int devtime, dc_ticks_t systime) { + dc_status_t status = DC_STATUS_SUCCESS; + uwatec_smart_parser_t *parser = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - uwatec_smart_parser_t *parser = (uwatec_smart_parser_t *) malloc (sizeof (uwatec_smart_parser_t)); + parser = (uwatec_smart_parser_t *) malloc (sizeof (uwatec_smart_parser_t)); if (parser == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -594,8 +597,8 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i parser->nevents[0] = C_ARRAY_SIZE (uwatec_smart_tec_events_0); break; default: - free (parser); - return DC_STATUS_INVALIDARGS; + status = DC_STATUS_INVALIDARGS; + goto error_free; } parser->cached = 0; @@ -616,6 +619,10 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i *out = (dc_parser_t*) parser; return DC_STATUS_SUCCESS; + +error_free: + free (parser); + return status; } diff --git a/src/zeagle_n2ition3.c b/src/zeagle_n2ition3.c index 1c1dcf1..a98825a 100644 --- a/src/zeagle_n2ition3.c +++ b/src/zeagle_n2ition3.c @@ -137,11 +137,14 @@ zeagle_n2ition3_init (zeagle_n2ition3_device_t *device) dc_status_t zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + zeagle_n2ition3_device_t *device = NULL; + if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. - zeagle_n2ition3_device_t *device = (zeagle_n2ition3_device_t *) malloc (sizeof (zeagle_n2ition3_device_t)); + device = (zeagle_n2ition3_device_t *) malloc (sizeof (zeagle_n2ition3_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; @@ -158,25 +161,23 @@ zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const cha int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_free; } // Set the serial communication protocol (4800 8N1). rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); - serial_close (device->port); - free (device); - return DC_STATUS_IO; + status = DC_STATUS_IO; + goto error_close; } // Make sure everything is in a sane state. @@ -188,6 +189,12 @@ zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const cha *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; + +error_close: + serial_close (device->port); +error_free: + free (device); + return status; }