mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 15:27:47 +00:00
Introduce a virFileDeleteTree method
Introduce a method virFileDeleteTree for recursively deleting an entire directory tree Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
b7f1d218d8
commit
035cdaa00b
@ -1264,6 +1264,7 @@ virEventPollUpdateTimeout;
|
||||
|
||||
# util/virfile.h
|
||||
virFileClose;
|
||||
virFileDeleteTree;
|
||||
virFileDirectFdFlag;
|
||||
virFileFclose;
|
||||
virFileFdopen;
|
||||
|
@ -644,3 +644,86 @@ int virFileLoopDeviceAssociate(const char *file,
|
||||
}
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
|
||||
/**
|
||||
* virFileDeleteTree:
|
||||
*
|
||||
* Recursively deletes all files / directories
|
||||
* starting from the directory @dir. Does not
|
||||
* follow symlinks
|
||||
*
|
||||
* NB the algorithm is not efficient, and is subject to
|
||||
* race conditions which can be exploited by malicious
|
||||
* code. It should not be used in any scenarios where
|
||||
* performance is important, or security is critical.
|
||||
*/
|
||||
int virFileDeleteTree(const char *dir)
|
||||
{
|
||||
DIR *dh = opendir(dir);
|
||||
struct dirent *de;
|
||||
char *filepath = NULL;
|
||||
int ret = -1;
|
||||
|
||||
if (!dh) {
|
||||
virReportSystemError(errno, _("Cannot open dir '%s'"),
|
||||
dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
while ((de = readdir(dh)) != NULL) {
|
||||
struct stat sb;
|
||||
|
||||
if (STREQ(de->d_name, ".") ||
|
||||
STREQ(de->d_name, ".."))
|
||||
continue;
|
||||
|
||||
if (virAsprintf(&filepath, "%s/%s",
|
||||
dir, de->d_name) < 0) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (lstat(filepath, &sb) < 0) {
|
||||
virReportSystemError(errno, _("Cannot access '%s'"),
|
||||
filepath);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
if (virFileDeleteTree(filepath) < 0)
|
||||
goto cleanup;
|
||||
} else {
|
||||
if (unlink(filepath) < 0 && errno != ENOENT) {
|
||||
virReportSystemError(errno,
|
||||
_("Cannot delete file '%s'"),
|
||||
filepath);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
VIR_FREE(filepath);
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
if (errno) {
|
||||
virReportSystemError(errno, _("Cannot read dir '%s'"),
|
||||
dir);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (rmdir(dir) < 0 && errno != ENOENT) {
|
||||
virReportSystemError(errno,
|
||||
_("Cannot delete directory '%s'"),
|
||||
dir);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(filepath);
|
||||
closedir(dh);
|
||||
return ret;
|
||||
}
|
||||
|
@ -108,4 +108,6 @@ int virFileUpdatePerm(const char *path,
|
||||
int virFileLoopDeviceAssociate(const char *file,
|
||||
char **dev);
|
||||
|
||||
int virFileDeleteTree(const char *dir);
|
||||
|
||||
#endif /* __VIR_FILES_H */
|
||||
|
Loading…
Reference in New Issue
Block a user