diff options
Diffstat (limited to 'apps/plugins/lua/liolib.c')
-rw-r--r-- | apps/plugins/lua/liolib.c | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/apps/plugins/lua/liolib.c b/apps/plugins/lua/liolib.c index fb6765492b..81edb9a534 100644 --- a/apps/plugins/lua/liolib.c +++ b/apps/plugins/lua/liolib.c | |||
@@ -40,7 +40,7 @@ static int pushresult (lua_State *L, int i, const char *filename) { | |||
40 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); | 40 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); |
41 | else | 41 | else |
42 | lua_pushfstring(L, "%s", strerror(en)); | 42 | lua_pushfstring(L, "%s", strerror(en)); |
43 | lua_pushinteger(L, 0); | 43 | lua_pushinteger(L, en); |
44 | return 3; | 44 | return 3; |
45 | } | 45 | } |
46 | } | 46 | } |
@@ -51,6 +51,7 @@ static void fileerror (lua_State *L, int arg, const char *filename) { | |||
51 | luaL_argerror(L, arg, lua_tostring(L, -1)); | 51 | luaL_argerror(L, arg, lua_tostring(L, -1)); |
52 | } | 52 | } |
53 | 53 | ||
54 | #define tofilep(L) ((int*) luaL_checkudata(L, 1, LUA_FILEHANDLE)) | ||
54 | 55 | ||
55 | static int io_type (lua_State *L) { | 56 | static int io_type (lua_State *L) { |
56 | void *ud; | 57 | void *ud; |
@@ -68,7 +69,7 @@ static int io_type (lua_State *L) { | |||
68 | 69 | ||
69 | 70 | ||
70 | static int* tofile (lua_State *L) { | 71 | static int* tofile (lua_State *L) { |
71 | int *f = (int*) luaL_checkudata(L, 1, LUA_FILEHANDLE); | 72 | int *f = tofilep(L); |
72 | if (*f < 0) | 73 | if (*f < 0) |
73 | luaL_error(L, "attempt to use a closed file"); | 74 | luaL_error(L, "attempt to use a closed file"); |
74 | return f; | 75 | return f; |
@@ -115,20 +116,20 @@ static int io_close (lua_State *L) { | |||
115 | 116 | ||
116 | 117 | ||
117 | static int io_gc (lua_State *L) { | 118 | static int io_gc (lua_State *L) { |
118 | int f = *(int*) luaL_checkudata(L, 1, LUA_FILEHANDLE); | 119 | int *f = tofilep(L); |
119 | /* ignore closed files */ | 120 | /* ignore closed files */ |
120 | if (f >= 0) | 121 | if (*f >= 0) |
121 | aux_close(L); | 122 | aux_close(L); |
122 | return 0; | 123 | return 0; |
123 | } | 124 | } |
124 | 125 | ||
125 | 126 | ||
126 | static int io_tostring (lua_State *L) { | 127 | static int io_tostring (lua_State *L) { |
127 | int f = *(int*) luaL_checkudata(L, 1, LUA_FILEHANDLE); | 128 | int *f = tofilep(L); |
128 | if (f < 0) | 129 | if (*f < 0) |
129 | lua_pushliteral(L, "file (closed)"); | 130 | lua_pushliteral(L, "file (closed)"); |
130 | else | 131 | else |
131 | lua_pushfstring(L, "file (%d)", f); | 132 | lua_pushfstring(L, "file (%d)", *f); |
132 | return 1; | 133 | return 1; |
133 | } | 134 | } |
134 | 135 | ||
@@ -137,28 +138,33 @@ static int io_open (lua_State *L) { | |||
137 | const char *filename = luaL_checkstring(L, 1); | 138 | const char *filename = luaL_checkstring(L, 1); |
138 | const char *mode = luaL_optstring(L, 2, "r"); | 139 | const char *mode = luaL_optstring(L, 2, "r"); |
139 | int *pf = newfile(L); | 140 | int *pf = newfile(L); |
140 | int flags = 0; | 141 | int flags, wrmode; |
141 | if(*(mode+1) == '+') { | 142 | |
142 | flags = O_RDWR; | 143 | switch(*mode) { |
143 | switch(*mode) { | 144 | case 'r': |
144 | case 'w': | 145 | flags = O_RDONLY; |
145 | flags |= O_TRUNC; break; | 146 | wrmode = 0; |
146 | case 'a': | 147 | break; |
147 | flags |= O_APPEND; break; | 148 | case 'w': |
148 | } | 149 | flags = O_WRONLY; |
149 | } | 150 | wrmode = O_CREAT | O_TRUNC; |
150 | else { | 151 | break; |
151 | switch(*mode) { | 152 | case 'a': |
152 | case 'r': | 153 | flags = O_WRONLY; |
153 | flags = O_RDONLY; break; | 154 | wrmode = O_CREAT | O_APPEND; |
154 | case 'w': | 155 | break; |
155 | flags = O_WRONLY | O_TRUNC; break; | 156 | default: |
156 | case 'a': | 157 | flags = 0; |
157 | flags = O_WRONLY | O_APPEND; break; | 158 | wrmode = 0; |
158 | } | 159 | return luaL_error(L, "invalid option " LUA_QL("%c") " to " |
160 | LUA_QL("open"), *mode); | ||
159 | } | 161 | } |
160 | if((*mode == 'w' || *mode == 'a') && !rb->file_exists(filename)) | 162 | |
161 | flags |= O_CREAT; | 163 | if(*(mode+1) == '+') |
164 | flags = O_RDWR; | ||
165 | |||
166 | flags |= wrmode; | ||
167 | |||
162 | *pf = rb->open(filename, flags, 0666); | 168 | *pf = rb->open(filename, flags, 0666); |
163 | return (*pf < 0) ? pushresult(L, 0, filename) : 1; | 169 | return (*pf < 0) ? pushresult(L, 0, filename) : 1; |
164 | } | 170 | } |
@@ -252,7 +258,10 @@ static int read_number (lua_State *L, int *f) { | |||
252 | lua_pushnumber(L, d); | 258 | lua_pushnumber(L, d); |
253 | return 1; | 259 | return 1; |
254 | } | 260 | } |
255 | else return 0; /* read fails */ | 261 | else { |
262 | lua_pushnil(L); /* "result" to be removed */ | ||
263 | return 0; /* read fails */ | ||
264 | } | ||
256 | } | 265 | } |
257 | 266 | ||
258 | 267 | ||
@@ -412,14 +421,14 @@ static int f_write (lua_State *L) { | |||
412 | static int f_seek (lua_State *L) { | 421 | static int f_seek (lua_State *L) { |
413 | static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; | 422 | static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; |
414 | static const char *const modenames[] = {"set", "cur", "end", NULL}; | 423 | static const char *const modenames[] = {"set", "cur", "end", NULL}; |
415 | int f = *tofile(L); | 424 | int *f = tofile(L); |
416 | int op = luaL_checkoption(L, 2, "cur", modenames); | 425 | int op = luaL_checkoption(L, 2, "cur", modenames); |
417 | long offset = luaL_optlong(L, 3, 0); | 426 | long offset = luaL_optlong(L, 3, 0); |
418 | off_t size = rb->lseek(f, offset, mode[op]); | 427 | off_t size = rb->lseek(*f, offset, mode[op]); |
419 | if (size < 0 || size > MAX_INT) /* signed limit */ | 428 | if (size < 0 || size > MAX_INT) /* signed limit */ |
420 | return pushresult(L, 0, NULL); /* error */ | 429 | return pushresult(L, 0, NULL); /* error */ |
421 | else { | 430 | else { |
422 | lua_pushinteger(L, (LUA_INTEGER) size ); | 431 | lua_pushinteger(L, (LUA_INTEGER) size ); |
423 | return 1; | 432 | return 1; |
424 | } | 433 | } |
425 | } | 434 | } |