|
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 |
Standard Posix Library functions.
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
@module posix.stdlib
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <config.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <fcntl.h> /* for open(2) */
|
|
Packit |
437b5e |
#include <stdlib.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include "_helpers.c"
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Abort the program immediately.
|
|
Packit |
437b5e |
@function abort
|
|
Packit |
437b5e |
@see abort(3)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pabort(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 0);
|
|
Packit |
437b5e |
abort();
|
|
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 |
Get value of environment variable, or _all_ variables.
|
|
Packit |
437b5e |
@function getenv
|
|
Packit |
437b5e |
@see getenv(3)
|
|
Packit |
437b5e |
@string[opt] name if nil, get all
|
|
Packit |
437b5e |
@return value if name given, otherwise a name-indexed table of values.
|
|
Packit |
437b5e |
@usage for a,b in pairs(posix.getenv()) do print(a, b) end
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgetenv(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
if (lua_isnoneornil(L, 1))
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
extern char **environ;
|
|
Packit |
437b5e |
char **e;
|
|
Packit |
437b5e |
lua_newtable(L);
|
|
Packit |
437b5e |
for (e=environ; *e!=NULL; e++)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
char *s=*e;
|
|
Packit |
437b5e |
char *eq=strchr(s, '=');
|
|
Packit |
437b5e |
if (eq==NULL) /* will this ever happen? */
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushstring(L, s);
|
|
Packit |
437b5e |
lua_pushboolean(L, 1);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushlstring(L, s, eq-s);
|
|
Packit |
437b5e |
lua_pushstring(L, eq+1);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
lua_settable(L, -3);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
lua_pushstring(L, getenv(optstring(L, 1,
|
|
Packit |
437b5e |
"lua_isnoneornil prevents this happening")));
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Grant access to a slave pseudoterminal
|
|
Packit |
437b5e |
@function grantpt
|
|
Packit |
437b5e |
@int fd descriptor returned by openpt
|
|
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 grantpt(3)
|
|
Packit |
437b5e |
@see openpt
|
|
Packit |
437b5e |
@see ptsname
|
|
Packit |
437b5e |
@see unlockpt
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pgrantpt(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd=checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, grantpt(fd), "grantpt");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Create a unique temporary directory.
|
|
Packit |
437b5e |
@function mkdtemp
|
|
Packit |
437b5e |
@string templ pattern that ends in six 'X' characters
|
|
Packit |
437b5e |
@treturn[1] string path to directory, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see mkdtemp(3)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pmkdtemp(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
#if defined LPOSIX_2008_COMPLIANT
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
size_t path_len = strlen(path) + 1;
|
|
Packit |
437b5e |
void *ud;
|
|
Packit |
437b5e |
lua_Alloc lalloc;
|
|
Packit |
437b5e |
char *tmppath;
|
|
Packit |
437b5e |
char *r;
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
lalloc = lua_getallocf(L, &ud);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
if ((tmppath = lalloc(ud, NULL, 0, path_len)) == NULL)
|
|
Packit |
437b5e |
return pusherror(L, "lalloc");
|
|
Packit |
437b5e |
strcpy(tmppath, path);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
if ((r = mkdtemp(tmppath)))
|
|
Packit |
437b5e |
lua_pushstring(L, tmppath);
|
|
Packit |
437b5e |
lalloc(ud, tmppath, path_len, 0);
|
|
Packit |
437b5e |
return (r == NULL) ? pusherror(L, path) : 1;
|
|
Packit |
437b5e |
#else
|
|
Packit |
437b5e |
return binding_notimplemented(L, "mkdtemp", "C");
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Create a unique temporary file.
|
|
Packit |
437b5e |
@function mkstemp
|
|
Packit |
437b5e |
@string templ pattern that ends in six 'X' characters
|
|
Packit |
437b5e |
@treturn[1] int open file descriptor
|
|
Packit |
437b5e |
@treturn[2] string path to file, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see mkstemp(3)
|
|
Packit |
437b5e |
@usage P.mkstemp 'wooXXXXXX'
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pmkstemp(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *path = luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
size_t path_len = strlen(path) + 1;
|
|
Packit |
437b5e |
void *ud;
|
|
Packit |
437b5e |
lua_Alloc lalloc;
|
|
Packit |
437b5e |
char *tmppath;
|
|
Packit |
437b5e |
int r;
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
lalloc = lua_getallocf(L, &ud);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
if ((tmppath = lalloc(ud, NULL, 0, path_len)) == NULL)
|
|
Packit |
437b5e |
return pusherror(L, "lalloc");
|
|
Packit |
437b5e |
strcpy(tmppath, path);
|
|
Packit |
437b5e |
r = mkstemp(tmppath);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
if (r != -1)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushinteger(L, r);
|
|
Packit |
437b5e |
lua_pushstring(L, tmppath);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
lalloc(ud, tmppath, path_len, 0);
|
|
Packit |
437b5e |
return (r == -1) ? pusherror(L, path) : 2;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Open a pseudoterminal.
|
|
Packit |
437b5e |
@function openpt
|
|
Packit |
437b5e |
@int oflags bitwise OR of zero or more of `O_RDWR` and `O_NOCTTY`
|
|
Packit |
437b5e |
@return[1] file descriptor of pseudoterminal, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see posix_openpt(3)
|
|
Packit |
437b5e |
@see grantpt
|
|
Packit |
437b5e |
@see ptsname
|
|
Packit |
437b5e |
@see unlockpt
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Popenpt(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int flags = checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
/* The name of the pseudo-device is specified by POSIX */
|
|
Packit |
437b5e |
return pushresult(L, open("/dev/ptmx", flags), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Get the name of a slave pseudo-terminal
|
|
Packit |
437b5e |
@function ptsname
|
|
Packit |
437b5e |
@int fd descriptor returned by @{openpt}
|
|
Packit |
437b5e |
@return[1] path name of the slave terminal device, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error message
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see ptsname(3)
|
|
Packit |
437b5e |
@see grantpt
|
|
Packit |
437b5e |
@see unlockpt
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Pptsname(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd=checkint(L, 1);
|
|
Packit |
437b5e |
const char* slave;
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
slave = ptsname(fd);
|
|
Packit |
437b5e |
if (!slave)
|
|
Packit |
437b5e |
return pusherror(L, "getptsname");
|
|
Packit |
437b5e |
return pushstringresult(slave);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Find canonicalized absolute pathname.
|
|
Packit |
437b5e |
@function realpath
|
|
Packit |
437b5e |
@string path file to act on
|
|
Packit |
437b5e |
@treturn[1] string canonicalized absolute path, if successful
|
|
Packit |
437b5e |
@return[2] nil
|
|
Packit |
437b5e |
@treturn[2] string error messag
|
|
Packit |
437b5e |
@treturn[2] int errnum
|
|
Packit |
437b5e |
@see realpath(3)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Prealpath(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
char *s;
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
if ((s = realpath(luaL_checkstring(L, 1), NULL)) == NULL)
|
|
Packit |
437b5e |
return pusherror(L, "realpath");
|
|
Packit |
437b5e |
lua_pushstring(L, s);
|
|
Packit |
437b5e |
free(s);
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Set an environment variable for this process.
|
|
Packit |
437b5e |
(Child processes will inherit this)
|
|
Packit |
437b5e |
@function setenv
|
|
Packit |
437b5e |
@string name
|
|
Packit |
437b5e |
@string[opt] value (maybe nil, meaning 'unset')
|
|
Packit |
437b5e |
@param[opt] overwrite non-nil prevents overwriting a variable
|
|
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 setenv(3)
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Psetenv(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *name=luaL_checkstring(L, 1);
|
|
Packit |
437b5e |
const char *value=optstring(L, 2, NULL);
|
|
Packit |
437b5e |
checknargs(L, 3);
|
|
Packit |
437b5e |
if (value==NULL)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
unsetenv(name);
|
|
Packit |
437b5e |
return pushresult(L, 0, NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int overwrite=lua_isnoneornil(L, 3) || lua_toboolean(L, 3);
|
|
Packit |
437b5e |
return pushresult(L, setenv(name,value,overwrite), NULL);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/***
|
|
Packit |
437b5e |
Unlock a pseudoterminal master/slave pair
|
|
Packit |
437b5e |
@function unlockpt
|
|
Packit |
437b5e |
@int fd descriptor returned by openpt
|
|
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 unlockpt(3)
|
|
Packit |
437b5e |
@see openpt
|
|
Packit |
437b5e |
@see ptsname
|
|
Packit |
437b5e |
@see grantpt
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
Punlockpt(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int fd=checkint(L, 1);
|
|
Packit |
437b5e |
checknargs(L, 1);
|
|
Packit |
437b5e |
return pushresult(L, unlockpt(fd), "unlockpt");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static const luaL_Reg posix_stdlib_fns[] =
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pabort ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgetenv ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pgrantpt ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pmkdtemp ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pmkstemp ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Popenpt ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Pptsname ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Prealpath ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Psetenv ),
|
|
Packit |
437b5e |
LPOSIX_FUNC( Punlockpt ),
|
|
Packit |
437b5e |
{NULL, NULL}
|
|
Packit |
437b5e |
};
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
LUALIB_API int
|
|
Packit |
437b5e |
luaopen_posix_stdlib(lua_State *L)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
luaL_register(L, "posix.stdlib", posix_stdlib_fns);
|
|
Packit |
437b5e |
lua_pushliteral(L, "posix.stdlib for " LUA_VERSION " / " PACKAGE_STRING);
|
|
Packit |
437b5e |
lua_setfield(L, -2, "version");
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
return 1;
|
|
Packit |
437b5e |
}
|