+ if (len < 0) return;
+
+ guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg, len);
+}
+
+/* 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);
+}
+
+static void
+default_error_cb (guestfs_h *g, void *data, const char *msg)
+{
+ fprintf (stderr, _("libguestfs: error: %s\n"), 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;
+
+#if !defined(_GNU_SOURCE) || defined(__APPLE__)
+ char buf[256];
+ strerror_r (errnum, buf, sizeof buf);
+#else
+ char _buf[256];
+ char *buf;
+ buf = strerror_r (errnum, _buf, sizeof _buf);
+#endif
+
+ 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);