|
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 |
Unix Standard APIs.
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
Where the underlying system does not support one of these functions, it
|
|
Packit |
437b5e |
will have a `nil` value in the module table.
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
@module posix.unistd
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <config.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if HAVE_CRYPT_H
|
|
Packit |
437b5e |
# include <crypt.h>
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
#include <sys/stat.h>
|
|
Packit |
437b5e |
#include <sys/types.h>
|
|
Packit |
437b5e |
#include <unistd.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include "_helpers.c"
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static uid_t
|
|
Packit |
437b5e |
mygetuid(lua_State *L, int i)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (lua_isnoneornil(L, i))
|
|
Packit |
437b5e |
return (uid_t)-1;
|
|
Packit |
437b5e |
else if (lua_isinteger(L, i))
|
|
Packit |
437b5e |
return (uid_t) lua_tointeger(L, i);
|
|
Packit |
437b5e |
else if (lua_isstring(L, i))
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
struct passwd *p = getpwnam(lua_tostring(L, i));
|
|
Packit |
437b5e |
return (p == NULL) ? (uid_t) -1 : p->pw_uid;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
return argtypeerror(L, i, "string, int or nil");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static gid_t
|
|
Packit |
437b5e |
mygetgid(lua_State *L, int i)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (lua_isnoneornil(L, i))
|
|
Packit |
437b5e |
return (gid_t)-1;
|
|
Packit |
437b5e |
else if (lua_isinteger(L, i))
|
|
Packit |
437b5e |
return (gid_t) lua_tointeger(L, i);
|
|
Packit |
437b5e |
else if (lua_isstring(L, i))
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
struct group *g = getgrnam(lua_tostring(L, i));
|
|
Packit |
437b5e |
return (g == NULL) ? (uid_t) -1 : g->gr_gid;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
return argtypeerror(L, i, "string, int or nil");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Terminate the calling process.
|
|
Packit |
437b5e |
@function _exit
|
|
Packit |
437b5e |
@int status process exit status
|
|
Packit |
437b5e |
@see _exit(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
P_exit(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
pid_t ret = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
_exit(ret);
|
|
Packit |
437b5e |
return 0; /* Avoid a compiler warning (or possibly cause one
|
|
Packit |
437b5e |
if the compiler's too clever, sigh). */
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Check real user's permissions for a file.
|
|
Packit |
437b5e |
@function access
|
|
Packit |
437b5e |
@string path file to act on
|
|
Packit |
437b5e |
@string[opt="f"] mode can contain 'r','w','x' and 'f'
|
|
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 access(2)
|
|
Packit |
437b5e |
@usage status, errstr, errno = P.access("/etc/passwd", "rw")
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Paccess(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int mode=F_OK;
|
|
Packit |
437b5e |
const char *path=luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
const char *s;
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
for (s=optstring(L, 2, "f"); *s!=0 ; s++)
|
|
Packit |
437b5e |
switch (*s)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
case ' ': break;
|
|
Packit |
437b5e |
case 'r': mode |= R_OK; break;
|
|
Packit |
437b5e |
case 'w': mode |= W_OK; break;
|
|
Packit |
437b5e |
case 'x': mode |= X_OK; break;
|
|
Packit |
437b5e |
case 'f': mode |= F_OK; break;
|
|
Packit |
437b5e |
default: badoption(L, 2, "mode", *s); break;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
return pushresult(L, access(path, mode), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Set the working directory.
|
|
Packit |
437b5e |
@function chdir
|
|
Packit |
437b5e |
@string path file to act on
|
|
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 chdir(2)
|
|
Packit |
437b5e |
@usage status, errstr, errno = P.chdir("/var/tmp")
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pchdir(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, chdir(path), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Change ownership of a file.
|
|
Packit |
437b5e |
@function chown
|
|
Packit |
437b5e |
@string path existing file path
|
|
Packit |
437b5e |
@tparam string|int uid new owner user id
|
|
Packit |
437b5e |
@tparam string|int gid new owner group id
|
|
Packit |
437b5e |
@treturn[1] int `0`, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error messoge
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see chown(2)
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
-- will fail for a normal user, and print an error
|
|
Packit |
437b5e |
print(P.chown("/etc/passwd",100,200))
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pchown(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
uid_t uid = mygetuid(L, 2);
|
|
Packit |
437b5e |
gid_t gid = mygetgid(L, 3);
|
|
Packit |
437b5e |
checknargs(L, 3);
|
|
Packit |
437b5e |
return pushresult(L, chown(path, uid, gid), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Close an open file descriptor.
|
|
Packit |
437b5e |
@function close
|
|
Packit |
437b5e |
@int fd file descriptor to act on
|
|
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 close(2)
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
local ok, errmsg = P.close (log)
|
|
Packit |
437b5e |
if not ok then error (errmsg) end
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pclose(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, close(fd), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if defined HAVE_CRYPT
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Encrypt a password.
|
|
Packit |
437b5e |
Not recommended for general encryption purposes.
|
|
Packit |
437b5e |
@function crypt
|
|
Packit |
437b5e |
@string trypass string to hash
|
|
Packit |
437b5e |
@string salt two-character string from [a-zA-Z0-9./]
|
|
Packit |
437b5e |
@return encrypted string
|
|
Packit |
437b5e |
@see crypt(3)
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
local salt, hash = pwent:match ":$6$(.-)$([^:]+)"
|
|
Packit |
437b5e |
if P.crypt (trypass, salt) ~= hash then
|
|
Packit |
437b5e |
error "wrong password"
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pcrypt(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *str, *salt;
|
|
Packit |
437b5e |
char *r;
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
str = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
salt = luaL_checkstring(L, 2);
|
|
Packit |
437b5e |
if (strlen(salt) < 2)
|
|
Packit |
437b5e |
luaL_error(L, "not enough salt");
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
r = crypt(str, salt);
|
|
Packit |
437b5e |
return pushstringresult(r);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Duplicate an open file descriptor.
|
|
Packit |
437b5e |
@function dup
|
|
Packit |
437b5e |
@int fd file descriptor to act on
|
|
Packit |
437b5e |
@treturn[1] int new file descriptor duplicating *fd*, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see dup(2)
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
local outfd = P.dup (P.fileno (io.stdout))
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pdup(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, dup(fd), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Duplicate one open file descriptor to another.
|
|
Packit |
437b5e |
If *newfd* references an open file already, it is closed before being
|
|
Packit |
437b5e |
reallocated to *fd*.
|
|
Packit |
437b5e |
@function dup2
|
|
Packit |
437b5e |
@int fd an open file descriptor to act on
|
|
Packit |
437b5e |
@int newfd new descriptor to duplicate *fd*
|
|
Packit |
437b5e |
@treturn[1] int new file descriptor, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see dup2(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pdup2(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
int newfd = checkint(L, 2);
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
return pushresult(L, dup2(fd, newfd), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
runexec(lua_State *L, int use_shell)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
char **argv;
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
int i, n;
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
if (lua_type(L, 2) != LUA_TTABLE)
|
|
Packit |
437b5e |
argtypeerror(L, 2, "table");
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
n = lua_objlen(L, 2);
|
|
Packit |
437b5e |
argv = lua_newuserdata(L, (n + 2) * sizeof(char*));
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Set argv[0], defaulting to command */
|
|
Packit |
437b5e |
argv[0] = (char*) path;
|
|
Packit |
437b5e |
lua_pushinteger(L, 0);
|
|
Packit |
437b5e |
lua_gettable(L, 2);
|
|
Packit |
437b5e |
if (lua_type(L, -1) == LUA_TSTRING)
|
|
Packit |
437b5e |
argv[0] = (char*)lua_tostring(L, -1);
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
lua_pop(L, 1);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Read argv[1..n] from table. */
|
|
Packit |
437b5e |
for (i=1; i<=n; i++)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushinteger(L, i);
|
|
Packit |
437b5e |
lua_gettable(L, 2);
|
|
Packit |
437b5e |
argv[i] = (char*)lua_tostring(L, -1);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
argv[n+1] = NULL;
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
(use_shell ? execvp : execv) (path, argv);
|
|
Packit |
437b5e |
return pusherror(L, path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Execute a program without using the shell.
|
|
Packit |
437b5e |
@function exec
|
|
Packit |
437b5e |
@string path
|
|
Packit |
437b5e |
@tparam table argt arguments (table can include index 0)
|
|
Packit |
437b5e |
@return nil
|
|
Packit |
437b5e |
@treturn string error message
|
|
Packit |
437b5e |
@see execve(2)
|
|
Packit |
437b5e |
@usage exec ("/bin/bash", {[0] = "-sh", "--norc})
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pexec(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
return runexec(L, 0);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Execute a program using the shell.
|
|
Packit |
437b5e |
@function execp
|
|
Packit |
437b5e |
@string path
|
|
Packit |
437b5e |
@tparam table argt arguments (table can include index 0)
|
|
Packit |
437b5e |
@return nil
|
|
Packit |
437b5e |
@treturn string error message
|
|
Packit |
437b5e |
@see execve(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pexecp(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
return runexec(L, 1);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if LPOSIX_2001_COMPLIANT
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if !HAVE_DECL_FDATASYNC
|
|
Packit |
437b5e |
extern int fdatasync ();
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Synchronize a file's in-core state with storage device without metadata.
|
|
Packit |
437b5e |
@function fdatasync
|
|
Packit |
437b5e |
@int fd
|
|
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 fdatasync(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pfdatasync(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, fdatasync(fd), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Fork this program.
|
|
Packit |
437b5e |
@function fork
|
|
Packit |
437b5e |
@treturn[1] int `0` in the resulting child process
|
|
Packit |
437b5e |
@treturn[2] int process id of child, in the calling process
|
|
Packit |
437b5e |
@return[3] nil
|
|
Packit |
437b5e |
@treturn[3] string error message
|
|
Packit |
437b5e |
@treturn[3] int errnum
|
|
Packit |
437b5e |
@see fork(2)
|
|
Packit |
437b5e |
@see fork.lua
|
|
Packit |
437b5e |
@see fork2.lua
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
local pid, errmsg = P.fork ()
|
|
Packit |
437b5e |
if pid == nil then
|
|
Packit |
437b5e |
error (errmsg)
|
|
Packit |
437b5e |
elseif pid == 0 then
|
|
Packit |
437b5e |
print ("in child:", P.getpid "pid")
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
print (P.wait (pid))
|
|
Packit |
437b5e |
end
|
|
Packit |
437b5e |
os.exit ()
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pfork(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushresult(L, fork(), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Synchronize a file's in-core state with storage device.
|
|
Packit |
437b5e |
@function fsync
|
|
Packit |
437b5e |
@int fd
|
|
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 fsync(2)
|
|
Packit |
437b5e |
@see sync
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pfsync(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, fsync(fd), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Current working directory for this process.
|
|
Packit |
437b5e |
@function getcwd
|
|
Packit |
437b5e |
@treturn[1] string path of current working directory, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see getcwd(3)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetcwd(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
#ifdef __GNU__
|
|
Packit |
437b5e |
char *b = get_current_dir_name();
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
if (b == NULL)
|
|
Packit |
437b5e |
/* we return the same error as below */
|
|
Packit |
437b5e |
return pusherror(L, ".");
|
|
Packit |
437b5e |
return pushstringresult(b);
|
|
Packit |
437b5e |
#else
|
|
Packit |
437b5e |
long size = pathconf(".", _PC_PATH_MAX);
|
|
Packit |
437b5e |
void *ud;
|
|
Packit |
437b5e |
lua_Alloc lalloc;
|
|
Packit |
437b5e |
char *b, *r;
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
lalloc = lua_getallocf(L, &ud);
|
|
Packit |
437b5e |
if (size == -1)
|
|
Packit |
437b5e |
size = _POSIX_PATH_MAX; /* FIXME: Retry if this is not long enough */
|
|
Packit |
437b5e |
if ((b = lalloc(ud, NULL, 0, (size_t)size + 1)) == NULL)
|
|
Packit |
437b5e |
return pusherror(L, "lalloc");
|
|
Packit |
437b5e |
r = getcwd(b, (size_t)size);
|
|
Packit |
437b5e |
if (r != NULL)
|
|
Packit |
437b5e |
lua_pushstring(L, b);
|
|
Packit |
437b5e |
lalloc(ud, b, (size_t)size + 1, 0);
|
|
Packit |
437b5e |
return (r == NULL) ? pusherror(L, ".") : 1;
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Return effective group id of calling process.
|
|
Packit |
437b5e |
@function getegid
|
|
Packit |
437b5e |
@treturn int effective group id of calling process
|
|
Packit |
437b5e |
@see getgid
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetegid(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushintresult(getegid ());
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Return effective user id of calling process.
|
|
Packit |
437b5e |
@function geteuid
|
|
Packit |
437b5e |
@treturn int effective user id of calling process
|
|
Packit |
437b5e |
@see getuid
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgeteuid(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushintresult(geteuid ());
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Return group id of calling process.
|
|
Packit |
437b5e |
@function getgid
|
|
Packit |
437b5e |
@treturn int group id of calling process
|
|
Packit |
437b5e |
@see getegid
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetgid(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushintresult(getgid ());
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if LPOSIX_2001_COMPLIANT
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Get list of supplementary group ids.
|
|
Packit |
437b5e |
@function getgroups
|
|
Packit |
437b5e |
@see getgroups(2)
|
|
Packit |
437b5e |
@treturn table group id
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetgroups(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int n_group_slots = getgroups(0, NULL);
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
if (n_group_slots < 0)
|
|
Packit |
437b5e |
return pusherror(L, NULL);
|
|
Packit |
437b5e |
else if (n_group_slots == 0)
|
|
Packit |
437b5e |
lua_newtable(L);
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
gid_t *group;
|
|
Packit |
437b5e |
int n_groups;
|
|
Packit |
437b5e |
int i;
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
group = lua_newuserdata(L, sizeof(*group) * n_group_slots);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
n_groups = getgroups(n_group_slots, group);
|
|
Packit |
437b5e |
if (n_groups < 0)
|
|
Packit |
437b5e |
return pusherror(L, NULL);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
lua_createtable(L, n_groups, 0);
|
|
Packit |
437b5e |
for (i = 0; i < n_groups; i++)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushinteger(L, group[i]);
|
|
Packit |
437b5e |
lua_rawseti(L, -2, i + 1);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Current logged-in user.
|
|
Packit |
437b5e |
@treturn[1] string username, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@see getlogin(3)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetlogin(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushstringresult(getlogin());
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Return process group id of calling process.
|
|
Packit |
437b5e |
@function getpgrp
|
|
Packit |
437b5e |
@treturn int process group id of calling process
|
|
Packit |
437b5e |
@see getpid
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetpgrp(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushintresult(getpgrp ());
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Return process id of calling process.
|
|
Packit |
437b5e |
@function getpid
|
|
Packit |
437b5e |
@treturn int process id of calling process
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetpid(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushintresult(getpid ());
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Return parent process id of calling process.
|
|
Packit |
437b5e |
@function getppid
|
|
Packit |
437b5e |
@treturn int parent process id of calling process
|
|
Packit |
437b5e |
@see getpid
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetppid(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushintresult(getppid ());
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Return user id of calling process.
|
|
Packit |
437b5e |
@function getuid
|
|
Packit |
437b5e |
@treturn int user id of calling process
|
|
Packit |
437b5e |
@see geteuid
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetuid(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
return pushintresult(getuid ());
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Get host id.
|
|
Packit |
437b5e |
@function gethostid
|
|
Packit |
437b5e |
@see gethostid(3)
|
|
Packit |
437b5e |
@treturn[1] int host id
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgethostid(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
#if HAVE_GETHOSTID
|
|
Packit |
437b5e |
return pushintresult(gethostid());
|
|
Packit |
437b5e |
#else
|
|
Packit |
437b5e |
lua_pushnil(L);
|
|
Packit |
437b5e |
lua_pushliteral(L, "unsupported by this host");
|
|
Packit |
437b5e |
return 2;
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Test whether a file descriptor refers to a terminal.
|
|
Packit |
437b5e |
@function isatty
|
|
Packit |
437b5e |
@int fd file descriptor to act on
|
|
Packit |
437b5e |
@treturn[1] int `1` if *fd* is open and refers to a terminal, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see isatty(3)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pisatty(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, isatty(fd) == 0 ? -1 : 1, "isatty");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Create a link.
|
|
Packit |
437b5e |
@function link
|
|
Packit |
437b5e |
@string target name
|
|
Packit |
437b5e |
@string link name
|
|
Packit |
437b5e |
@bool[opt=false] soft link
|
|
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 link(2)
|
|
Packit |
437b5e |
@see symlink(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Plink(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *oldpath = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
const char *newpath = luaL_checkstring(L, 2);
|
|
Packit |
437b5e |
int symbolicp = optboolean(L, 3, 0);
|
|
Packit |
437b5e |
checknargs(L, 3);
|
|
Packit |
437b5e |
return pushresult(L, (symbolicp ? symlink : link)(oldpath, newpath), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
reposition read/write file offset
|
|
Packit |
437b5e |
@function lseek
|
|
Packit |
437b5e |
@see lseek(2)
|
|
Packit |
437b5e |
@int fd open file descriptor to act on
|
|
Packit |
437b5e |
@int offset bytes to seek
|
|
Packit |
437b5e |
@int whence one of `SEEK_SET`, `SEEK_CUR` or `SEEK_END`
|
|
Packit |
437b5e |
@treturn[1] int new offset, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Plseek(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
int offset = checkint(L, 2);
|
|
Packit |
437b5e |
int whence = checkint(L, 3);
|
|
Packit |
437b5e |
checknargs(L, 3);
|
|
Packit |
437b5e |
return pushresult(L, lseek(fd, offset, whence), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
change process priority
|
|
Packit |
437b5e |
@function nice
|
|
Packit |
437b5e |
@int inc adds inc to the nice value for the calling process
|
|
Packit |
437b5e |
@treturn[1] int new nice value, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@return[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see nice(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pnice(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int inc = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, nice(inc), "nice");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Get a value for a configuration option for a filename.
|
|
Packit |
437b5e |
@function pathconf
|
|
Packit |
437b5e |
@string path optional
|
|
Packit |
437b5e |
@int key one of `_PC_LINK_MAX`, `_PC_MAX_CANON`, `_PC_NAME_MAX`,
|
|
Packit |
437b5e |
`_PC_PIPE_BUF`, `_PC_CHOWN_RESTRICTED`, `_PC_NO_TRUNC` or
|
|
Packit |
437b5e |
`_PC_VDISABLE`
|
|
Packit |
437b5e |
@treturn int associated path configuration value
|
|
Packit |
437b5e |
@see pathconf(3)
|
|
Packit |
437b5e |
@usage for a, b in pairs (P.pathconf "/dev/tty") do print(a, b) end
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Ppathconf(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
return pushintresult(pathconf(path, checkint(L, 2)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Creates a pipe.
|
|
Packit |
437b5e |
@function pipe
|
|
Packit |
437b5e |
@treturn[1] int read end file descriptor
|
|
Packit |
437b5e |
@treturn[1] int write end file descriptor
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see pipe(2)
|
|
Packit |
437b5e |
@see fork.lua
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Ppipe(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int pipefd[2];
|
|
Packit |
437b5e |
int rc;
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
rc = pipe(pipefd);
|
|
Packit |
437b5e |
if (rc < 0)
|
|
Packit |
437b5e |
return pusherror(L, "pipe");
|
|
Packit |
437b5e |
lua_pushinteger(L, pipefd[0]);
|
|
Packit |
437b5e |
lua_pushinteger(L, pipefd[1]);
|
|
Packit |
437b5e |
return 2;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Read bytes from a file.
|
|
Packit |
437b5e |
@function read
|
|
Packit |
437b5e |
@int fd the file descriptor to act on
|
|
Packit |
437b5e |
@int count maximum number of bytes to read
|
|
Packit |
437b5e |
@treturn[1] string string from *fd* with at most *count* bytes, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see read(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pread(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
int count = checkint(L, 2), ret;
|
|
Packit |
437b5e |
void *ud, *buf;
|
|
Packit |
437b5e |
lua_Alloc lalloc;
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
lalloc = lua_getallocf(L, &ud);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Reset errno in case lalloc doesn't set it */
|
|
Packit |
437b5e |
errno = 0;
|
|
Packit |
437b5e |
if ((buf = lalloc(ud, NULL, 0, count)) == NULL && count > 0)
|
|
Packit |
437b5e |
return pusherror(L, "lalloc");
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
ret = read(fd, buf, count);
|
|
Packit |
437b5e |
if (ret >= 0)
|
|
Packit |
437b5e |
lua_pushlstring(L, buf, ret);
|
|
Packit |
437b5e |
lalloc(ud, buf, count, 0);
|
|
Packit |
437b5e |
return (ret < 0) ? pusherror(L, NULL) : 1;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Read value of a symbolic link.
|
|
Packit |
437b5e |
@function readlink
|
|
Packit |
437b5e |
@string path file to act on
|
|
Packit |
437b5e |
@treturn[1] string link target, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see readlink(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Preadlink(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
char *b;
|
|
Packit |
437b5e |
struct stat s;
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
void *ud;
|
|
Packit |
437b5e |
lua_Alloc lalloc;
|
|
Packit |
437b5e |
ssize_t n;
|
|
Packit |
437b5e |
int err;
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
lalloc = lua_getallocf(L, &ud);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
errno = 0; /* ignore outstanding unreported errors */
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* s.st_size is length of linkname, with no trailing \0 */
|
|
Packit |
437b5e |
if (lstat(path, &s) < 0)
|
|
Packit |
437b5e |
return pusherror(L, path);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* diagnose non-symlinks */
|
|
Packit |
437b5e |
if (!S_ISLNK(s.st_mode))
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushnil(L);
|
|
Packit |
437b5e |
lua_pushfstring(L, "%s: not a symbolic link", path);
|
|
Packit |
437b5e |
lua_pushinteger(L, EINVAL);
|
|
Packit |
437b5e |
return 3;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* allocate a buffer for linkname, with no trailing \0 */
|
|
Packit |
437b5e |
if ((b = lalloc(ud, NULL, 0, s.st_size)) == NULL)
|
|
Packit |
437b5e |
return pusherror(L, "lalloc");
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
n = readlink(path, b, s.st_size);
|
|
Packit |
437b5e |
err = errno; /* save readlink error code, if any */
|
|
Packit |
437b5e |
if (n != -1)
|
|
Packit |
437b5e |
lua_pushlstring(L, b, s.st_size);
|
|
Packit |
437b5e |
lalloc(ud, b, s.st_size, 0);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* report new errors from this function */
|
|
Packit |
437b5e |
if (n < 0)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
errno = err; /* restore readlink error code */
|
|
Packit |
437b5e |
return pusherror(L, "readlink");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
else if (n < s.st_size)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushnil(L);
|
|
Packit |
437b5e |
lua_pushfstring(L, "%s: readlink wrote only %d of %d bytes", path, n, s.st_size);
|
|
Packit |
437b5e |
return 2;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Remove a directory.
|
|
Packit |
437b5e |
@function rmdir
|
|
Packit |
437b5e |
@string path file to act on
|
|
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 rmdir(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Prmdir(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, rmdir(path), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Set the uid, euid, gid, egid, sid or pid & gid.
|
|
Packit |
437b5e |
@function setpid
|
|
Packit |
437b5e |
@string what one of 'u', 'U', 'g', 'G', 's', 'p' (upper-case means "effective")
|
|
Packit |
437b5e |
@int id (uid, gid or pid for every value of `what` except 's')
|
|
Packit |
437b5e |
@int[opt] gid (only for `what` value 'p')
|
|
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 setuid(2)
|
|
Packit |
437b5e |
@see seteuid(2)
|
|
Packit |
437b5e |
@see setgid(2)
|
|
Packit |
437b5e |
@see setegid(2)
|
|
Packit |
437b5e |
@see setsid(2)
|
|
Packit |
437b5e |
@see setpgid(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Psetpid(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *what=luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, *what == 'p' ? 3 : 2);
|
|
Packit |
437b5e |
switch (*what)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
case 'U':
|
|
Packit |
437b5e |
return pushresult(L, seteuid(mygetuid(L, 2)), NULL);
|
|
Packit |
437b5e |
case 'u':
|
|
Packit |
437b5e |
return pushresult(L, setuid(mygetuid(L, 2)), NULL);
|
|
Packit |
437b5e |
case 'G':
|
|
Packit |
437b5e |
return pushresult(L, setegid(mygetgid(L, 2)), NULL);
|
|
Packit |
437b5e |
case 'g':
|
|
Packit |
437b5e |
return pushresult(L, setgid(mygetgid(L, 2)), NULL);
|
|
Packit |
437b5e |
case 's':
|
|
Packit |
437b5e |
return pushresult(L, setsid(), NULL);
|
|
Packit |
437b5e |
case 'p':
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
pid_t pid = checkint(L, 2);
|
|
Packit |
437b5e |
pid_t pgid = checkint(L, 3);
|
|
Packit |
437b5e |
return pushresult(L, setpgid(pid,pgid), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
default:
|
|
Packit |
437b5e |
badoption(L, 1, "id", *what);
|
|
Packit |
437b5e |
return 0;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Sleep for a number of seconds.
|
|
Packit |
437b5e |
@function sleep
|
|
Packit |
437b5e |
@int seconds minimum numebr of seconds to sleep
|
|
Packit |
437b5e |
@treturn[1] int `0` if the requested time has elapsed
|
|
Packit |
437b5e |
@treturn[2] int unslept seconds remaining, if interrupted
|
|
Packit |
437b5e |
@see sleep(3)
|
|
Packit |
437b5e |
@see posix.time.nanosleep
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Psleep(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
unsigned int seconds = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(sleep(seconds));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Commit buffer cache to disk.
|
|
Packit |
437b5e |
@function sync
|
|
Packit |
437b5e |
@see fsync
|
|
Packit |
437b5e |
@see sync(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Psync(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
sync();
|
|
Packit |
437b5e |
return 0;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Get configuration information at runtime.
|
|
Packit |
437b5e |
@function sysconf
|
|
Packit |
437b5e |
@int key one of `_SC_ARG_MAX`, `_SC_CHILD_MAX`, `_SC_CLK_TCK`, `_SC_JOB_CONTROL`,
|
|
Packit |
437b5e |
`_SC_OPEN_MAX`, `_SC_NGROUPS_MAX`, `_SC_SAVED_IDS`, `_SC_STREAM_MAX`,
|
|
Packit |
437b5e |
`_SC_TZNAME_MAX` or `_SC_VERSION`,
|
|
Packit |
437b5e |
@treturn int associated system configuration value
|
|
Packit |
437b5e |
@see sysconf(3)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Psysconf(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushintresult(sysconf(checkint(L, 1)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Name of a terminal device.
|
|
Packit |
437b5e |
@function ttyname
|
|
Packit |
437b5e |
@see ttyname(3)
|
|
Packit |
437b5e |
@int[opt=0] fd file descriptor to process
|
|
Packit |
437b5e |
@return string name
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pttyname(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd=optint(L, 1, 0);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushstringresult(ttyname(fd));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Unlink a file.
|
|
Packit |
437b5e |
@function unlink
|
|
Packit |
437b5e |
@string 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 unlink(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Punlink(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, unlink(path), path);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Write bytes to a file.
|
|
Packit |
437b5e |
@function write
|
|
Packit |
437b5e |
@int fd the file descriptor to act on
|
|
Packit |
437b5e |
@string buf containing bytes to write
|
|
Packit |
437b5e |
@treturn[1] int number of bytes written, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see write(2)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pwrite(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd = checkint(L, 1);
|
|
Packit |
437b5e |
const char *buf = luaL_checkstring(L, 2);
|
|
Packit |
437b5e |
checknargs(L, 2);
|
|
Packit |
437b5e |
return pushresult(L, write(fd, buf, lua_objlen(L, 2)), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static const luaL_Reg posix_unistd_fns[] =
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
LPOSIX_FUNC( P_exit ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Paccess ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pchdir ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pchown ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pclose ),
|
|
Packit |
437b5e |
#if defined HAVE_CRYPT
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pcrypt ),
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pdup ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pdup2 ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pexec ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pexecp ),
|
|
Packit |
437b5e |
#if LPOSIX_2001_COMPLIANT
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pfdatasync ),
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pfork ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pfsync ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetcwd ),
|
|
Packit |
437b5e |
#if LPOSIX_2001_COMPLIANT
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetgroups ),
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetegid ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgeteuid ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetgid ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetlogin ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetpgrp ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetpid ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetppid ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetuid ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgethostid ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pisatty ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Plink ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Plseek ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pnice ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Ppathconf ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Ppipe ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pread ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Preadlink ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Prmdir ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Psetpid ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Psleep ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Psync ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Psysconf ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pttyname ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Punlink ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pwrite ),
|
|
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 |
Standard constants.
|
|
Packit |
437b5e |
Any constants not available in the underlying system will be `nil` valued.
|
|
Packit |
437b5e |
@table posix.unistd
|
|
Packit |
437b5e |
@int _PC_CHOWN_RESTRICTED return 1 if chown requires appropriate privileges, 0 otherwise
|
|
Packit |
437b5e |
@int _PC_LINK_MAX maximum file link count
|
|
Packit |
437b5e |
@int _PC_MAX_CANON maximum bytes in terminal canonical input line
|
|
Packit |
437b5e |
@int _PC_MAX_INPUT maximum number of bytes in a terminal input queue
|
|
Packit |
437b5e |
@int _PC_NAME_MAX maximum number of bytes in a file name
|
|
Packit |
437b5e |
@int _PC_NO_TRUNC return 1 if over-long file names are truncated
|
|
Packit |
437b5e |
@int _PC_PATH_MAXmaximum number of bytes in a pathname
|
|
Packit |
437b5e |
@int _PC_PIPE_BUF maximum number of bytes in an atomic pipe write
|
|
Packit |
437b5e |
@int _PC_VDISABLE terminal character disabling value
|
|
Packit |
437b5e |
@int _SC_ARG_MAX maximum bytes of argument to @{posix.unistd.execp}
|
|
Packit |
437b5e |
@int _SC_CHILD_MAX maximum number of processes per user
|
|
Packit |
437b5e |
@int _SC_CLK_TCK statistics clock frequency
|
|
Packit |
437b5e |
@int _SC_JOB_CONTROL return 1 if system has job control, -1 otherwise
|
|
Packit |
437b5e |
@int _SC_NGROUPS_MAX maximum number of supplemental groups
|
|
Packit |
437b5e |
@int _SC_OPEN_MAX maximum number of open files per user
|
|
Packit |
437b5e |
@int _SC_SAVED_IDS return 1 if system supports saved user and group ids, -1 otherwise
|
|
Packit |
437b5e |
@int _SC_STREAM_MAX maximum number of streams per process
|
|
Packit |
437b5e |
@int _SC_TZNAME_MAX maximum number of timezone types
|
|
Packit |
437b5e |
@int _SC_VERSION POSIX.1 compliance version
|
|
Packit |
437b5e |
@int SEEK_CUR relative file pointer position
|
|
Packit |
437b5e |
@int SEEK_END set file pointer to the end of file
|
|
Packit |
437b5e |
@int SEEK_SET absolute file pointer position
|
|
Packit |
437b5e |
@int STDERR_FILENO standard error file descriptor
|
|
Packit |
437b5e |
@int STDIN_FILENO standard input file descriptor
|
|
Packit |
437b5e |
@int STDOUT_FILENO standard output file descriptor
|
|
Packit |
437b5e |
@usage
|
|
Packit |
437b5e |
-- Print unistd constants supported on this host.
|
|
Packit |
437b5e |
for name, value in pairs (require "posix.unistd") 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_unistd(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
luaL_register(L, "posix.unistd", posix_unistd_fns);
|
|
Packit |
437b5e |
lua_pushliteral(L, "posix.unistd for " LUA_VERSION " / " PACKAGE_STRING);
|
|
Packit |
437b5e |
lua_setfield(L, -2, "version");
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* pathconf arguments */
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_CHOWN_RESTRICTED );
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_LINK_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_MAX_CANON );
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_MAX_INPUT );
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_NAME_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_NO_TRUNC );
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_PATH_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_PIPE_BUF );
|
|
Packit |
437b5e |
LPOSIX_CONST( _PC_VDISABLE );
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* sysconf arguments */
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_ARG_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_CHILD_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_CLK_TCK );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_JOB_CONTROL );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_OPEN_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_NGROUPS_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_SAVED_IDS );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_STREAM_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_TZNAME_MAX );
|
|
Packit |
437b5e |
LPOSIX_CONST( _SC_VERSION );
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* lseek arguments */
|
|
Packit |
437b5e |
LPOSIX_CONST( SEEK_CUR );
|
|
Packit |
437b5e |
LPOSIX_CONST( SEEK_END );
|
|
Packit |
437b5e |
LPOSIX_CONST( SEEK_SET );
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Miscellaneous */
|
|
Packit |
437b5e |
LPOSIX_CONST( STDERR_FILENO );
|
|
Packit |
437b5e |
LPOSIX_CONST( STDIN_FILENO );
|
|
Packit |
437b5e |
LPOSIX_CONST( STDOUT_FILENO );
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|