|
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 Control.
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
Low-level control over file descriptors, including creating new file
|
|
Packit |
437b5e |
descriptors with `open`.
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
@module posix.fcntl
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <config.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <fcntl.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include "_helpers.c"
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Darwin fails to define O_RSYNC. */
|
|
Packit |
437b5e |
#ifndef O_RSYNC
|
|
Packit |
437b5e |
#define O_RSYNC 0
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
/* FreeBSD 10 fails to define O_DSYNC. */
|
|
Packit |
437b5e |
#ifndef O_DSYNC
|
|
Packit |
437b5e |
#define O_DSYNC 0
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Manipulate file descriptor.
|
|
Packit |
437b5e |
@function fcntl
|
|
Packit |
437b5e |
@int fd file descriptor to act on
|
|
Packit |
437b5e |
@int cmd operation to perform
|
|
Packit |
437b5e |
@tparam[opt=0] int|flock arg when *cmd* is `F_GETLK`, `F_SETLK` or `F_SETLKW`,
|
|
Packit |
437b5e |
then *arg* is a @{flock} table, otherwise an integer with meaning dependent
|
|
Packit |
437b5e |
upon the value of *cmd*.
|
|
Packit |
437b5e |
@return[1] integer return value depending on *cmd*, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see fcntl(2)
|
|
Packit |
437b5e |
@see lock.lua
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
local flag = P.fcntl (fd, P.F_GETFL)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pfcntl(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
int cmd = checkint(L, 2);
|
|
Packit |
437b5e |
int arg;
|
|
Packit |
437b5e |
struct flock lockinfo;
|
|
Packit |
437b5e |
int r;
|
|
Packit |
437b5e |
checknargs(L, 3);
|
|
Packit |
437b5e |
switch (cmd)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
case F_SETLK:
|
|
Packit |
437b5e |
case F_SETLKW:
|
|
Packit |
437b5e |
case F_GETLK:
|
|
Packit |
437b5e |
luaL_checktype(L, 3, LUA_TTABLE);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Copy fields to flock struct */
|
|
Packit |
437b5e |
lua_getfield(L, 3, "l_type");
|
|
Packit |
437b5e |
lockinfo.l_type = (short)lua_tointeger(L, -1);
|
|
Packit |
437b5e |
lua_getfield(L, 3, "l_whence");
|
|
Packit |
437b5e |
lockinfo.l_whence = (short)lua_tointeger(L, -1);
|
|
Packit |
437b5e |
lua_getfield(L, 3, "l_start");
|
|
Packit |
437b5e |
lockinfo.l_start = (off_t)lua_tointeger(L, -1);
|
|
Packit |
437b5e |
lua_getfield(L, 3, "l_len");
|
|
Packit |
437b5e |
lockinfo.l_len = (off_t)lua_tointeger(L, -1);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Lock */
|
|
Packit |
437b5e |
r = fcntl(fd, cmd, &lockinfo);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Copy fields from flock struct */
|
|
Packit |
437b5e |
lua_pushinteger(L, lockinfo.l_type);
|
|
Packit |
437b5e |
lua_setfield(L, 3, "l_type");
|
|
Packit |
437b5e |
lua_pushinteger(L, lockinfo.l_whence);
|
|
Packit |
437b5e |
lua_setfield(L, 3, "l_whence");
|
|
Packit |
437b5e |
lua_pushinteger(L, lockinfo.l_start);
|
|
Packit |
437b5e |
lua_setfield(L, 3, "l_start");
|
|
Packit |
437b5e |
lua_pushinteger(L, lockinfo.l_len);
|
|
Packit |
437b5e |
lua_setfield(L, 3, "l_len");
|
|
Packit |
437b5e |
lua_pushinteger(L, lockinfo.l_pid);
|
|
Packit |
437b5e |
lua_setfield(L, 3, "l_pid");
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
break;
|
|
Packit |
437b5e |
default:
|
|
Packit |
437b5e |
arg = optint(L, 3, 0);
|
|
Packit |
437b5e |
r = fcntl(fd, cmd, arg);
|
|
Packit |
437b5e |
break;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
return pushresult(L, r, "fcntl");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Open a file.
|
|
Packit |
437b5e |
@function open
|
|
Packit |
437b5e |
@string path
|
|
Packit |
437b5e |
@int oflags bitwise OR of zero or more of `O_RDONLY`, `O_WRONLY`, `O_RDWR`,
|
|
Packit |
437b5e |
`O_APPEND`, `O_CREAT`, `O_DSYNC`, `O_EXCL`, `O_NOCTTY`, `O_NONBLOCK`,
|
|
Packit |
437b5e |
`O_RSYNC`, `O_SYNC`, `O_TRUNC`
|
|
Packit |
437b5e |
@int[opt=511] mode access modes used by `O_CREAT`
|
|
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 open(2)
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
fd = P.open ("data", bit.bor (P.O_CREAT, P.O_RDWR), bit.bor (P.S_IRWXU, P.S_IRGRP))
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Popen(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
int oflags = checkint(L, 2);
|
|
Packit |
437b5e |
checknargs(L, 3);
|
|
Packit |
437b5e |
return pushresult(L, open(path, oflags, (mode_t) optint(L, 3, 511)), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if HAVE_POSIX_FADVISE
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Instruct kernel on appropriate cache behaviour for a file or file segment.
|
|
Packit |
437b5e |
@function posix_fadvise
|
|
Packit |
437b5e |
@int fd open file descriptor
|
|
Packit |
437b5e |
@int offset start of region
|
|
Packit |
437b5e |
@int len number of bytes in region
|
|
Packit |
437b5e |
@int advice one of `POSIX_FADV_NORMAL`, `POSIX_FADV_SEQUENTIAL`,
|
|
Packit |
437b5e |
`POSIX_FADV_RANDOM`, `POSIX_FADV_NOREUSE`, `POSIX_FADV_WILLNEED` or
|
|
Packit |
437b5e |
`POSIX_FADV_DONTNEED`
|
|
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 posix_fadvise(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pposix_fadvise(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
int offset = checkint(L, 2);
|
|
Packit |
437b5e |
int len = checkint(L, 3);
|
|
Packit |
437b5e |
int advice = checkint(L, 4);
|
|
Packit |
437b5e |
int r;
|
|
Packit |
437b5e |
checknargs(L, 4);
|
|
Packit |
437b5e |
r = posix_fadvise(fd, offset, len, advice);
|
|
Packit |
437b5e |
return pushresult(L, r == 0 ? 0 : -1, "posix_fadvise");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static const luaL_Reg posix_fcntl_fns[] =
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pfcntl ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Popen ),
|
|
Packit |
437b5e |
#if HAVE_POSIX_FADVISE
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pposix_fadvise ),
|
|
Packit |
437b5e |
#endif
|
|
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 |
Fcntl constants.
|
|
Packit |
437b5e |
Any constants not available in the underlying system will be `nil` valued.
|
|
Packit |
437b5e |
@table posix.fcntl
|
|
Packit |
437b5e |
@int F_DUPFD duplicate file descriptor
|
|
Packit |
437b5e |
@int F_GETFD get file descriptor flags
|
|
Packit |
437b5e |
@int F_SETFD set file descriptor flags
|
|
Packit |
437b5e |
@int F_GETFL get file status flags
|
|
Packit |
437b5e |
@int F_SETFL set file status flags
|
|
Packit |
437b5e |
@int F_GETLK get record locking information
|
|
Packit |
437b5e |
@int F_SETLK set record locking information
|
|
Packit |
437b5e |
@int F_SETLKW set lock, and wait if blocked
|
|
Packit |
437b5e |
@int F_GETOWN get SIGIO/SIGURG process owner
|
|
Packit |
437b5e |
@int F_SETOWN set SIGIO/SIGURG process owner
|
|
Packit |
437b5e |
@int F_RDLCK shared or read lock
|
|
Packit |
437b5e |
@int F_WRLCK exclusive or write lock
|
|
Packit |
437b5e |
@int F_UNLCK unlock
|
|
Packit |
437b5e |
@int O_RDONLY open for reading only
|
|
Packit |
437b5e |
@int O_WRONLY open for writing only
|
|
Packit |
437b5e |
@int O_RDWR open for reading and writing
|
|
Packit |
437b5e |
@int O_APPEND set append mode
|
|
Packit |
437b5e |
@int O_CREAT create if nonexistent
|
|
Packit |
437b5e |
@int O_DSYNC synchronise io data integrity
|
|
Packit |
437b5e |
@int O_EXCL error if file already exists
|
|
Packit |
437b5e |
@int O_NOCTTY don't assign controlling terminal
|
|
Packit |
437b5e |
@int O_NONBLOCK no delay
|
|
Packit |
437b5e |
@int O_RSYNC synchronise file read integrity
|
|
Packit |
437b5e |
@int O_SYNC synchronise file write integrity
|
|
Packit |
437b5e |
@int O_TRUNC truncate to zero length
|
|
Packit |
437b5e |
@int POSIX_FADV_NORMAL no advice
|
|
Packit |
437b5e |
@int POSIX_FADV_SEQUENTIAL expecting to access data sequentially
|
|
Packit |
437b5e |
@int POSIX_FADV_RANDOM expecting to access data randomly
|
|
Packit |
437b5e |
@int POSIX_FADV_NOREUSE expecting to access data once only
|
|
Packit |
437b5e |
@int POSIX_FADV_WILLNEED expecting to access data in the near future
|
|
Packit |
437b5e |
@int POSIX_FADV_DONTNEED not expecting to access the data in the near future
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
-- Print fcntl constants supported on this host.
|
|
Packit |
437b5e |
for name, value in pairs (require "posix.fcntl") 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 |
LUALIB_API int
|
|
Packit |
437b5e |
luaopen_posix_fcntl(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
luaL_register(L, "posix.fcntl", posix_fcntl_fns);
|
|
Packit |
437b5e |
lua_pushliteral(L, "posix.fcntl for " LUA_VERSION " / " PACKAGE_STRING);
|
|
Packit |
437b5e |
lua_setfield(L, -2, "version");
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* fcntl flags */
|
|
Packit |
437b5e |
LPOSIX_CONST( F_DUPFD );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_GETFD );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_SETFD );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_GETFL );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_SETFL );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_GETLK );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_SETLK );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_SETLKW );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_GETOWN );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_SETOWN );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_RDLCK );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_WRLCK );
|
|
Packit |
437b5e |
LPOSIX_CONST( F_UNLCK );
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* file creation & status flags */
|
|
Packit |
437b5e |
LPOSIX_CONST( O_RDONLY );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_WRONLY );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_RDWR );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_APPEND );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_CREAT );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_DSYNC );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_EXCL );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_NOCTTY );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_NONBLOCK );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_RSYNC );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_SYNC );
|
|
Packit |
437b5e |
LPOSIX_CONST( O_TRUNC );
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* posix_fadvise flags */
|
|
Packit |
437b5e |
#ifdef POSIX_FADV_NORMAL
|
|
Packit |
437b5e |
LPOSIX_CONST( POSIX_FADV_NORMAL );
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
#ifdef POSIX_FADV_SEQUENTIAL
|
|
Packit |
437b5e |
LPOSIX_CONST( POSIX_FADV_SEQUENTIAL );
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
#ifdef POSIX_FADV_RANDOM
|
|
Packit |
437b5e |
LPOSIX_CONST( POSIX_FADV_RANDOM );
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
#ifdef POSIX_FADV_NOREUSE
|
|
Packit |
437b5e |
LPOSIX_CONST( POSIX_FADV_NOREUSE );
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
#ifdef POSIX_FADV_WILLNEED
|
|
Packit |
437b5e |
LPOSIX_CONST( POSIX_FADV_WILLNEED );
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
#ifdef POSIX_FADV_DONTNEED
|
|
Packit |
437b5e |
LPOSIX_CONST( POSIX_FADV_DONTNEED );
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Tables.
|
|
Packit |
437b5e |
@section tables
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Advisory file locks.
|
|
Packit |
437b5e |
Passed as *arg* to @{fcntl} when *cmd* is `F_GETLK`, `F_SETLK` or `F_SETLKW`.
|
|
Packit |
437b5e |
@table flock
|
|
Packit |
437b5e |
@int l_start starting offset
|
|
Packit |
437b5e |
@int l_len len = 0 means until end of file
|
|
Packit |
437b5e |
@int l_pid lock owner
|
|
Packit |
437b5e |
@int l_type lock type
|
|
Packit |
437b5e |
@int l_whence one of `SEEK_SET`, `SEEK_CUR` or `SEEK_END`
|
|
Packit |
437b5e |
*/
|