[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 24/31] libxl: provide libxl__remove_file et al.
On Tue, 2012-04-10 at 20:07 +0100, Ian Jackson wrote: > 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@xxxxxxxxxxxxx> > --- > 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; starting to look a bit like a switch statement... > + 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; This misses the closedir() at 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) > { _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |