mirror of
git://sigrok.org/libserialport
synced 2023-08-10 21:13:24 +03:00
Add an example of proper error handling.
This commit is contained in:
parent
6dba844779
commit
4720053160
@ -66,7 +66,8 @@ EXTRA_DIST = Doxyfile \
|
|||||||
examples/README \
|
examples/README \
|
||||||
examples/list_ports.c \
|
examples/list_ports.c \
|
||||||
examples/port_info.c \
|
examples/port_info.c \
|
||||||
examples/port_config.c
|
examples/port_config.c \
|
||||||
|
examples/handle_errors.c
|
||||||
|
|
||||||
MAINTAINERCLEANFILES = ChangeLog
|
MAINTAINERCLEANFILES = ChangeLog
|
||||||
|
|
||||||
|
1
examples/.gitignore
vendored
1
examples/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
handle_errors
|
||||||
list_ports
|
list_ports
|
||||||
port_info
|
port_info
|
||||||
port_config
|
port_config
|
||||||
|
116
examples/handle_errors.c
Normal file
116
examples/handle_errors.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include <libserialport.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Example of how to handle errors from libserialport.
|
||||||
|
*
|
||||||
|
* This example file is released to the public domain. */
|
||||||
|
|
||||||
|
/* Pointers used in the program to resources that may need to be freed. */
|
||||||
|
struct sp_port **port_list = NULL;
|
||||||
|
struct sp_port_config *config = NULL;
|
||||||
|
struct sp_port *port = NULL;
|
||||||
|
|
||||||
|
/* Example of a function to clean up and exit the program with a given return code. */
|
||||||
|
void end_program(int return_code)
|
||||||
|
{
|
||||||
|
/* Free any structures we allocated. */
|
||||||
|
if (port_list != NULL)
|
||||||
|
sp_free_port_list(port_list);
|
||||||
|
if (config != NULL)
|
||||||
|
sp_free_config(config);
|
||||||
|
if (port != NULL)
|
||||||
|
sp_free_port(port);
|
||||||
|
|
||||||
|
/* Exit with the given return code. */
|
||||||
|
exit(return_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Example of a helper function for error handling. */
|
||||||
|
int check(enum sp_return result)
|
||||||
|
{
|
||||||
|
int error_code;
|
||||||
|
char *error_message;
|
||||||
|
switch (result) {
|
||||||
|
|
||||||
|
/* Handle each of the four negative error codes that can be returned.
|
||||||
|
*
|
||||||
|
* In this example, we will end the program on any error, using
|
||||||
|
* a different return code for each possible class of error. */
|
||||||
|
|
||||||
|
case SP_ERR_ARG:
|
||||||
|
/* When SP_ERR_ARG is returned, there was a problem with one
|
||||||
|
* or more of the arguments passed to the function, e.g. a null
|
||||||
|
* pointer or an invalid value. This generally implies a bug in
|
||||||
|
* the calling code. */
|
||||||
|
printf("Error: Invalid argument.\n");
|
||||||
|
end_program(1);
|
||||||
|
|
||||||
|
case SP_ERR_FAIL:
|
||||||
|
/* When SP_ERR_FAIL is returned, there was an error from the OS,
|
||||||
|
* which we can obtain the error code and message for. These
|
||||||
|
* calls must be made in the same thread as the call that
|
||||||
|
* returned SP_ERR_FAIL, and before any other system functions
|
||||||
|
* are called in that thread, or they may not return the
|
||||||
|
* correct results. */
|
||||||
|
error_code = sp_last_error_code();
|
||||||
|
error_message = sp_last_error_message();
|
||||||
|
printf("Error: Failed: OS error code: %d, message: '%s'\n",
|
||||||
|
error_code, error_message);
|
||||||
|
/* The error message should be freed after use. */
|
||||||
|
sp_free_error_message(error_message);
|
||||||
|
end_program(2);
|
||||||
|
|
||||||
|
case SP_ERR_SUPP:
|
||||||
|
/* When SP_ERR_SUPP is returned, the function was asked to do
|
||||||
|
* something that isn't supported by the current OS or device,
|
||||||
|
* or that libserialport doesn't know how to do in the current
|
||||||
|
* version. */
|
||||||
|
printf("Error: Not supported.\n");
|
||||||
|
end_program(3);
|
||||||
|
|
||||||
|
case SP_ERR_MEM:
|
||||||
|
/* When SP_ERR_MEM is returned, libserialport wasn't able to
|
||||||
|
* allocate some memory it needed. Since the library doesn't
|
||||||
|
* normally use any large data structures, this probably means
|
||||||
|
* the system is critically low on memory and recovery will
|
||||||
|
* require very careful handling. The library itself will
|
||||||
|
* always try to handle any allocation failure safely.
|
||||||
|
*
|
||||||
|
* In this example, we'll just try to exit gracefully without
|
||||||
|
* calling printf, which might need to allocate further memory. */
|
||||||
|
end_program(4);
|
||||||
|
|
||||||
|
case SP_OK:
|
||||||
|
default:
|
||||||
|
/* A return value of SP_OK, defined as zero, means that the
|
||||||
|
* operation succeeded. */
|
||||||
|
printf("Operation succeeded.\n");
|
||||||
|
|
||||||
|
/* Some fuctions can also return a value greater than zero to
|
||||||
|
* indicate a numeric result, such as the number of bytes read by
|
||||||
|
* sp_blocking_read(). So when writing an error handling wrapper
|
||||||
|
* function like this one, it's helpful to return the result so
|
||||||
|
* that it can be used. */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* Call some functions that should not result in errors. */
|
||||||
|
|
||||||
|
printf("Getting list of ports.\n");
|
||||||
|
check(sp_list_ports(&port_list));
|
||||||
|
|
||||||
|
printf("Creating a new port configuration.\n");
|
||||||
|
check(sp_new_config(&config));
|
||||||
|
|
||||||
|
/* Now make a function call that will result in an error. */
|
||||||
|
|
||||||
|
printf("Trying to find a port that doesn't exist.\n");
|
||||||
|
check(sp_get_port_by_name("NON-EXISTENT-PORT", &port));
|
||||||
|
|
||||||
|
/* We could now clean up and exit normally if an error hadn't occured. */
|
||||||
|
end_program(0);
|
||||||
|
}
|
@ -68,6 +68,7 @@
|
|||||||
* - @ref list_ports.c - Getting a list of ports present on the system.
|
* - @ref list_ports.c - Getting a list of ports present on the system.
|
||||||
* - @ref port_info.c - Getting information on a particular serial port.
|
* - @ref port_info.c - Getting information on a particular serial port.
|
||||||
* - @ref port_config.c - Accessing configuration settings of a port.
|
* - @ref port_config.c - Accessing configuration settings of a port.
|
||||||
|
* - @ref handle_errors.c - Handling errors returned from the library.
|
||||||
*
|
*
|
||||||
* These examples are linked with the API documentation. Each function
|
* These examples are linked with the API documentation. Each function
|
||||||
* in the API reference includes links to where it is used in an example
|
* in the API reference includes links to where it is used in an example
|
||||||
@ -1596,6 +1597,8 @@ SP_API enum sp_return sp_end_break(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* Obtaining error information.
|
* Obtaining error information.
|
||||||
*
|
*
|
||||||
|
* See @ref handle_errors.c for an example of error handling.
|
||||||
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1806,6 +1809,7 @@ SP_API const char *sp_get_lib_version_string(void);
|
|||||||
* @example list_ports.c Getting a list of ports present on the system.
|
* @example list_ports.c Getting a list of ports present on the system.
|
||||||
* @example port_info.c Getting information on a particular serial port.
|
* @example port_info.c Getting information on a particular serial port.
|
||||||
* @example port_config.c Accessing configuration settings of a port.
|
* @example port_config.c Accessing configuration settings of a port.
|
||||||
|
* @example handle_errors.c - Handling errors returned from the library.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user