From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Subject: [PATCH 05/20] libxl: provide libxl__remove_file et al.
Date: Fri, 13 Apr 2012 19:39:59 +0100 [thread overview]
Message-ID: <1334342414-10289-6-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1334342414-10289-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 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
next prev parent reply other threads:[~2012-04-13 18:39 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-13 18:39 [PATCH v6 00/20] libxl: subprocess handling Ian Jackson
2012-04-13 18:39 ` [PATCH 01/20] libxl: handle POLLERR, POLLHUP, POLLNVAL properly Ian Jackson
2012-04-16 7:53 ` Ian Campbell
2012-04-13 18:39 ` [PATCH 02/20] libxl: support multiple libxl__ev_fds for the same fd Ian Jackson
2012-04-16 8:04 ` Ian Campbell
2012-04-16 10:26 ` Ian Jackson
2012-04-16 11:17 ` Ian Campbell
2012-04-13 18:39 ` [PATCH 03/20] libxl: event API: new facilities for waiting for subprocesses Ian Jackson
2012-04-13 18:39 ` [PATCH 04/20] autoconf: New test for openpty et al Ian Jackson
2012-04-16 9:09 ` Ian Campbell
2012-04-16 10:32 ` Ian Jackson
2012-04-16 11:19 ` Ian Campbell
2012-04-16 11:50 ` Ian Jackson
2012-04-16 10:09 ` Roger Pau Monne
2012-04-16 10:35 ` Ian Jackson
2012-04-16 10:40 ` Roger Pau Monne
2012-04-16 10:56 ` Ian Jackson
2012-04-13 18:39 ` Ian Jackson [this message]
2012-04-16 9:24 ` [PATCH 05/20] libxl: provide libxl__remove_file " Ian Campbell
2012-04-16 10:33 ` Ian Jackson
2012-04-13 18:40 ` [PATCH 06/20] libxl: Introduce libxl__sendmsg_fds and libxl__recvmsg_fds Ian Jackson
2012-04-13 18:40 ` [PATCH 07/20] libxl: Clean up setdefault in do_domain_create Ian Jackson
2012-04-13 18:40 ` [PATCH 08/20] libxl: provide libxl__datacopier_* Ian Jackson
2012-04-13 18:40 ` [PATCH 09/20] libxl: provide libxl__openpty_* Ian Jackson
2012-04-13 18:40 ` [PATCH 10/20] libxl: ao: Convert libxl_run_bootloader Ian Jackson
2012-04-13 18:40 ` [PATCH 11/20] libxl: make libxl_create_logfile const-correct Ian Jackson
2012-04-13 18:40 ` [PATCH 12/20] libxl: log bootloader output Ian Jackson
2012-04-13 18:40 ` [PATCH 13/20] libxl: Allow AO_GC and EGC_GC even if not used Ian Jackson
2012-04-16 14:43 ` Ian Campbell
2012-04-13 18:40 ` [PATCH 14/20] libxl: remove ctx->waitpid_instead Ian Jackson
2012-04-13 18:40 ` [PATCH 15/20] libxl: change some structures to unit arrays Ian Jackson
2012-04-13 18:40 ` [PATCH 16/20] libxl: ao: convert libxl__spawn_* Ian Jackson
2012-04-13 18:40 ` [PATCH 17/20] libxl: make libxl_create run bootloader via callback Ian Jackson
2012-04-13 18:40 ` [PATCH 18/20] libxl: provide progress reporting for long-running operations Ian Jackson
2012-04-13 18:40 ` [PATCH 19/20] libxl: remove malloc failure handling from NEW_EVENT Ian Jackson
2012-04-13 18:40 ` [PATCH 20/20] libxl: convert console callback to libxl_asyncprogress_how 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=1334342414-10289-6-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).