aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2008-03-17 09:00:41 +0000
committerdos-reis <gdr@axiomatics.org>2008-03-17 09:00:41 +0000
commit0f8d3e4c660cc6177e57b21579ac40733b82b940 (patch)
tree815ca8b520f594bcbbe2fd4c23a30b1e4e1c9f92 /src/lib
parentd9b9f67266bcb24e7bec1a26afaf062b376d450e (diff)
downloadopen-axiom-0f8d3e4c660cc6177e57b21579ac40733b82b940.tar.gz
* lib/cfuns-c.c (oa_chdir): Define.
(is_dot_or_dotdot): New. (oa_unlink): Define. (oa_rename): Likewise. (oa_mkdir): Likewise. * interp/sys-os.boot: New file. * interp/util.lisp (MAKE-TAGS-FILE): Use changeDirectory. (MAKELIB): Likewise. (MAKESPAD): Likewise. (LIBCHECK): Likewise. * interp/sys-utility.boot ($ERASE): Define here. Use removeFile. ($REPLACE): Likewise. (checkMkdir): Define. * interp/obey.lisp (MAKEDIR): Remove definition. * interp/nlib.lisp (RDEFIOSTREAM): Use checkMkdir. (MAKEDIR): Remove. (RPACKFILE): Use removeFile. ($ERASE): Remove Lisp definition. ($REPLACE): Likewise. * interp/i-syscmd.boot (cd): Use changeDirectory. (compileAsharpArchiveCmd): Use mkdir. (histFileErase): Likewise. * interp/fortcall.boot (fortCall): Use removeFile. (invokeNagman): Likewise. * interp/daase.lisp (|library|): Use changeDirectory. (LOCALDATABASE): Likewise. (DaaseName): Use removeFile. * interp/construc.lisp (mergelibs): Use removeFile. (mergeall): Use changeDirectory. * interp/c-doc.boot (docreport): Use removeFile. * interp/br-search.boot (getTempPath): Likewise. * interp/br-saturn.boot (dbSort): Likewise. * interp/br-data.boot (buildLibdb): Likewise (dbSplitLibdb): Likewise. (buildGloss): Likewise. (purgeLocalLibdb): Likewise. * interp/as.boot (asList): Likewise. * interp/Makefile.pamphlet (OBJS): Include sys-os.$(FASLEXT). (sys-os.$(FASLEXT)): New rule. (sys-utility.$(FASLEXT)): Require sys-os.$(FASLEXT). * include/cfuns.h (oa_chdir): Declare. (oa_unlink): Likewise. (oa_rename): Likewise. (oad_mkdir): Likewise.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/cfuns-c.c133
1 files changed, 132 insertions, 1 deletions
diff --git a/src/lib/cfuns-c.c b/src/lib/cfuns-c.c
index 7ed80551..95c9787f 100644
--- a/src/lib/cfuns-c.c
+++ b/src/lib/cfuns-c.c
@@ -2,7 +2,7 @@
Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
All rights reserved.
- Copyright (C) 2007, 2008, Gabriel Dos Reis
+ Copyright (C) 2007-2008, Gabriel Dos Reis.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@
#include "axiom-c-macros.h"
+#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -46,6 +47,8 @@
#ifdef __WIN32__
# include <windows.h>
+#else
+# include <dirent.h>
#endif
#include "cfuns.h"
@@ -300,3 +303,131 @@ std_stream_is_terminal(int fd)
return isatty(fd);
#endif
}
+
+/* Change the process' curretnt directory. Return zero on success,
+ and -1 on failure. */
+OPENAXIOM_EXPORT int
+oa_chdir(const char* path)
+{
+#ifdef __MINGW32__
+ SetCurrentDirectory(path) ? 0 : -1;
+#else
+ return chdir(path);
+#endif /* __MINGW32__ */
+}
+
+
+/* return true if path is `.' or `..'. */
+static inline int
+is_dot_or_dotdot(const char* path)
+{
+ return strcmp(path, ".") == 0 || strcmp(path, "..") == 0;
+}
+
+/* Remove a directory entry. Files are removed, directories are
+ recursively walked and there 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)
+{
+#ifdef __MINGW32__
+ WIN32_FIND_DATA findData;
+ HANDLE walkHandle;
+ DWORD pathAttributes;
+
+ if (is_dot_or_dotdot(path))
+ return -1;
+
+ if ((pathAttributes = GetFileAttributes(path)) == 0xFFFFFFFF)
+ 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;
+ do {
+ if (is_dot_or_dotdot(findData.cFileName))
+ continue;
+ if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if (oa_chdir(findData.cFileName) < 0)
+ return -1;
+ }
+ else if (!DeleteFile(findData.cFileName))
+ return -1;
+ } while (FindNextFile(walkHandle, &findData));
+ if (!FindClose(walkHandle))
+ return -1;
+ if (oa_chdir("..") < 0)
+ return -1;
+ return RemoveDirectory(path) ? 0 : -1;
+#else
+ struct stat pathstat;
+ DIR* dir;
+ struct dirent* entry;
+
+ /* Don't ever try to remove `.' or `..'. */
+ if (is_dot_or_dotdot(path))
+ return -1;
+
+ if (stat(path, &pathstat) < 0)
+ return -1;
+
+ /* handle non dictories first. */
+ if (!S_ISDIR(pathstat.st_mode))
+ return unlink(path);
+
+ /* change into the path so that we don't have to form full
+ pathnames. */
+ if ((dir = opendir(path)) == NULL || oa_chdir(path) < 0)
+ return -1;
+
+ 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 (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;
+#endif /* __MINGW32__ */
+}
+
+/* Rename a file or directory. */
+OPENAXIOM_EXPORT int
+oa_rename(const char* old_path, const char* new_path)
+{
+#ifdef __MINGW32__
+ return MoveFile(old_path, new_path) ? 0 : -1;
+#else
+ return rename(old_path, new_path);
+#endif
+}
+
+/* Create a new directory named `path'. Return 0 on success,
+ and -1 on failure. */
+OPENAXIOM_EXPORT int
+oa_mkdir(const char* path)
+{
+#ifdef __MINGW32__
+ return CreateDirectory(path, NULL) ? 0 : -1;
+#else
+# define DIRECTORY_PERM ((S_IRWXU|S_IRWXG|S_IRWXO) & ~(S_IWGRP|S_IWOTH))
+ return mkdir (path, DIRECTORY_PERM);
+# undef DIRECTORY_PERM
+#endif
+}