Fix lua lseek command / io lib
lua would not return or set arbitrary file positions file:seek("set", 0) worked file:seek("cur") worked but setting an offset or file:seek("end") failed I tracked this down to a bug checking the return of rb->lseek on error lseek returns a negative number and returns the file position otherwise, the function was checking for if(N) instead of if(N < 0) Fixed - limited size of lseek to size of signed LuaNumber Fixed - io:lines() stopped after first line containing only a newline instead of returning a blank line and continuing till EOF this fixes file:read("*l") as well Fixed - ssize_t for read() with error checking Change-Id: Ie859b288fb8f6814f1b3ae30992ecf78f2669de7
This commit is contained in:
parent
1f63604e2c
commit
0d41e13cf4
1 changed files with 14 additions and 11 deletions
|
@ -18,7 +18,7 @@
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
#include "rocklibc.h"
|
#include "rocklibc.h"
|
||||||
|
|
||||||
|
#include "llimits.h"
|
||||||
|
|
||||||
#define IO_INPUT 1
|
#define IO_INPUT 1
|
||||||
#define IO_OUTPUT 2
|
#define IO_OUTPUT 2
|
||||||
|
@ -256,9 +256,9 @@ static int read_number (lua_State *L, int *f) {
|
||||||
|
|
||||||
|
|
||||||
static int test_eof (lua_State *L, int *f) {
|
static int test_eof (lua_State *L, int *f) {
|
||||||
ssize_t s = rb->lseek(*f, 0, SEEK_CUR);
|
off_t s = rb->lseek(*f, 0, SEEK_CUR);
|
||||||
lua_pushlstring(L, NULL, 0);
|
lua_pushlstring(L, NULL, 0);
|
||||||
return s != rb->filesize(*f);
|
return s < rb->filesize(*f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,10 +268,11 @@ static int _read_line (lua_State *L, int *f) {
|
||||||
luaL_buffinit(L, &b);
|
luaL_buffinit(L, &b);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t l;
|
size_t l;
|
||||||
size_t r;
|
off_t r;
|
||||||
char *p = luaL_prepbuffer(&b);
|
char *p = luaL_prepbuffer(&b);
|
||||||
r = rb->read_line(*f, p, LUAL_BUFFERSIZE);
|
r = rb->read_line(*f, p, LUAL_BUFFERSIZE);
|
||||||
l = strlen(p);
|
l = strlen(p);
|
||||||
|
|
||||||
if (l == 0 || p[l-1] != '\n')
|
if (l == 0 || p[l-1] != '\n')
|
||||||
luaL_addsize(&b, l);
|
luaL_addsize(&b, l);
|
||||||
else {
|
else {
|
||||||
|
@ -281,7 +282,7 @@ static int _read_line (lua_State *L, int *f) {
|
||||||
}
|
}
|
||||||
if (r < LUAL_BUFFERSIZE) { /* eof? */
|
if (r < LUAL_BUFFERSIZE) { /* eof? */
|
||||||
luaL_pushresult(&b); /* close buffer */
|
luaL_pushresult(&b); /* close buffer */
|
||||||
return (lua_objlen(L, -1) > 0); /* check whether read something */
|
return (r > 0); /* check whether read something */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,7 +290,7 @@ static int _read_line (lua_State *L, int *f) {
|
||||||
|
|
||||||
static int read_chars (lua_State *L, int *f, size_t n) {
|
static int read_chars (lua_State *L, int *f, size_t n) {
|
||||||
size_t rlen; /* how much to read */
|
size_t rlen; /* how much to read */
|
||||||
size_t nr; /* number of chars actually read */
|
ssize_t nr; /* number of chars actually read */
|
||||||
luaL_Buffer b;
|
luaL_Buffer b;
|
||||||
luaL_buffinit(L, &b);
|
luaL_buffinit(L, &b);
|
||||||
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
|
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
|
||||||
|
@ -297,9 +298,11 @@ static int read_chars (lua_State *L, int *f, size_t n) {
|
||||||
char *p = luaL_prepbuffer(&b);
|
char *p = luaL_prepbuffer(&b);
|
||||||
if (rlen > n) rlen = n; /* cannot read more than asked */
|
if (rlen > n) rlen = n; /* cannot read more than asked */
|
||||||
nr = rb->read(*f, p, rlen);
|
nr = rb->read(*f, p, rlen);
|
||||||
|
if (nr < 0)
|
||||||
|
luaL_error(L, "error reading file");
|
||||||
luaL_addsize(&b, nr);
|
luaL_addsize(&b, nr);
|
||||||
n -= nr; /* still have to read `n' chars */
|
n -= nr; /* still have to read `n' chars */
|
||||||
} while (n > 0 && nr == rlen); /* until end of count or eof */
|
} while (n > 0 && nr == (ssize_t) rlen); /* until end of count or eof */
|
||||||
luaL_pushresult(&b); /* close buffer */
|
luaL_pushresult(&b); /* close buffer */
|
||||||
return (n == 0 || lua_objlen(L, -1) > 0);
|
return (n == 0 || lua_objlen(L, -1) > 0);
|
||||||
}
|
}
|
||||||
|
@ -414,11 +417,11 @@ static int f_seek (lua_State *L) {
|
||||||
int f = *tofile(L);
|
int f = *tofile(L);
|
||||||
int op = luaL_checkoption(L, 2, "cur", modenames);
|
int op = luaL_checkoption(L, 2, "cur", modenames);
|
||||||
long offset = luaL_optlong(L, 3, 0);
|
long offset = luaL_optlong(L, 3, 0);
|
||||||
op = rb->lseek(f, offset, mode[op]);
|
off_t size = rb->lseek(f, offset, mode[op]);
|
||||||
if (op)
|
if (size < 0 || size > MAX_INT) /* signed limit */
|
||||||
return pushresult(L, 0, NULL); /* error */
|
return pushresult(L, 0, NULL); /* error */
|
||||||
else {
|
else {
|
||||||
lua_pushinteger(L, rb->lseek(f, 0, SEEK_CUR));
|
lua_pushinteger(L, (LUA_INTEGER) size );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,4 +468,4 @@ LUALIB_API int luaopen_io (lua_State *L) {
|
||||||
/* create (and set) default files */
|
/* create (and set) default files */
|
||||||
lua_pop(L, 1); /* pop environment for default files */
|
lua_pop(L, 1); /* pop environment for default files */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
Loading…
Reference in a new issue