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 06/24] libxl: provide libxl__remove_file et al.
Date: Mon, 16 Apr 2012 18:17:48 +0100	[thread overview]
Message-ID: <1334596686-8479-7-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1334596686-8479-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>
Acked-by: Ian Campbell <ian.campbell@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 abc38fb..3996824 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..1a4874c 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) goto out;
+        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-16 17:17 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-16 17:17 [PATCH v7 00/24] libxl: subprocess handling Ian Jackson
2012-04-16 17:17 ` [PATCH 01/24] libxl: handle POLLERR, POLLHUP, POLLNVAL properly Ian Jackson
2012-04-16 17:17 ` [PATCH 02/24] libxl: support multiple libxl__ev_fds for the same fd Ian Jackson
2012-04-16 17:17 ` [PATCH 03/24] libxl: event API: new facilities for waiting for subprocesses Ian Jackson
2012-04-16 17:17 ` [PATCH 04/24] autoconf: trim the configure script; use autoheader Ian Jackson
2012-04-17  9:18   ` Ian Campbell
2012-04-17 13:18     ` Ian Jackson
2012-04-17 13:22       ` Ian Campbell
2012-04-17 14:07         ` Roger Pau Monne
2012-04-16 17:17 ` [PATCH 05/24] autoconf: New test for openpty et al Ian Jackson
2012-04-17  9:20   ` Ian Campbell
2012-04-16 17:17 ` Ian Jackson [this message]
2012-04-16 17:17 ` [PATCH 07/24] libxl: Introduce libxl__sendmsg_fds and libxl__recvmsg_fds Ian Jackson
2012-04-16 17:17 ` [PATCH 08/24] libxl: Clean up setdefault in do_domain_create Ian Jackson
2012-04-16 17:17 ` [PATCH 09/24] libxl: provide libxl__datacopier_* Ian Jackson
2012-04-17  9:37   ` Ian Campbell
2012-04-16 17:17 ` [PATCH 10/24] libxl: provide libxl__openpty_* Ian Jackson
2012-04-16 17:17 ` [PATCH 11/24] libxl: ao: Convert libxl_run_bootloader Ian Jackson
2012-04-16 17:17 ` [PATCH 12/24] libxl: make libxl_create_logfile const-correct Ian Jackson
2012-04-16 17:17 ` [PATCH 13/24] libxl: log bootloader output Ian Jackson
2012-04-16 17:17 ` [PATCH 14/24] libxl: Allow AO_GC and EGC_GC even if not used Ian Jackson
2012-04-16 17:17 ` [PATCH 15/24] libxl: remove ctx->waitpid_instead Ian Jackson
2012-04-17  9:40   ` Ian Campbell
2012-04-17 13:24     ` Ian Jackson
2012-04-16 17:17 ` [PATCH 16/24] libxl: change some structures to unit arrays Ian Jackson
2012-04-17  9:41   ` Ian Campbell
2012-04-16 17:17 ` [PATCH 17/24] libxl: ao: convert libxl__spawn_* Ian Jackson
2012-04-17 15:17   ` Ian Campbell
2012-04-17 17:03     ` Ian Jackson
2012-04-18 10:12       ` Ian Campbell
2012-04-18 10:52         ` Ian Jackson
2012-04-18 11:07           ` Ian Campbell
2012-04-16 17:18 ` [PATCH 18/24] libxl: make libxl_create run bootloader via callback Ian Jackson
2012-04-24 13:46   ` Ian Campbell
2012-04-24 13:54     ` Ian Jackson
2012-04-16 17:18 ` [PATCH 19/24] libxl: provide progress reporting for long-running operations Ian Jackson
2012-04-24 13:59   ` Ian Campbell
2012-04-25 13:38     ` Ian Jackson
2012-04-16 17:18 ` [PATCH 20/24] libxl: remove malloc failure handling from NEW_EVENT Ian Jackson
2012-04-24 14:01   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 21/24] libxl: convert console callback to libxl_asyncprogress_how Ian Jackson
2012-04-24 14:05   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 22/24] libxl: clarify definition of "slow" operation Ian Jackson
2012-04-24 14:06   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 23/24] libxl: child processes cleanups Ian Jackson
2012-04-24 14:12   ` Ian Campbell
2012-04-24 14:27     ` Ian Jackson
2012-04-24 15:05       ` Ian Campbell
2012-04-24 15:07         ` Ian Campbell
2012-04-24 15:22     ` Ian Jackson
2012-04-24 15:32       ` Ian Campbell
2012-04-16 17:18 ` [PATCH 24/24] libxl: aborting bootloader invocation when domain dioes Ian Jackson
2012-04-24 14:18   ` Ian Campbell
2012-04-24 14:38     ` Ian Jackson
2012-04-24 15:08       ` Ian Campbell
2012-04-24 15:26         ` 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=1334596686-8479-7-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).