Line 0
Link Here
|
|
|
1 |
--- src/lfs.c 2009-10-21 00:54:35.000000000 +0400 |
2 |
+++ ../luafilesystem-master/src/lfs.c 2012-10-04 18:25:54.000000000 +0400 |
3 |
@@ -56,11 +56,19 @@ |
4 |
#include <utime.h> |
5 |
#endif |
6 |
|
7 |
-#include "lua.h" |
8 |
-#include "lauxlib.h" |
9 |
-#include "lualib.h" |
10 |
+#include <lua.h> |
11 |
+#include <lauxlib.h> |
12 |
+#include <lualib.h> |
13 |
+ |
14 |
#include "lfs.h" |
15 |
|
16 |
+#define LFS_VERSION "1.6.2" |
17 |
+#define LFS_LIBNAME "lfs" |
18 |
+ |
19 |
+#if LUA_VERSION_NUM < 502 |
20 |
+# define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l)) |
21 |
+#endif |
22 |
+ |
23 |
/* Define 'strerror' for systems that do not implement it */ |
24 |
#ifdef NO_STRERROR |
25 |
#define strerror(_) "System unable to describe the error" |
26 |
@@ -72,15 +80,22 @@ |
27 |
#define getcwd_error "Function 'getcwd' not provided by system" |
28 |
#else |
29 |
#define getcwd_error strerror(errno) |
30 |
+ #ifdef _WIN32 |
31 |
+ /* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */ |
32 |
+ #define LFS_MAXPATHLEN MAX_PATH |
33 |
+ #else |
34 |
+ /* For MAXPATHLEN: */ |
35 |
+ #include <sys/param.h> |
36 |
+ #define LFS_MAXPATHLEN MAXPATHLEN |
37 |
+ #endif |
38 |
#endif |
39 |
|
40 |
#define DIR_METATABLE "directory metatable" |
41 |
-#define MAX_DIR_LENGTH 1023 |
42 |
typedef struct dir_data { |
43 |
int closed; |
44 |
#ifdef _WIN32 |
45 |
long hFile; |
46 |
- char pattern[MAX_DIR_LENGTH+1]; |
47 |
+ char pattern[MAX_PATH+1]; |
48 |
#else |
49 |
DIR *dir; |
50 |
#endif |
51 |
@@ -97,17 +112,40 @@ |
52 |
#define STAT_STRUCT struct _stati64 |
53 |
#endif |
54 |
#define STAT_FUNC _stati64 |
55 |
+#define LSTAT_FUNC STAT_FUNC |
56 |
#else |
57 |
#define _O_TEXT 0 |
58 |
#define _O_BINARY 0 |
59 |
-#define lfs_setmode(L,file,m) ((void)((void)file,m), \ |
60 |
- luaL_error(L, LUA_QL("setmode") " not supported on this platform"), -1) |
61 |
+#define lfs_setmode(L,file,m) ((void)L, (void)file, (void)m, 0) |
62 |
#define STAT_STRUCT struct stat |
63 |
#define STAT_FUNC stat |
64 |
#define LSTAT_FUNC lstat |
65 |
#endif |
66 |
|
67 |
/* |
68 |
+** Utility functions |
69 |
+*/ |
70 |
+static int pusherror(lua_State *L, const char *info) |
71 |
+{ |
72 |
+ lua_pushnil(L); |
73 |
+ if (info==NULL) |
74 |
+ lua_pushstring(L, strerror(errno)); |
75 |
+ else |
76 |
+ lua_pushfstring(L, "%s: %s", info, strerror(errno)); |
77 |
+ lua_pushinteger(L, errno); |
78 |
+ return 3; |
79 |
+} |
80 |
+ |
81 |
+static int pushresult(lua_State *L, int i, const char *info) |
82 |
+{ |
83 |
+ if (i==-1) |
84 |
+ return pusherror(L, info); |
85 |
+ lua_pushinteger(L, i); |
86 |
+ return 1; |
87 |
+} |
88 |
+ |
89 |
+ |
90 |
+/* |
91 |
** This function changes the working (current) directory |
92 |
*/ |
93 |
static int change_dir (lua_State *L) { |
94 |
@@ -130,14 +168,15 @@ |
95 |
*/ |
96 |
static int get_dir (lua_State *L) { |
97 |
char *path; |
98 |
- if ((path = getcwd(NULL, 0)) == NULL) { |
99 |
+ /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */ |
100 |
+ char buf[LFS_MAXPATHLEN]; |
101 |
+ if ((path = getcwd(buf, LFS_MAXPATHLEN)) == NULL) { |
102 |
lua_pushnil(L); |
103 |
lua_pushstring(L, getcwd_error); |
104 |
return 2; |
105 |
} |
106 |
else { |
107 |
lua_pushstring(L, path); |
108 |
- free(path); |
109 |
return 1; |
110 |
} |
111 |
} |
112 |
@@ -281,10 +320,9 @@ |
113 |
} |
114 |
#endif |
115 |
|
116 |
-#ifdef _WIN32 |
117 |
static int lfs_g_setmode (lua_State *L, FILE *f, int arg) { |
118 |
- static const int mode[] = {_O_TEXT, _O_BINARY}; |
119 |
- static const char *const modenames[] = {"text", "binary", NULL}; |
120 |
+ static const int mode[] = {_O_BINARY, _O_TEXT}; |
121 |
+ static const char *const modenames[] = {"binary", "text", NULL}; |
122 |
int op = luaL_checkoption(L, arg, NULL, modenames); |
123 |
int res = lfs_setmode(L, f, mode[op]); |
124 |
if (res != -1) { |
125 |
@@ -307,13 +345,6 @@ |
126 |
return 3; |
127 |
} |
128 |
} |
129 |
-#else |
130 |
-static int lfs_g_setmode (lua_State *L, FILE *f, int arg) { |
131 |
- lua_pushboolean(L, 0); |
132 |
- lua_pushliteral(L, "setmode not supported on this platform"); |
133 |
- return 2; |
134 |
-} |
135 |
-#endif |
136 |
|
137 |
static int lfs_f_setmode(lua_State *L) { |
138 |
return lfs_g_setmode(L, check_file(L, 1, "setmode"), 2); |
139 |
@@ -363,14 +394,35 @@ |
140 |
} |
141 |
|
142 |
|
143 |
+/* |
144 |
+** Creates a link. |
145 |
+** @param #1 Object to link to. |
146 |
+** @param #2 Name of link. |
147 |
+** @param #3 True if link is symbolic (optional). |
148 |
+*/ |
149 |
+static int make_link(lua_State *L) |
150 |
+{ |
151 |
+#ifndef _WIN32 |
152 |
+ const char *oldpath = luaL_checkstring(L, 1); |
153 |
+ const char *newpath = luaL_checkstring(L, 2); |
154 |
+ return pushresult(L, |
155 |
+ (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL); |
156 |
+#else |
157 |
+ pusherror(L, "make_link is not supported on Windows"); |
158 |
+#endif |
159 |
+} |
160 |
+ |
161 |
+ |
162 |
+/* |
163 |
+** Creates a directory. |
164 |
+** @param #1 Directory path. |
165 |
+*/ |
166 |
static int make_dir (lua_State *L) { |
167 |
const char *path = luaL_checkstring (L, 1); |
168 |
int fail; |
169 |
#ifdef _WIN32 |
170 |
- int oldmask = umask (0); |
171 |
fail = _mkdir (path); |
172 |
#else |
173 |
- mode_t oldmask = umask( (mode_t)0 ); |
174 |
fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | |
175 |
S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH ); |
176 |
#endif |
177 |
@@ -379,7 +431,6 @@ |
178 |
lua_pushfstring (L, "%s", strerror(errno)); |
179 |
return 2; |
180 |
} |
181 |
- umask (oldmask); |
182 |
lua_pushboolean (L, 1); |
183 |
return 1; |
184 |
} |
185 |
@@ -413,12 +464,13 @@ |
186 |
struct dirent *entry; |
187 |
#endif |
188 |
dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE); |
189 |
- luaL_argcheck (L, !d->closed, 1, "closed directory"); |
190 |
+ luaL_argcheck (L, d->closed == 0, 1, "closed directory"); |
191 |
#ifdef _WIN32 |
192 |
if (d->hFile == 0L) { /* first entry */ |
193 |
if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { |
194 |
lua_pushnil (L); |
195 |
lua_pushstring (L, strerror (errno)); |
196 |
+ d->closed = 1; |
197 |
return 2; |
198 |
} else { |
199 |
lua_pushstring (L, c_file.name); |
200 |
@@ -457,14 +509,13 @@ |
201 |
#ifdef _WIN32 |
202 |
if (!d->closed && d->hFile) { |
203 |
_findclose (d->hFile); |
204 |
- d->closed = 1; |
205 |
} |
206 |
#else |
207 |
if (!d->closed && d->dir) { |
208 |
closedir (d->dir); |
209 |
- d->closed = 1; |
210 |
} |
211 |
#endif |
212 |
+ d->closed = 1; |
213 |
return 0; |
214 |
} |
215 |
|
216 |
@@ -477,18 +528,16 @@ |
217 |
dir_data *d; |
218 |
lua_pushcfunction (L, dir_iter); |
219 |
d = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); |
220 |
+ luaL_getmetatable (L, DIR_METATABLE); |
221 |
+ lua_setmetatable (L, -2); |
222 |
d->closed = 0; |
223 |
#ifdef _WIN32 |
224 |
d->hFile = 0L; |
225 |
- luaL_getmetatable (L, DIR_METATABLE); |
226 |
- lua_setmetatable (L, -2); |
227 |
- if (strlen(path) > MAX_DIR_LENGTH) |
228 |
+ if (strlen(path) > MAX_PATH-2) |
229 |
luaL_error (L, "path too long: %s", path); |
230 |
else |
231 |
sprintf (d->pattern, "%s/*", path); |
232 |
#else |
233 |
- luaL_getmetatable (L, DIR_METATABLE); |
234 |
- lua_setmetatable (L, -2); |
235 |
d->dir = opendir (path); |
236 |
if (d->dir == NULL) |
237 |
luaL_error (L, "cannot open %s: %s", path, strerror (errno)); |
238 |
@@ -502,19 +551,18 @@ |
239 |
*/ |
240 |
static int dir_create_meta (lua_State *L) { |
241 |
luaL_newmetatable (L, DIR_METATABLE); |
242 |
- /* set its __gc field */ |
243 |
- lua_pushstring (L, "__index"); |
244 |
+ |
245 |
+ /* Method table */ |
246 |
lua_newtable(L); |
247 |
- lua_pushstring (L, "next"); |
248 |
lua_pushcfunction (L, dir_iter); |
249 |
- lua_settable(L, -3); |
250 |
- lua_pushstring (L, "close"); |
251 |
+ lua_setfield(L, -2, "next"); |
252 |
lua_pushcfunction (L, dir_close); |
253 |
- lua_settable(L, -3); |
254 |
- lua_settable (L, -3); |
255 |
- lua_pushstring (L, "__gc"); |
256 |
+ lua_setfield(L, -2, "close"); |
257 |
+ |
258 |
+ /* Metamethods */ |
259 |
+ lua_setfield(L, -2, "__index"); |
260 |
lua_pushcfunction (L, dir_close); |
261 |
- lua_settable (L, -3); |
262 |
+ lua_setfield (L, -2, "__gc"); |
263 |
return 1; |
264 |
} |
265 |
|
266 |
@@ -523,10 +571,13 @@ |
267 |
*/ |
268 |
static int lock_create_meta (lua_State *L) { |
269 |
luaL_newmetatable (L, LOCK_METATABLE); |
270 |
- /* set its __gc field */ |
271 |
+ |
272 |
+ /* Method table */ |
273 |
lua_newtable(L); |
274 |
lua_pushcfunction(L, lfs_unlock_dir); |
275 |
lua_setfield(L, -2, "free"); |
276 |
+ |
277 |
+ /* Metamethods */ |
278 |
lua_setfield(L, -2, "__index"); |
279 |
lua_pushcfunction(L, lfs_unlock_dir); |
280 |
lua_setfield(L, -2, "__gc"); |
281 |
@@ -669,6 +720,46 @@ |
282 |
#endif |
283 |
} |
284 |
|
285 |
+ /* |
286 |
+** Convert the inode protection mode to a permission list. |
287 |
+*/ |
288 |
+ |
289 |
+#ifdef _WIN32 |
290 |
+static const char *perm2string (unsigned short mode) { |
291 |
+ static char perms[10] = "---------\0"; |
292 |
+ int i; |
293 |
+ for (i=0;i<9;i++) perms[i]='-'; |
294 |
+ if (mode & _S_IREAD) |
295 |
+ { perms[0] = 'r'; perms[3] = 'r'; perms[6] = 'r'; } |
296 |
+ if (mode & _S_IWRITE) |
297 |
+ { perms[1] = 'w'; perms[4] = 'w'; perms[7] = 'w'; } |
298 |
+ if (mode & _S_IEXEC) |
299 |
+ { perms[2] = 'x'; perms[5] = 'x'; perms[8] = 'x'; } |
300 |
+ return perms; |
301 |
+} |
302 |
+#else |
303 |
+static const char *perm2string (mode_t mode) { |
304 |
+ static char perms[10] = "---------\0"; |
305 |
+ int i; |
306 |
+ for (i=0;i<9;i++) perms[i]='-'; |
307 |
+ if (mode & S_IRUSR) perms[0] = 'r'; |
308 |
+ if (mode & S_IWUSR) perms[1] = 'w'; |
309 |
+ if (mode & S_IXUSR) perms[2] = 'x'; |
310 |
+ if (mode & S_IRGRP) perms[3] = 'r'; |
311 |
+ if (mode & S_IWGRP) perms[4] = 'w'; |
312 |
+ if (mode & S_IXGRP) perms[5] = 'x'; |
313 |
+ if (mode & S_IROTH) perms[6] = 'r'; |
314 |
+ if (mode & S_IWOTH) perms[7] = 'w'; |
315 |
+ if (mode & S_IXOTH) perms[8] = 'x'; |
316 |
+ return perms; |
317 |
+} |
318 |
+#endif |
319 |
+ |
320 |
+/* permssions string */ |
321 |
+static void push_st_perm (lua_State *L, STAT_STRUCT *info) { |
322 |
+ lua_pushstring (L, perm2string (info->st_mode)); |
323 |
+} |
324 |
+ |
325 |
typedef void (*_push_function) (lua_State *L, STAT_STRUCT *info); |
326 |
|
327 |
struct _stat_members { |
328 |
@@ -688,6 +779,7 @@ |
329 |
{ "modification", push_st_mtime }, |
330 |
{ "change", push_st_ctime }, |
331 |
{ "size", push_st_size }, |
332 |
+ { "permissions", push_st_perm }, |
333 |
#ifndef _WIN32 |
334 |
{ "blocks", push_st_blocks }, |
335 |
{ "blksize", push_st_blksize }, |
336 |
@@ -747,17 +839,9 @@ |
337 |
/* |
338 |
** Get symbolic link information using lstat. |
339 |
*/ |
340 |
-#ifndef _WIN32 |
341 |
static int link_info (lua_State *L) { |
342 |
return _file_info_ (L, LSTAT_FUNC); |
343 |
} |
344 |
-#else |
345 |
-static int link_info (lua_State *L) { |
346 |
- lua_pushboolean(L, 0); |
347 |
- lua_pushliteral(L, "symlinkattributes not supported on this platform"); |
348 |
- return 2; |
349 |
-} |
350 |
-#endif |
351 |
|
352 |
|
353 |
/* |
354 |
@@ -765,13 +849,13 @@ |
355 |
*/ |
356 |
static void set_info (lua_State *L) { |
357 |
lua_pushliteral (L, "_COPYRIGHT"); |
358 |
- lua_pushliteral (L, "Copyright (C) 2003-2009 Kepler Project"); |
359 |
+ lua_pushliteral (L, "Copyright (C) 2003-2012 Kepler Project"); |
360 |
lua_settable (L, -3); |
361 |
lua_pushliteral (L, "_DESCRIPTION"); |
362 |
lua_pushliteral (L, "LuaFileSystem is a Lua library developed to complement the set of functions related to file systems offered by the standard Lua distribution"); |
363 |
lua_settable (L, -3); |
364 |
lua_pushliteral (L, "_VERSION"); |
365 |
- lua_pushliteral (L, "LuaFileSystem 1.5.0"); |
366 |
+ lua_pushliteral (L, "LuaFileSystem "LFS_VERSION); |
367 |
lua_settable (L, -3); |
368 |
} |
369 |
|
370 |
@@ -781,6 +865,7 @@ |
371 |
{"chdir", change_dir}, |
372 |
{"currentdir", get_dir}, |
373 |
{"dir", dir_iter_factory}, |
374 |
+ {"link", make_link}, |
375 |
{"lock", file_lock}, |
376 |
{"mkdir", make_dir}, |
377 |
{"rmdir", remove_dir}, |
378 |
@@ -795,7 +880,9 @@ |
379 |
int luaopen_lfs (lua_State *L) { |
380 |
dir_create_meta (L); |
381 |
lock_create_meta (L); |
382 |
- luaL_register (L, "lfs", fslib); |
383 |
+ luaL_newlib (L, fslib); |
384 |
+ lua_pushvalue(L, -1); |
385 |
+ lua_setglobal(L, LFS_LIBNAME); |
386 |
set_info (L); |
387 |
return 1; |
388 |
} |