]> sigrok.org Git - libserialport.git/blame - examples/handle_errors.c
Add an example of proper error handling.
[libserialport.git] / examples / handle_errors.c
CommitLineData
47200531
ML
1#include <libserialport.h>
2#include <stdio.h>
3#include <stdlib.h>
4
5/* Example of how to handle errors from libserialport.
6 *
7 * This example file is released to the public domain. */
8
9/* Pointers used in the program to resources that may need to be freed. */
10struct sp_port **port_list = NULL;
11struct sp_port_config *config = NULL;
12struct sp_port *port = NULL;
13
14/* Example of a function to clean up and exit the program with a given return code. */
15void end_program(int return_code)
16{
17 /* Free any structures we allocated. */
18 if (port_list != NULL)
19 sp_free_port_list(port_list);
20 if (config != NULL)
21 sp_free_config(config);
22 if (port != NULL)
23 sp_free_port(port);
24
25 /* Exit with the given return code. */
26 exit(return_code);
27}
28
29/* Example of a helper function for error handling. */
30int check(enum sp_return result)
31{
32 int error_code;
33 char *error_message;
34 switch (result) {
35
36 /* Handle each of the four negative error codes that can be returned.
37 *
38 * In this example, we will end the program on any error, using
39 * a different return code for each possible class of error. */
40
41 case SP_ERR_ARG:
42 /* When SP_ERR_ARG is returned, there was a problem with one
43 * or more of the arguments passed to the function, e.g. a null
44 * pointer or an invalid value. This generally implies a bug in
45 * the calling code. */
46 printf("Error: Invalid argument.\n");
47 end_program(1);
48
49 case SP_ERR_FAIL:
50 /* When SP_ERR_FAIL is returned, there was an error from the OS,
51 * which we can obtain the error code and message for. These
52 * calls must be made in the same thread as the call that
53 * returned SP_ERR_FAIL, and before any other system functions
54 * are called in that thread, or they may not return the
55 * correct results. */
56 error_code = sp_last_error_code();
57 error_message = sp_last_error_message();
58 printf("Error: Failed: OS error code: %d, message: '%s'\n",
59 error_code, error_message);
60 /* The error message should be freed after use. */
61 sp_free_error_message(error_message);
62 end_program(2);
63
64 case SP_ERR_SUPP:
65 /* When SP_ERR_SUPP is returned, the function was asked to do
66 * something that isn't supported by the current OS or device,
67 * or that libserialport doesn't know how to do in the current
68 * version. */
69 printf("Error: Not supported.\n");
70 end_program(3);
71
72 case SP_ERR_MEM:
73 /* When SP_ERR_MEM is returned, libserialport wasn't able to
74 * allocate some memory it needed. Since the library doesn't
75 * normally use any large data structures, this probably means
76 * the system is critically low on memory and recovery will
77 * require very careful handling. The library itself will
78 * always try to handle any allocation failure safely.
79 *
80 * In this example, we'll just try to exit gracefully without
81 * calling printf, which might need to allocate further memory. */
82 end_program(4);
83
84 case SP_OK:
85 default:
86 /* A return value of SP_OK, defined as zero, means that the
87 * operation succeeded. */
88 printf("Operation succeeded.\n");
89
90 /* Some fuctions can also return a value greater than zero to
91 * indicate a numeric result, such as the number of bytes read by
92 * sp_blocking_read(). So when writing an error handling wrapper
93 * function like this one, it's helpful to return the result so
94 * that it can be used. */
95 return result;
96 }
97}
98
99int main(int argc, char **argv)
100{
101 /* Call some functions that should not result in errors. */
102
103 printf("Getting list of ports.\n");
104 check(sp_list_ports(&port_list));
105
106 printf("Creating a new port configuration.\n");
107 check(sp_new_config(&config));
108
109 /* Now make a function call that will result in an error. */
110
111 printf("Trying to find a port that doesn't exist.\n");
112 check(sp_get_port_by_name("NON-EXISTENT-PORT", &port));
113
114 /* We could now clean up and exit normally if an error hadn't occured. */
115 end_program(0);
116}