xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Subject: [PATCH 24/31] libxl: provide libxl__remove_file et al.
Date: Tue, 10 Apr 2012 20:07:58 +0100	[thread overview]
Message-ID: <1334084885-14474-25-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1334084885-14474-1-git-send-email-ian.jackson@eu.citrix.com>

These utility functions cope with EINTR AND ENOENT, do error logging,
and we provide a recursive version to delete whole directory trees.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_internal.h |    7 ++++
 tools/libxl/libxl_utils.c    |   79 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a60171c..8e47213 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -442,6 +442,13 @@ _hidden char *libxl__strndup(libxl__gc *gc_opt, const char *c, size_t n);
  * string. (similar to a gc'd dirname(3)). */
 _hidden char *libxl__dirname(libxl__gc *gc_opt, const char *s);
 
+/* Each of these logs errors and returns a libxl error code.
+ * They do not mind if path is already removed.
+ * For _file, path must not be a directory; for _directory it must be. */
+_hidden int libxl__remove_file(libxl__gc *gc, const char *path);
+_hidden int libxl__remove_directory(libxl__gc *gc, const char *path);
+_hidden int libxl__remove_file_or_directory(libxl__gc *gc, const char *path);
+
 _hidden char **libxl__xs_kvs_of_flexarray(libxl__gc *gc, flexarray_t *array, int length);
 
 _hidden int libxl__xs_writev(libxl__gc *gc, xs_transaction_t t,
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 0cbd85e..c9157a6 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -364,6 +364,85 @@ int libxl_read_file_contents(libxl_ctx *ctx, const char *filename,
 READ_WRITE_EXACTLY(read, 1, /* */)
 READ_WRITE_EXACTLY(write, 0, const)
 
+int libxl__remove_file(libxl__gc *gc, const char *path)
+{
+    for (;;) {
+        int r = unlink(path);
+        if (!r) return 0;
+        if (errno == ENOENT) return 0;
+        if (errno == EINTR) continue;
+        LOGE(ERROR, "failed to remove file %s", path);
+        return ERROR_FAIL;
+     }
+}
+
+int libxl__remove_file_or_directory(libxl__gc *gc, const char *path)
+{
+    for (;;) {
+        int r = rmdir(path);
+        if (!r) return 0;
+        if (errno == ENOENT) return 0;
+        if (errno == ENOTEMPTY) return libxl__remove_directory(gc, path);
+        if (errno == ENOTDIR) return libxl__remove_file(gc, path);
+        if (errno == EINTR) continue;
+        LOGE(ERROR, "failed to remove %s", path);
+        return ERROR_FAIL;
+     }
+}
+
+int libxl__remove_directory(libxl__gc *gc, const char *dirpath)
+{
+    int rc = 0;
+    DIR *d = 0;
+
+    d = opendir(dirpath);
+    if (!d) {
+        if (errno == ENOENT)
+            goto out;
+
+        LOGE(ERROR, "failed to opendir %s for removal", dirpath);
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    size_t need = offsetof(struct dirent, d_name) +
+        pathconf(dirpath, _PC_NAME_MAX) + 1;
+    struct dirent *de_buf = libxl__zalloc(gc, need);
+    struct dirent *de;
+
+    for (;;) {
+        int r = readdir_r(d, de_buf, &de);
+        if (r) {
+            LOGE(ERROR, "failed to readdir %s for removal", dirpath);
+            rc = ERROR_FAIL;
+            break;
+        }
+        if (!de)
+            break;
+
+        if (!strcmp(de->d_name, ".") ||
+            !strcmp(de->d_name, ".."))
+            continue;
+
+        const char *subpath = GCSPRINTF("%s/%s", dirpath, de->d_name);
+        if (libxl__remove_file_or_directory(gc, subpath))
+            rc = ERROR_FAIL;
+    }
+
+    for (;;) {
+        int r = rmdir(dirpath);
+        if (!r) break;
+        if (errno == ENOENT) return 0;
+        if (errno == EINTR) continue;
+        LOGE(ERROR, "failed to remove emptied directory %s", dirpath);
+        rc = ERROR_FAIL;
+    }
+
+ out:
+    if (d) closedir(d);
+
+    return rc;
+}
 
 pid_t libxl_fork(libxl_ctx *ctx)
 {
-- 
1.7.2.5

  parent reply	other threads:[~2012-04-10 19:07 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-10 19:07 [PATCH v4 00/31] libxl child process handling Ian Jackson
2012-04-10 19:07 ` [PATCH 01/31] .gitignore: Add a missing file Ian Jackson
2012-04-11  8:44   ` Ian Campbell
2012-04-10 19:07 ` [PATCH 02/31] libxl: ao: allow immediate completion Ian Jackson
2012-04-10 19:07 ` [PATCH 03/31] libxl: fix hang due to libxl__initiate_device_remove Ian Jackson
2012-04-10 19:07 ` [PATCH 04/31] libxl: Fix eventloop_iteration over-locking Ian Jackson
2012-04-10 19:07 ` [PATCH 05/31] libxl: remove poller from list in libxl__poller_get Ian Jackson
2012-04-10 19:07 ` [PATCH 06/31] libxl: Fix leak of ctx->lock Ian Jackson
2012-04-10 19:07 ` [PATCH 07/31] tools: Correct PTHREAD options in config/StdGNU.mk Ian Jackson
2012-04-10 19:07 ` [PATCH 08/31] libxl: Use PTHREAD_CFLAGS, LDFLAGS, LIBS Ian Jackson
2012-04-10 19:07 ` [PATCH 09/31] tools: Use PTHREAD_CFLAGS, _LDFLAGS, _LIBS Ian Jackson
2012-04-10 19:07 ` [PATCH 10/31] libxl: Crash (more sensibly) on malloc failure Ian Jackson
2012-04-11  9:02   ` Ian Campbell
2012-04-11 10:24     ` Ian Jackson
2012-04-11 10:47       ` Ian Campbell
2012-04-11 11:04         ` Ian Jackson
2012-04-11 11:14           ` Ian Campbell
2012-04-11 11:21             ` Ian Jackson
2012-04-11 11:23               ` Ian Jackson
2012-04-11 11:33               ` Ian Campbell
2012-04-10 19:07 ` [PATCH 11/31] libxl: Make libxl__zalloc et al tolerate a NULL gc Ian Jackson
2012-04-10 19:07 ` [PATCH 12/31] libxl: Introduce some convenience macros Ian Jackson
2012-04-10 19:07 ` [PATCH 13/31] libxl: include <ctype.h> and introduce CTYPE helper macro Ian Jackson
2012-04-10 19:07 ` [PATCH 14/31] libxl: Provide libxl_string_list_length Ian Jackson
2012-04-10 19:07 ` [PATCH 15/31] libxl: include <_libxl_paths.h> in libxl_internal.h Ian Jackson
2012-04-10 19:07 ` [PATCH 16/31] libxl: abolish libxl_ctx_postfork Ian Jackson
2012-04-10 19:07 ` [PATCH 17/31] libxl: libxl_event.c:beforepoll_internal, REQUIRE_FDS Ian Jackson
2012-04-10 19:07 ` [PATCH 18/31] libxl: Protect fds with CLOEXEC even with forking threads Ian Jackson
2012-04-11  9:14   ` Ian Campbell
2012-04-11 10:38     ` Ian Jackson
2012-04-10 19:07 ` [PATCH 19/31] libxl: provide STATE_AO_GC Ian Jackson
2012-04-11  9:17   ` Ian Campbell
2012-04-10 19:07 ` [PATCH 20/31] libxl: handle POLLERR, POLLHUP, POLLNVAL properly Ian Jackson
2012-04-11  9:21   ` Ian Campbell
2012-04-11 10:50     ` Ian Jackson
2012-04-11 10:52       ` Ian Campbell
2012-04-10 19:07 ` [PATCH 21/31] libxl: support multiple libxl__ev_fds for the same fd Ian Jackson
2012-04-10 19:07 ` [PATCH 22/31] libxl: event API: new facilities for waiting for subprocesses Ian Jackson
2012-04-11  9:42   ` Ian Campbell
2012-04-10 19:07 ` [PATCH 23/31] autoconf: New test for openpty et al Ian Jackson
2012-04-10 19:07 ` Ian Jackson [this message]
2012-04-11  9:54   ` [PATCH 24/31] libxl: provide libxl__remove_file " Ian Campbell
2012-04-11 10:56     ` Ian Jackson
2012-04-11 11:03       ` Ian Campbell
2012-04-10 19:07 ` [PATCH 25/31] libxl: Introduce libxl__sendmsg_fds and libxl__recvmsg_fds Ian Jackson
2012-04-10 19:08 ` [PATCH 26/31] libxl: Clean up setdefault in do_domain_create Ian Jackson
2012-04-11  9:57   ` Ian Campbell
2012-04-10 19:08 ` [PATCH 27/31] libxl: provide libxl__datacopier_* Ian Jackson
2012-04-11 10:47   ` Ian Campbell
2012-04-11 11:11     ` Ian Jackson
2012-04-10 19:08 ` [PATCH 28/31] libxl: provide libxl__openpty_* Ian Jackson
2012-04-11 11:03   ` Ian Campbell
2012-04-11 11:19     ` Ian Jackson
2012-04-11 11:33       ` Ian Campbell
2012-04-10 19:08 ` [PATCH 29/31] libxl: ao: Convert libxl_run_bootloader Ian Jackson
2012-04-11 11:31   ` Ian Campbell
2012-04-11 11:39     ` Ian Jackson
2012-04-11 11:45       ` Ian Campbell
2012-04-10 19:08 ` [PATCH 30/31] libxl: make libxl_create_logfile const-correct Ian Jackson
2012-04-11  9:58   ` Ian Campbell
2012-04-10 19:08 ` [PATCH 31/31] libxl: log bootloader output Ian Jackson
2012-04-11 10:00   ` Ian Campbell
2012-04-11  9:04 ` [PATCH v4 00/31] libxl child process handling Ian Campbell
2012-04-11 10:35   ` Ian Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1334084885-14474-25-git-send-email-ian.jackson@eu.citrix.com \
    --to=ian.jackson@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).