aboutsummaryrefslogtreecommitdiff
path: root/src/lfs.c
diff options
context:
space:
mode:
authorHisham <hisham@gobolinux.org>2016-10-19 01:36:11 -0400
committerHisham <hisham@gobolinux.org>2016-10-19 01:36:11 -0400
commitb1f0f80141fe4ddd622e7f525cd0da4d24ce72af (patch)
tree270c8eb43212f0acc97f3dac4568542abc9a1acd /src/lfs.c
parentaa18f3e127b3d11344d6472fe3647cdf0e8a8f08 (diff)
parent3c4e563d9c140319e28c419f2710b51a2f6d6d24 (diff)
downloadluafilesystem-2.0.tar.gz
luafilesystem-2.0.tar.bz2
luafilesystem-2.0.zip
Merge branch 'master' into 2.02.0
Diffstat (limited to 'src/lfs.c')
-rw-r--r--src/lfs.c141
1 files changed, 97 insertions, 44 deletions
diff --git a/src/lfs.c b/src/lfs.c
index 34e30a9..c45cae0 100644
--- a/src/lfs.c
+++ b/src/lfs.c
@@ -41,22 +41,26 @@
41#include <sys/stat.h> 41#include <sys/stat.h>
42 42
43#ifdef _WIN32 43#ifdef _WIN32
44#include <direct.h> 44 #include <direct.h>
45#include <windows.h> 45 #include <windows.h>
46#include <io.h> 46 #include <io.h>
47#include <sys/locking.h> 47 #include <sys/locking.h>
48#ifdef __BORLANDC__ 48 #ifdef __BORLANDC__
49 #include <utime.h> 49 #include <utime.h>
50#else 50 #else
51 #include <sys/utime.h> 51 #include <sys/utime.h>
52#endif 52 #endif
53#include <fcntl.h> 53 #include <fcntl.h>
54 /* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */
55 #define LFS_MAXPATHLEN MAX_PATH
54#else 56#else
55#include <unistd.h> 57 #include <unistd.h>
56#include <dirent.h> 58 #include <dirent.h>
57#include <fcntl.h> 59 #include <fcntl.h>
58#include <sys/types.h> 60 #include <sys/types.h>
59#include <utime.h> 61 #include <utime.h>
62 #include <sys/param.h> /* for MAXPATHLEN */
63 #define LFS_MAXPATHLEN MAXPATHLEN
60#endif 64#endif
61 65
62#include <lua.h> 66#include <lua.h>
@@ -84,22 +88,6 @@
84#define strerror(_) "System unable to describe the error" 88#define strerror(_) "System unable to describe the error"
85#endif 89#endif
86 90
87/* Define 'getcwd' for systems that do not implement it */
88#ifdef NO_GETCWD
89#define getcwd(p,s) NULL
90#define getcwd_error "Function 'getcwd' not provided by system"
91#else
92#define getcwd_error strerror(errno)
93 #ifdef _WIN32
94 /* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */
95 #define LFS_MAXPATHLEN MAX_PATH
96 #else
97 /* For MAXPATHLEN: */
98 #include <sys/param.h>
99 #define LFS_MAXPATHLEN MAXPATHLEN
100 #endif
101#endif
102
103#define DIR_METATABLE "directory metatable" 91#define DIR_METATABLE "directory metatable"
104typedef struct dir_data { 92typedef struct dir_data {
105 int closed; 93 int closed;
@@ -185,18 +173,35 @@ static int change_dir (lua_State *L) {
185** and a string describing the error 173** and a string describing the error
186*/ 174*/
187static int get_dir (lua_State *L) { 175static int get_dir (lua_State *L) {
188 char *path; 176#ifdef NO_GETCWD
189 /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */
190 char buf[LFS_MAXPATHLEN];
191 if ((path = getcwd(buf, LFS_MAXPATHLEN)) == NULL) {
192 lua_pushnil(L); 177 lua_pushnil(L);
193 lua_pushstring(L, getcwd_error); 178 lua_pushstring(L, "Function 'getcwd' not provided by system");
194 return 2; 179 return 2;
195 } 180#else
196 else { 181 char *path = NULL;
197 lua_pushstring(L, path); 182 /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */
198 return 1; 183 size_t size = LFS_MAXPATHLEN; /* initial buffer size */
199 } 184 int result;
185 while (1) {
186 path = realloc(path, size);
187 if (!path) /* failed to allocate */
188 return pusherror(L, "get_dir realloc() failed");
189 if (getcwd(path, size) != NULL) {
190 /* success, push the path to the Lua stack */
191 lua_pushstring(L, path);
192 result = 1;
193 break;
194 }
195 if (errno != ERANGE) { /* unexpected error */
196 result = pusherror(L, "get_dir getcwd() failed");
197 break;
198 }
199 /* ERANGE = insufficient buffer capacity, double size and retry */
200 size *= 2;
201 }
202 free(path);
203 return result;
204#endif
200} 205}
201 206
202/* 207/*
@@ -808,7 +813,8 @@ static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
808 /* member not found */ 813 /* member not found */
809 return luaL_error(L, "invalid attribute name '%s'", member); 814 return luaL_error(L, "invalid attribute name '%s'", member);
810 } 815 }
811 /* creates a table if none is given */ 816 /* creates a table if none is given, removes extra arguments */
817 lua_settop(L, 2);
812 if (!lua_istable (L, 2)) { 818 if (!lua_istable (L, 2)) {
813 lua_newtable (L); 819 lua_newtable (L);
814 } 820 }
@@ -831,10 +837,57 @@ static int file_info (lua_State *L) {
831 837
832 838
833/* 839/*
840** Push the symlink target to the top of the stack.
841** Assumes the file name is at position 1 of the stack.
842** Returns 1 if successful (with the target on top of the stack),
843** 0 on failure (with stack unchanged, and errno set).
844*/
845static int push_link_target(lua_State *L) {
846#ifdef _WIN32
847 errno = ENOSYS;
848 return 0;
849#else
850 const char *file = luaL_checkstring(L, 1);
851 char *target = NULL;
852 int tsize, size = 256; /* size = initial buffer capacity */
853 while (1) {
854 target = realloc(target, size);
855 if (!target) /* failed to allocate */
856 return 0;
857 tsize = readlink(file, target, size);
858 if (tsize < 0) { /* a readlink() error occurred */
859 free(target);
860 return 0;
861 }
862 if (tsize < size)
863 break;
864 /* possibly truncated readlink() result, double size and retry */
865 size *= 2;
866 }
867 target[tsize] = '\0';
868 lua_pushlstring(L, target, tsize);
869 free(target);
870 return 1;
871#endif
872}
873
874/*
834** Get symbolic link information using lstat. 875** Get symbolic link information using lstat.
835*/ 876*/
836static int link_info (lua_State *L) { 877static int link_info (lua_State *L) {
837 return _file_info_ (L, LSTAT_FUNC); 878 int ret;
879 if (lua_isstring (L, 2) && (strcmp(lua_tostring(L, 2), "target") == 0)) {
880 int ok = push_link_target(L);
881 return ok ? 1 : pusherror(L, "could not obtain link target");
882 }
883 ret = _file_info_ (L, LSTAT_FUNC);
884 if (ret == 1 && lua_type(L, -1) == LUA_TTABLE) {
885 int ok = push_link_target(L);
886 if (ok) {
887 lua_setfield(L, -2, "target");
888 }
889 }
890 return ret;
838} 891}
839 892
840 893
@@ -868,7 +921,7 @@ static const struct luaL_Reg fslib[] = {
868 {NULL, NULL}, 921 {NULL, NULL},
869}; 922};
870 923
871int luaopen_lfs (lua_State *L) { 924LFS_EXPORT int luaopen_lfs (lua_State *L) {
872 dir_create_meta (L); 925 dir_create_meta (L);
873 lock_create_meta (L); 926 lock_create_meta (L);
874 luaL_newlib (L, fslib); 927 luaL_newlib (L, fslib);