diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2010-11-03 15:49:36 +0000 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2010-11-03 18:48:56 +0000 |
commit | 2066805a5d93b62beaf6653324715f0b62b06a05 (patch) | |
tree | 393ec11feb514069cf5cfb102b24a4d3a75d7e40 /generator | |
parent | d859c283c469b9d9124d90d0ac32024671372ed5 (diff) | |
download | libguestfs-2066805a5d93b62beaf6653324715f0b62b06a05.tar.gz libguestfs-2066805a5d93b62beaf6653324715f0b62b06a05.tar.xz libguestfs-2066805a5d93b62beaf6653324715f0b62b06a05.zip |
lib: Expose errno through new API guestfs_last_errno.
If either the daemon sends back an errno, or a system call
fails in the library, save the errno in the handle and then
make it available to callers through the guestfs_last_errno
function.
Diffstat (limited to 'generator')
-rw-r--r-- | generator/generator_c.ml | 13 | ||||
-rw-r--r-- | generator/generator_errnostring.ml | 66 | ||||
-rw-r--r-- | generator/generator_main.ml | 1 |
3 files changed, 78 insertions, 2 deletions
diff --git a/generator/generator_c.ml b/generator/generator_c.ml index 513bc1da..c1b2e632 100644 --- a/generator/generator_c.ml +++ b/generator/generator_c.ml @@ -438,6 +438,7 @@ and generate_client_actions () = #include \"guestfs-internal.h\" #include \"guestfs-internal-actions.h\" #include \"guestfs_protocol.h\" +#include \"errnostring.h\" /* Check the return message from a call for validity. */ static int @@ -802,7 +803,16 @@ check_state (guestfs_h *g, const char *caller) pr "\n"; pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n"; - pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" shortname; + pr " int errnum = 0;\n"; + pr " if (err.errno_string[0] != '\\0')\n"; + pr " errnum = guestfs___string_to_errno (err.errno_string);\n"; + pr " if (errnum <= 0)\n"; + pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" + shortname; + pr " else\n"; + pr " guestfs_error_errno (g, errnum, \"%%s: %%s\", \"%s\",\n" + shortname; + pr " err.error_message);\n"; pr " free (err.error_message);\n"; pr " free (err.errno_string);\n"; pr " guestfs___end_busy (g);\n"; @@ -995,6 +1005,7 @@ and generate_linker_script () = "guestfs_get_error_handler"; "guestfs_get_out_of_memory_handler"; "guestfs_get_private"; + "guestfs_last_errno"; "guestfs_last_error"; "guestfs_set_close_callback"; "guestfs_set_error_handler"; diff --git a/generator/generator_errnostring.ml b/generator/generator_errnostring.ml index d0a5734f..a0249892 100644 --- a/generator/generator_errnostring.ml +++ b/generator/generator_errnostring.ml @@ -224,7 +224,11 @@ extern const char *guestfs___errno_to_string (int errnum); * system, EINVAL is returned (all POSIX-conforming systems must * support EINVAL). */ -//extern int guestfs___string_to_errno (const char *errnostr); +extern int guestfs___string_to_errno (const char *errnostr); + +/* Private structure and function used by the perfect hash implementation. */ +struct errnostring_entry { char *name; int errnum; }; +extern const struct errnostring_entry *guestfs___string_to_errno_lookup (register const char *str, register unsigned int len); #endif /* GUESTFS_ERRNOSTRING_H_ */ " @@ -236,6 +240,7 @@ let generate_errnostring_c () = #include <config.h> #include <stdlib.h> +#include <string.h> #include <errno.h> #include \"errnostring.h\" @@ -270,4 +275,63 @@ guestfs___errno_to_string (int errnum) return errno_to_string[errnum]; } +int +guestfs___string_to_errno (const char *errnostr) +{ + const struct errnostring_entry *v = + guestfs___string_to_errno_lookup (errnostr, strlen (errnostr)); + if (v /* not necessary to check v->name != NULL here */) + return v->errnum; + else + return EINVAL; +} " + +let generate_errnostring_gperf () = + generate_header CStyle LGPLv2plus; + + pr "\ +%%language=ANSI-C +%%define lookup-function-name guestfs___string_to_errno_lookup +%%readonly-tables +%%null-strings + +%%{ + +#include <config.h> + +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include \"errnostring.h\" + +"; + + (* Some of these errnos might not exist on the target platform, but + * we are going to include E_ macros directly in the C output of + * gperf. To avoid this causing errors, we include macros to define + * unknown errors as EINVAL (see specification of + * guestfs___string_to_errno above). Note this only affects the + * single output file containing gperf-generated code. + *) + List.iter ( + fun e -> + pr "#ifndef %s\n" e; + pr "#define %s EINVAL\n" e; + pr "#endif\n"; + ) errnos; + + pr "\ + +%%} + +struct errnostring_entry; + +%%%% +"; + + List.iter ( + fun e -> + pr "%s, %s\n" e e + ) errnos diff --git a/generator/generator_main.ml b/generator/generator_main.ml index 1aa15d0f..2d4b2412 100644 --- a/generator/generator_main.ml +++ b/generator/generator_main.ml @@ -81,6 +81,7 @@ Run it from the top source directory using the command output_to "src/guestfs-structs.pod" generate_structs_pod; output_to "src/guestfs-actions.pod" generate_actions_pod; output_to "src/guestfs-availability.pod" generate_availability_pod; + output_to "src/errnostring_gperf.gperf" generate_errnostring_gperf; output_to "src/errnostring.c" generate_errnostring_c; output_to "src/errnostring.h" generate_errnostring_h; output_to "src/MAX_PROC_NR" generate_max_proc_nr; |