/* libguestfs
- * Copyright (C) 2009-2010 Red Hat Inc.
+ * Copyright (C) 2009-2011 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
#include "guestfs_protocol.h"
static void default_error_cb (guestfs_h *g, void *data, const char *msg);
+static void remove_tmpdir (guestfs_h *g);
static void close_handles (void);
gl_lock_define_initialized (static, handles_lock);
void
guestfs_close (guestfs_h *g)
{
- int i;
- char filename[256];
- guestfs_h *gg;
-
if (g->state == NO_HANDLE) {
/* Not safe to call ANY callbacks here, so ... */
fprintf (stderr, _("guestfs_close: called twice on the same handle\n"));
return;
}
+ if (g->trace) {
+ const char trace_msg[] = "close";
+
+ guestfs___call_callbacks_message (g, GUESTFS_EVENT_TRACE,
+ trace_msg, strlen (trace_msg));
+ }
+
debug (g, "closing guestfs handle %p (state %d)", g, g->state);
/* Try to sync if autosync flag is set. */
if (g->pid > 0) waitpid (g->pid, NULL, 0);
if (g->recoverypid > 0) waitpid (g->recoverypid, NULL, 0);
- /* Remove tmpfiles. */
- if (g->tmpdir) {
- snprintf (filename, sizeof filename, "%s/sock", g->tmpdir);
- unlink (filename);
-
- rmdir (g->tmpdir);
-
- free (g->tmpdir);
- }
+ /* Remove whole temporary directory. */
+ remove_tmpdir (g);
if (g->cmdline) {
+ size_t i;
+
for (i = 0; i < g->cmdline_size; ++i)
free (g->cmdline[i]);
free (g->cmdline);
if (handles == g)
handles = g->next;
else {
+ guestfs_h *gg;
+
for (gg = handles; gg->next != g; gg = gg->next)
;
gg->next = g->next;
free (g);
}
+/* g->tmpdir can contain any files (but not subdirectories). Remove
+ * those and the directory itself. Note that errors in this function
+ * aren't really that important: if we end up not deleting temporary
+ * files it's only annoying.
+ */
+static void
+remove_tmpdir (guestfs_h *g)
+{
+ DIR *dir;
+ struct dirent *d;
+
+ if (!g->tmpdir)
+ return;
+
+ dir = opendir (g->tmpdir);
+ if (dir == NULL) {
+ perror (g->tmpdir);
+ return;
+ }
+
+ while ((d = readdir (dir)) != NULL) {
+ if (STRNEQ (d->d_name, ".") && STRNEQ (d->d_name, "..")) {
+ if (unlinkat (dirfd (dir), d->d_name, 0) == -1)
+ perror (d->d_name);
+ }
+ }
+
+ if (closedir (dir) == -1)
+ perror (g->tmpdir);
+
+ if (rmdir (g->tmpdir) == -1)
+ perror (g->tmpdir);
+
+ free (g->tmpdir);
+ g->tmpdir = NULL;
+}
+
/* Close all open handles (called from atexit(3)). */
static void
close_handles (void)