|
Packit |
437b5e |
/*
|
|
Packit |
437b5e |
* POSIX library for Lua 5.1, 5.2 & 5.3.
|
|
Packit |
437b5e |
* (c) Gary V. Vaughan <gary@vaughan.pe>, 2013-2015
|
|
Packit |
437b5e |
* (c) Reuben Thomas <rrt@sc3d.org> 2010-2013
|
|
Packit |
437b5e |
* (c) Natanael Copa <natanael.copa@gmail.com> 2008-2010
|
|
Packit |
437b5e |
* Clean up and bug fixes by Leo Razoumov <slonik.az@gmail.com> 2006-10-11
|
|
Packit |
437b5e |
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> 07 Apr 2006 23:17:49
|
|
Packit |
437b5e |
* Based on original by Claudio Terra for Lua 3.x.
|
|
Packit |
437b5e |
* With contributions by Roberto Ierusalimschy.
|
|
Packit |
437b5e |
* With documentation from Steve Donovan 2012
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
File Status Querying and Setting.
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
@module posix.sys.stat
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <config.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <sys/stat.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include "_helpers.c"
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
File state record.
|
|
Packit |
437b5e |
@table PosixStat
|
|
Packit |
437b5e |
@int st_dev device id
|
|
Packit |
437b5e |
@int st_ino inode number
|
|
Packit |
437b5e |
@int st_mode mode of file
|
|
Packit |
437b5e |
@int st_nlink number of hardlinks to file
|
|
Packit |
437b5e |
@int st_uid user id of file owner
|
|
Packit |
437b5e |
@int st_gid group id of file owner
|
|
Packit |
437b5e |
@int st_rdev additional device specific id for special files
|
|
Packit |
437b5e |
@int st_size file size in bytes
|
|
Packit |
437b5e |
@int st_atime time of last access
|
|
Packit |
437b5e |
@int st_mtime time of last data modification
|
|
Packit |
437b5e |
@int st_ctime time of last state change
|
|
Packit |
437b5e |
@int st_blksize preferred block size
|
|
Packit |
437b5e |
@int st_blocks number of blocks allocated
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
pushstat(lua_State *L, struct stat *st)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (!st)
|
|
Packit |
437b5e |
return lua_pushnil(L), 1;
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
lua_createtable(L, 0, 13);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
setintegerfield(st, st_dev);
|
|
Packit |
437b5e |
setintegerfield(st, st_ino);
|
|
Packit |
437b5e |
setintegerfield(st, st_mode);
|
|
Packit |
437b5e |
setintegerfield(st, st_nlink);
|
|
Packit |
437b5e |
setintegerfield(st, st_uid);
|
|
Packit |
437b5e |
setintegerfield(st, st_gid);
|
|
Packit |
437b5e |
setintegerfield(st, st_rdev);
|
|
Packit |
437b5e |
setintegerfield(st, st_size);
|
|
Packit |
437b5e |
setintegerfield(st, st_blksize);
|
|
Packit |
437b5e |
setintegerfield(st, st_blocks);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* st_[amc]time is a macro on at least Mac OS, so we have to
|
|
Packit |
437b5e |
assign field name strings manually. */
|
|
Packit |
437b5e |
pushintegerfield("st_atime", st->st_atime);
|
|
Packit |
437b5e |
pushintegerfield("st_mtime", st->st_mtime);
|
|
Packit |
437b5e |
pushintegerfield("st_ctime", st->st_ctime);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
settypemetatable("PosixStat");
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Test for a block special file.
|
|
Packit |
437b5e |
@function S_ISBLK
|
|
Packit |
437b5e |
@int mode the st_mode field of a @{PosixStat}
|
|
Packit |
437b5e |
@treturn int non-zero if *mode* represents a block special file
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
PS_ISBLK(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(S_ISBLK((mode_t) checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Test for a character special file.
|
|
Packit |
437b5e |
@function S_ISCHR
|
|
Packit |
437b5e |
@int mode the st_mode field of a @{PosixStat}
|
|
Packit |
437b5e |
@treturn int non-zero if *mode* represents a character special file
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
PS_ISCHR(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(S_ISCHR((mode_t) checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Test for a directory.
|
|
Packit |
437b5e |
@function S_ISDIR
|
|
Packit |
437b5e |
@int mode the st_mode field of a @{PosixStat}
|
|
Packit |
437b5e |
@treturn int non-zero if *mode* represents a directory
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
PS_ISDIR(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(S_ISDIR((mode_t) checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Test for a fifo special file.
|
|
Packit |
437b5e |
@function S_ISFIFO
|
|
Packit |
437b5e |
@int mode the st_mode field of a @{PosixStat}
|
|
Packit |
437b5e |
@treturn int non-zero if *mode* represents a fifo special file
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
PS_ISFIFO(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(S_ISFIFO((mode_t) checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Test for a symbolic link.
|
|
Packit |
437b5e |
@function S_ISLNK
|
|
Packit |
437b5e |
@int mode the st_mode field of a @{PosixStat}
|
|
Packit |
437b5e |
@treturn int non-zero if *mode* represents a symbolic link
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
PS_ISLNK(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(S_ISLNK((mode_t) checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Test for a regular file.
|
|
Packit |
437b5e |
@function S_ISREG
|
|
Packit |
437b5e |
@int mode the st_mode field of a @{PosixStat}
|
|
Packit |
437b5e |
@treturn int non-zero if *mode* represents a regular file
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
PS_ISREG(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(S_ISREG((mode_t) checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Test for a socket.
|
|
Packit |
437b5e |
@function S_ISSOCK
|
|
Packit |
437b5e |
@int mode the st_mode field of a @{PosixStat}
|
|
Packit |
437b5e |
@treturn int non-zero if *mode* represents a socket
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
PS_ISSOCK(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(S_ISSOCK((mode_t) checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Change the mode of the path.
|
|
Packit |
437b5e |
@function chmod
|
|
Packit |
437b5e |
@string path existing file path to act on
|
|
Packit |
437b5e |
@int mode access modes to set for *path*
|
|
Packit |
437b5e |
@treturn[1] int `0`, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see chmod(2)
|
|
Packit |
437b5e |
@usage P.chmod ('bin/dof', bit.bor (P.S_IRWXU, P.S_IRGRP))
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pchmod(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
return pushresult(L, chmod(path, (mode_t) checkint(L, 2)), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Information about an existing file path.
|
|
Packit |
437b5e |
If file is a symbolic link, return information about the link itself.
|
|
Packit |
437b5e |
@function lstat
|
|
Packit |
437b5e |
@string path file to act on
|
|
Packit |
437b5e |
@treturn PosixStat information about *path*
|
|
Packit |
437b5e |
@see lstat(2)
|
|
Packit |
437b5e |
@see stat
|
|
Packit |
437b5e |
@usage for a, b in pairs (P.lstat "/etc/") do print (a, b) end
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Plstat(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
struct stat s;
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
if (lstat(path, &s) == -1)
|
|
Packit |
437b5e |
return pusherror(L, path);
|
|
Packit |
437b5e |
return pushstat(L, &s);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Make a directory.
|
|
Packit |
437b5e |
@function mkdir
|
|
Packit |
437b5e |
@string path location in file system to create directory
|
|
Packit |
437b5e |
@int[opt=511] mode access modes to set for *path*
|
|
Packit |
437b5e |
@treturn[1] int `0`, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see mkdir(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pmkdir(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
return pushresult(L, mkdir(path, (mode_t) optint(L, 2, 0777)), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Make a FIFO pipe.
|
|
Packit |
437b5e |
@function mkfifo
|
|
Packit |
437b5e |
@string path location in file system to create fifo
|
|
Packit |
437b5e |
@int[opt=511] mode access modes to set for *path*
|
|
Packit |
437b5e |
@treturn[1] int file descriptor for *path*, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see mkfifo(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pmkfifo(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
return pushresult(L, mkfifo(path, (mode_t) optint(L, 2, 0777)), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Information about an existing file path.
|
|
Packit |
437b5e |
If file is a symbolic link, return information about the file the link points to.
|
|
Packit |
437b5e |
@function stat
|
|
Packit |
437b5e |
@string path file to act on
|
|
Packit |
437b5e |
@treturn PosixStat information about *path*
|
|
Packit |
437b5e |
@see stat(2)
|
|
Packit |
437b5e |
@see lstat
|
|
Packit |
437b5e |
@usage for a, b in pairs (P.stat "/etc/") do print (a, b) end
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pstat(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
struct stat s;
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
if (stat(path, &s) == -1)
|
|
Packit |
437b5e |
return pusherror(L, path);
|
|
Packit |
437b5e |
return pushstat(L, &s);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Set file mode creation mask.
|
|
Packit |
437b5e |
@function umask
|
|
Packit |
437b5e |
@int[opt] mode new file creation mask
|
|
Packit |
437b5e |
@treturn int previous umask
|
|
Packit |
437b5e |
@see umask(2)
|
|
Packit |
437b5e |
@see posix.umask
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pumask(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(umask((mode_t) checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static const luaL_Reg posix_sys_stat_fns[] =
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
LPOSIX_FUNC( PS_ISBLK ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( PS_ISCHR ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( PS_ISDIR ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( PS_ISFIFO ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( PS_ISLNK ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( PS_ISREG ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( PS_ISSOCK ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pchmod ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Plstat ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pmkdir ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pmkfifo ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pstat ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pumask ),
|
|
Packit |
437b5e |
{NULL, NULL}
|
|
Packit |
437b5e |
};
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Constants.
|
|
Packit |
437b5e |
@section constants
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Stat constants.
|
|
Packit |
437b5e |
Any constants not available in the underlying system will be `nil` valued.
|
|
Packit |
437b5e |
@table posix.sys.stat
|
|
Packit |
437b5e |
@int S_IFMT file type mode bitmask
|
|
Packit |
437b5e |
@int S_IFBLK block special
|
|
Packit |
437b5e |
@int S_IFCHR character special
|
|
Packit |
437b5e |
@int S_IFDIR directory
|
|
Packit |
437b5e |
@int S_IFIFO fifo
|
|
Packit |
437b5e |
@int S_IFLNK symbolic link
|
|
Packit |
437b5e |
@int S_IFREG regular file
|
|
Packit |
437b5e |
@int S_IFSOCK socket
|
|
Packit |
437b5e |
@int S_IRWXU user read, write and execute
|
|
Packit |
437b5e |
@int S_IRUSR user read
|
|
Packit |
437b5e |
@int S_IWUSR user write
|
|
Packit |
437b5e |
@int S_IXUSR user execute
|
|
Packit |
437b5e |
@int S_IRWXG group read, write and execute
|
|
Packit |
437b5e |
@int S_IRGRP group read
|
|
Packit |
437b5e |
@int S_IWGRP group write
|
|
Packit |
437b5e |
@int S_IXGRP group execute
|
|
Packit |
437b5e |
@int S_IRWXO other read, write and execute
|
|
Packit |
437b5e |
@int S_IROTH other read
|
|
Packit |
437b5e |
@int S_IWOTH other write
|
|
Packit |
437b5e |
@int S_IXOTH other execute
|
|
Packit |
437b5e |
@int S_ISGID set group id on execution
|
|
Packit |
437b5e |
@int S_ISUID set user id on execution
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
-- Print stat constants supported on this host.
|
|
Packit |
437b5e |
for name, value in pairs (require "posix.sys.stat") do
|
|
Packit |
437b5e |
if type (value) == "number" then
|
|
Packit |
437b5e |
print (name, value)
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
LUALIB_API int
|
|
Packit |
437b5e |
luaopen_posix_sys_stat(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
luaL_register(L, "posix.sys.stat", posix_sys_stat_fns);
|
|
Packit |
437b5e |
lua_pushliteral(L, "posix.sys.stat for " LUA_VERSION " / " PACKAGE_STRING);
|
|
Packit |
437b5e |
lua_setfield(L, -2, "version");
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IFMT );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IFBLK );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IFCHR );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IFDIR );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IFIFO );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IFLNK );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IFREG );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IFSOCK );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IRWXU );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IRUSR );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IWUSR );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IXUSR );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IRWXG );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IRGRP );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IWGRP );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IXGRP );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IRWXO );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IROTH );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IWOTH );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_IXOTH );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_ISGID );
|
|
Packit |
437b5e |
LPOSIX_CONST( S_ISUID );
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|