summaryrefslogtreecommitdiffstats
path: root/generator
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2010-11-03 15:49:36 +0000
committerRichard W.M. Jones <rjones@redhat.com>2010-11-03 18:48:56 +0000
commit2066805a5d93b62beaf6653324715f0b62b06a05 (patch)
tree393ec11feb514069cf5cfb102b24a4d3a75d7e40 /generator
parentd859c283c469b9d9124d90d0ac32024671372ed5 (diff)
downloadlibguestfs-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.ml13
-rw-r--r--generator/generator_errnostring.ml66
-rw-r--r--generator/generator_main.ml1
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;