diff options
author | dos-reis <gdr@axiomatics.org> | 2008-03-17 09:00:41 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2008-03-17 09:00:41 +0000 |
commit | 0f8d3e4c660cc6177e57b21579ac40733b82b940 (patch) | |
tree | 815ca8b520f594bcbbe2fd4c23a30b1e4e1c9f92 /src/lib | |
parent | d9b9f67266bcb24e7bec1a26afaf062b376d450e (diff) | |
download | open-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.c | 133 |
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 +} |