--- Read a file.
-- @param file File object.
--- @return File data as a string, or false on error. May be up to 16K bytes
--- large and contain embedded zero's. On EOF an empty string is returned.
+-- @param size Positive number specifying how many bytes to read.
+-- @return File data as a string, or false on error. May be *up to* 'size' bytes
+-- large and contain embedded zero's. On EOF the empty string is returned.
-- @return Error object on failure.
-function eio.fread(file)
+function eio.fread(file, size)
local rc, re, errstring, buffer
rc, re = is_eio_object(file)
return false, re
end
- buffer, errstring = leio.fread(file.handle)
+ if type(size) ~= "number" then
+ return false, err.new("error reading file: size argument has wrong type")
+ end
+
+ if size <= 0 or size > 2147483648 --[[2GB]] then
+ return false, err("error reading file: size argument out of range")
+ end
+
+ buffer, errstring = leio.fread(file.handle, size)
if not buffer then
return false, err.new("error reading file: %s", errstring)
end
static int
eio_fread(lua_State *lua)
{
- char buf[16384];
- size_t ret;
+ char *buf;
FILE *f;
+ size_t ret, sz;
f = lua_touserdata(lua, 1);
- if (f == NULL) {
+ sz = lua_tointeger(lua, 2);
+ if (f == NULL || sz == 0) {
lua_pushboolean(lua, 0);
lua_pushstring(lua,
"eio_fread: one or more arguments of wrong type/missing");
return 2;
}
+ buf = malloc(sz);
+ if (buf == NULL) {
+ lua_pushboolean(lua, 0);
+ lua_pushstring(lua, strerror(errno));
+ return 2;
+ }
- ret = fread(buf, 1, sizeof(buf), f);
- if (ret != sizeof(buf)) {
+ ret = fread(buf, 1, sz, f);
+ if (ret != sz) {
if (ferror(f)) {
- lua_pushboolean(lua, 0);
- lua_pushstring(lua, strerror(errno));
- return 2;
+ free(buf);
+ lua_pushboolean(lua, 0);
+ lua_pushstring(lua, strerror(errno));
+ return 2;
}
if (ret <= 0 && feof(f)) {
/* ret <= 0: do not discard data on short reads,
* only signal EOF when all data is returned. */
+ free(buf);
lua_pushstring(lua, "");
return 1;
}
}
lua_pushlstring(lua, buf, ret);
+ free(buf);
return 1;
}