# HG changeset patch # User jbe # Date 1427384310 -3600 # Node ID b1748c6c3c89ea09d0248c5d2081a7ee30aea509 # Parent e00d11c12b689e665bb857a2aaea60a897689177 extos.stat(...) returns false (instead of nil) if file does not exist; Added extos.lstat(...) and extos.fstat(...) diff -r e00d11c12b68 -r b1748c6c3c89 libraries/extos/extos.autodoc.lua --- a/libraries/extos/extos.autodoc.lua Thu Mar 26 12:26:00 2015 +0100 +++ b/libraries/extos/extos.autodoc.lua Thu Mar 26 16:38:30 2015 +0100 @@ -20,13 +20,30 @@ --[[-- -filestat_table, -- table with information on the file -errmsg = -- error message if file information could not be read +directory_entries, -- table of directory entries +errmsg = -- error message if directory could not be read +extos.listdir( + path -- path name +) + +This function returns a table containing strings representing each entry in a directory. On error nil and an error message are returned. + +--]]-- +-- implemented in extos.c as +-- static int extos_listdir(lua_State *L) +--//-- + + +--[[-- +filestat_table, -- table with information on the file, false if file does not exist, nil on error +errmsg = -- error message if file information could not be read or file does not exist extos.stat( filename -- path to a file on the file system ) -Return information on a file. The returned table contains the following fields: +Return information on a file, following symbolic links if applicable. See also: extos.lstat(...) and extos.fstat(...). + +The returned table contains the following fields: - "dev" (numeric ID of the device containing the file) - "ino" (file's inode number) @@ -48,7 +65,9 @@ - "isreg" (true if regular file) - "issock" (true if socket) -On error, nil and an error message are returned. +If the file does not exist, false and an error message are returned. +In case of any other error, nil and an error message are returned. + --]]-- -- implemented in extos.c as @@ -57,17 +76,36 @@ --[[-- -directory_entries, -- table of directory entries -errmsg = -- error message if directory could not be read -extos.listdir( - path -- path name +filestat_table, -- table with information on the file, false if file does not exist, nil on error +errmsg = -- error message if file information could not be read or file does not exist +extos.lstat( + filename -- path to a file on the file system ) -This function returns a table containing strings representing each entry in a directory. On error nil and an error message are returned. +Return information on a file. Symbolic links are not followed, which means that if the filename points to a symbolic link, information on that symbolic link will be returned. Otherwise this function behaves like extos.stat(filename). + +See extos.stat(...) for further information. --]]-- -- implemented in extos.c as --- static int extos_listdir(lua_State *L) +-- static int extos_stat(lua_State *L) +--//-- + + +--[[-- +filestat_table, -- table with information on the file, nil on error +errmsg = -- error message if file information could not be determined +extos.fstat( + file_handle -- Lua file handle (e.g. as returned by io.open(...)) +) + +Return information on an open file. The file is specified by passing an open file handle to this function. Otherwise this function behaves like extos.stat(...). + +See extos.stat(...) for further information. + +--]]-- +-- implemented in extos.c as +-- static int extos_stat(lua_State *L) --//-- diff -r e00d11c12b68 -r b1748c6c3c89 libraries/extos/extos.c --- a/libraries/extos/extos.c Thu Mar 26 12:26:00 2015 +0100 +++ b/libraries/extos/extos.c Thu Mar 26 16:38:30 2015 +0100 @@ -296,16 +296,30 @@ return 1; } -static int extos_stat(lua_State *L) { - const char *filename; +#define EXTOS_STAT_FOLLOW -1 +#define EXTOS_STAT_NOFOLLOW -2 + +static int extos_stat_impl(lua_State *L, int fd) { struct stat sb; - filename = luaL_checkstring(L, 1); - if (stat(filename, &sb)) { - char errmsg[EXTOS_MAX_ERRLEN+1]; - strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); - lua_pushnil(L); - lua_pushfstring(L, "Could not get file stats for \"%s\": %s", filename, errmsg); - return 2; + if (fd < 0) { + const char *filename; + filename = luaL_checkstring(L, 1); + if (fd == EXTOS_STAT_FOLLOW ? stat(filename, &sb) : lstat(filename, &sb)) { + char errmsg[EXTOS_MAX_ERRLEN+1]; + strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); + if (errno == ENOENT) lua_pushboolean(L, 0); + else lua_pushnil(L); + lua_pushfstring(L, "Could not get file stats for \"%s\": %s", filename, errmsg); + return 2; + } + } else { + if (fstat(fd, &sb)) { + char errmsg[EXTOS_MAX_ERRLEN+1]; + strerror_r(errno, errmsg, EXTOS_MAX_ERRLEN+1); + lua_pushnil(L); + lua_pushfstring(L, "Could not get file stats for open file: %s", errmsg); + return 2; + } } lua_createtable(L, 0, 19); lua_pushinteger(L, sb.st_dev); @@ -349,6 +363,21 @@ return 1; } +static int extos_stat(lua_State *L) { + return extos_stat_impl(L, EXTOS_STAT_FOLLOW); +} + +static int extos_lstat(lua_State *L) { + return extos_stat_impl(L, EXTOS_STAT_NOFOLLOW); +} + +static int extos_fstat(lua_State *L) { + luaL_Stream *stream; + stream = luaL_checkudata(L, 1, LUA_FILEHANDLE); + if (!stream->closef) luaL_error(L, "attempt to use a closed file"); + return extos_stat_impl(L, fileno(stream->f)); +} + static int extos_crypt(lua_State *L) { const char *key; const char *salt; @@ -386,6 +415,8 @@ {"pfilter", extos_pfilter}, {"listdir", extos_listdir}, {"stat", extos_stat}, + {"lstat", extos_lstat}, + {"fstat", extos_fstat}, {"crypt", extos_crypt}, {"hires_time", extos_hires_time}, {"monotonic_hires_time", extos_monotonic_hires_time},