Blame ext/posix/fcntl.c

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
*/