summaryrefslogtreecommitdiffstats
path: root/src/errors.c
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-11-12 12:56:39 +0000
committerRichard W.M. Jones <rjones@redhat.com>2012-11-12 13:40:25 +0000
commit02ecd048d3caf7804361bb0f5dca071f97aefaa1 (patch)
tree2b17e6b2037297bc1bc93b4371be15a3b9d3aef6 /src/errors.c
parentf9ab256f0e4c1197b505b0249e66e7614644bd0b (diff)
downloadlibguestfs-02ecd048d3caf7804361bb0f5dca071f97aefaa1.tar.gz
libguestfs-02ecd048d3caf7804361bb0f5dca071f97aefaa1.tar.xz
libguestfs-02ecd048d3caf7804361bb0f5dca071f97aefaa1.zip
lib: Split up huge src/guestfs.c into logical compilation units.
This file had grown by accretion to include: - code related to handles (now in src/handle.c) - safe allocation (src/alloc.c) - debug, errors, warnings (src/errors.c) - private data (src/private-data.c) - miscellaneous functions (src/canonical-name.c, src/utils.c) This commit also removes about a dozen #include files which were probably not really used. This is just code motion.
Diffstat (limited to 'src/errors.c')
-rw-r--r--src/errors.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/src/errors.c b/src/errors.c
new file mode 100644
index 00000000..d12a4a3a
--- /dev/null
+++ b/src/errors.c
@@ -0,0 +1,282 @@
+/* libguestfs
+ * Copyright (C) 2009-2012 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#include "c-ctype.h"
+
+#include "guestfs.h"
+#include "guestfs-internal.h"
+
+const char *
+guestfs_last_error (guestfs_h *g)
+{
+ return g->last_error;
+}
+
+int
+guestfs_last_errno (guestfs_h *g)
+{
+ return g->last_errnum;
+}
+
+static void
+set_last_error (guestfs_h *g, int errnum, const char *msg)
+{
+ free (g->last_error);
+ g->last_error = strdup (msg);
+ g->last_errnum = errnum;
+}
+
+/* Warning are printed unconditionally. We try to make these rare.
+ * Generally speaking, a warning should either be an error, or if it's
+ * not important for end users then it should be a debug message.
+ */
+void
+guestfs___warning (guestfs_h *g, const char *fs, ...)
+{
+ va_list args;
+ char *msg, *msg2;
+ int len;
+
+ va_start (args, fs);
+ len = vasprintf (&msg, fs, args);
+ va_end (args);
+
+ if (len < 0) return;
+
+ len = asprintf (&msg2, _("warning: %s"), msg);
+ free (msg);
+
+ if (len < 0) return;
+
+ guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg2, len);
+
+ free (msg2);
+}
+
+/* Debug messages. */
+void
+guestfs___debug (guestfs_h *g, const char *fs, ...)
+{
+ va_list args;
+ char *msg;
+ int len;
+
+ /* The cpp macro "debug" has already checked that g->verbose is true
+ * before calling this function, but we check it again just in case
+ * anyone calls this function directly.
+ */
+ if (!g->verbose)
+ return;
+
+ va_start (args, fs);
+ len = vasprintf (&msg, fs, args);
+ va_end (args);
+
+ if (len < 0) return;
+
+ guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg, len);
+
+ free (msg);
+}
+
+/* Call trace messages. These are enabled by setting g->trace, and
+ * calls to this function should only happen from the generated code
+ * in src/actions.c
+ */
+void
+guestfs___trace (guestfs_h *g, const char *fs, ...)
+{
+ va_list args;
+ char *msg;
+ int len;
+
+ va_start (args, fs);
+ len = vasprintf (&msg, fs, args);
+ va_end (args);
+
+ if (len < 0) return;
+
+ guestfs___call_callbacks_message (g, GUESTFS_EVENT_TRACE, msg, len);
+
+ free (msg);
+}
+
+void
+guestfs_error_errno (guestfs_h *g, int errnum, const char *fs, ...)
+{
+ va_list args;
+ char *msg;
+
+ va_start (args, fs);
+ int err = vasprintf (&msg, fs, args);
+ va_end (args);
+
+ if (err < 0) return;
+
+ /* set_last_error first so that the callback can access the error
+ * message and errno through the handle if it wishes.
+ */
+ set_last_error (g, errnum, msg);
+ if (g->error_cb) g->error_cb (g, g->error_cb_data, msg);
+
+ free (msg);
+}
+
+void
+guestfs_perrorf (guestfs_h *g, const char *fs, ...)
+{
+ va_list args;
+ char *msg;
+ int errnum = errno;
+
+ va_start (args, fs);
+ int err = vasprintf (&msg, fs, args);
+ va_end (args);
+
+ if (err < 0) return;
+
+ char buf[256];
+ strerror_r (errnum, buf, sizeof buf);
+
+ msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (buf) + 1);
+ strcat (msg, ": ");
+ strcat (msg, buf);
+
+ /* set_last_error first so that the callback can access the error
+ * message and errno through the handle if it wishes.
+ */
+ set_last_error (g, errnum, msg);
+ if (g->error_cb) g->error_cb (g, g->error_cb_data, msg);
+
+ free (msg);
+}
+
+void
+guestfs_set_out_of_memory_handler (guestfs_h *g, guestfs_abort_cb cb)
+{
+ g->abort_cb = cb;
+}
+
+guestfs_abort_cb
+guestfs_get_out_of_memory_handler (guestfs_h *g)
+{
+ return g->abort_cb;
+}
+
+void
+guestfs_set_error_handler (guestfs_h *g,
+ guestfs_error_handler_cb cb, void *data)
+{
+ g->error_cb = cb;
+ g->error_cb_data = data;
+}
+
+guestfs_error_handler_cb
+guestfs_get_error_handler (guestfs_h *g, void **data_rtn)
+{
+ if (data_rtn) *data_rtn = g->error_cb_data;
+ return g->error_cb;
+}
+
+void
+guestfs_push_error_handler (guestfs_h *g,
+ guestfs_error_handler_cb cb, void *data)
+{
+ struct error_cb_stack *old_stack;
+
+ old_stack = g->error_cb_stack;
+ g->error_cb_stack = safe_malloc (g, sizeof (struct error_cb_stack));
+ g->error_cb_stack->next = old_stack;
+ g->error_cb_stack->error_cb = g->error_cb;
+ g->error_cb_stack->error_cb_data = g->error_cb_data;
+
+ guestfs_set_error_handler (g, cb, data);
+}
+
+void
+guestfs_pop_error_handler (guestfs_h *g)
+{
+ struct error_cb_stack *next_stack;
+
+ if (g->error_cb_stack) {
+ next_stack = g->error_cb_stack->next;
+ guestfs_set_error_handler (g, g->error_cb_stack->error_cb,
+ g->error_cb_stack->error_cb_data);
+ free (g->error_cb_stack);
+ g->error_cb_stack = next_stack;
+ }
+ else
+ guestfs___init_error_handler (g);
+}
+
+static void default_error_cb (guestfs_h *g, void *data, const char *msg);
+
+void
+guestfs___init_error_handler (guestfs_h *g)
+{
+ g->error_cb = default_error_cb;
+ g->error_cb_data = NULL;
+}
+
+static void
+default_error_cb (guestfs_h *g, void *data, const char *msg)
+{
+ fprintf (stderr, _("libguestfs: error: %s\n"), msg);
+}
+
+/* When tracing, be careful how we print BufferIn parameters which
+ * usually contain large amounts of binary data (RHBZ#646822).
+ */
+void
+guestfs___print_BufferIn (FILE *out, const char *buf, size_t buf_size)
+{
+ size_t i;
+ size_t orig_size = buf_size;
+
+ if (buf_size > 256)
+ buf_size = 256;
+
+ fputc ('"', out);
+
+ for (i = 0; i < buf_size; ++i) {
+ if (c_isprint (buf[i]))
+ fputc (buf[i], out);
+ else
+ fprintf (out, "\\x%02x", (unsigned char) buf[i]);
+ }
+
+ fputc ('"', out);
+
+ if (orig_size > buf_size)
+ fprintf (out,
+ _("<truncated, original size %zu bytes>"), orig_size);
+}
+
+void
+guestfs___print_BufferOut (FILE *out, const char *buf, size_t buf_size)
+{
+ guestfs___print_BufferIn (out, buf, buf_size);
+}