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