aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/cfuns-c.c83
1 files changed, 51 insertions, 32 deletions
diff --git a/src/lib/cfuns-c.c b/src/lib/cfuns-c.c
index 00fb35c5..b57f77ad 100644
--- a/src/lib/cfuns-c.c
+++ b/src/lib/cfuns-c.c
@@ -327,45 +327,54 @@ is_dot_or_dotdot(const char* path)
}
/* Remove a directory entry. Files are removed, directories are
- recursively walked and there removed.
+ recursively walked and removed.
Return 0 on success, and -1 on falure.
In practice, OpenAxiom does not remove directories with
non-trivial recursive structues. */
OPENAXIOM_EXPORT int
oa_unlink(const char* path)
{
+ const char* curdir;
+ int status = -1;
#ifdef __MINGW32__
WIN32_FIND_DATA findData;
HANDLE walkHandle;
- DWORD pathAttributes;
if (is_dot_or_dotdot(path))
return -1;
- if ((pathAttributes = GetFileAttributes(path)) == 0xFFFFFFFF)
+ walkHandle = FindFirstFile(path, &findData);
+ if (walkHandle == INVALID_HANDLE_VALUE)
return -1;
- if (pathAttributes & ~FILE_ATTRIBUTE_DIRECTORY)
- return DeleteFile(path) ? 0 : -1;
-
- if ((walkHandle = FindFirstFile(path, &findData)) == INVALID_HANDLE_VALUE
- || oa_chdir(path) < 0)
- return -1;
+ /* Remember where we are so we can return back properly. */
+ curdir = oa_getcwd();
+
do {
if (is_dot_or_dotdot(findData.cFileName))
continue;
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- if (oa_chdir(findData.cFileName) < 0)
- return -1;
+ if ((status = oa_chdir(findData.cFileName)) < 0)
+ goto sortie;
+ if ((status = oa_unlink("*")) < 0)
+ goto sortie;
+ if ((status = oa_chdir("..")) < 0)
+ goto sortie;
+ if(!RemoveDirectory(findData.cFileName)) {
+ status = -1;
+ goto sortie;
+ }
}
- else if (!DeleteFile(findData.cFileName))
- return -1;
+ else if (!DeleteFile(findData.cFileName)) {
+ status = -1;
+ goto sortie;
+ }
+ status = 0;
} while (FindNextFile(walkHandle, &findData));
- if (!FindClose(walkHandle))
- return -1;
- if (oa_chdir("..") < 0)
- return -1;
- return RemoveDirectory(path) ? 0 : -1;
+ if (!FindClose(walkHandle)) {
+ status = -1;
+ goto sortie;
+ }
#else
struct stat pathstat;
DIR* dir;
@@ -378,35 +387,45 @@ oa_unlink(const char* path)
if (stat(path, &pathstat) < 0)
return -1;
- /* handle non dictories first. */
+ /* handle non directories first. */
if (!S_ISDIR(pathstat.st_mode))
return unlink(path);
/* change into the path so that we don't have to form full
pathnames. */
+ curdir = oa_getcwd();
if ((dir = opendir(path)) == NULL || oa_chdir(path) < 0)
- return -1;
+ goto sortie;
while (errno = 0, (entry = readdir(dir)) != NULL) {
struct stat s;
if (is_dot_or_dotdot(entry->d_name))
continue;
- if (stat(entry->d_name, &s) < 0)
- return -1;
- if (S_ISDIR(s.st_mode) && oa_unlink(entry->d_name) < 0)
- return -1;
- else if (unlink(entry->d_name) < 0)
- return -1;
+ if ((status = stat(entry->d_name, &s)) < 0)
+ goto sortie;
+ if (S_ISDIR(s.st_mode)) {
+ if ((status = oa_unlink(entry->d_name)) < 0)
+ goto sortie;
+ }
+ else if ((status = unlink(entry->d_name)) < 0)
+ goto sortie;
+ }
+ if (errno != 0) {
+ status = -1;
+ goto sortie;
}
- if (errno != 0)
- return -1;
/* Now, get one level up, and remove the empty directory. */
- if (oa_chdir("..") < 0 || closedir(dir) < 0 || rmdir(path) < 0)
- return -1;
-
- return 0;
+ if (oa_chdir("..") < 0 || closedir(dir) < 0 || rmdir(path) < 0)
+ status = -1;
+ else
+ status = 0;
#endif /* __MINGW32__ */
+
+ sortie:
+ oa_chdir(curdir);
+ free((char*) curdir);
+ return status;
}
/* Rename a file or directory. */