/*** Send message to a message queue @function msgsnd @int id message queue identifier returned by @{msgget} @int type arbitrary message type @string message content @int[opt=0] flags optionally `IPC_NOWAIT` @treturn int 0, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see msgsnd(2) */ static int Pmsgsnd(lua_State *L) { void *ud; lua_Alloc lalloc = lua_getallocf(L, &ud); struct { long mtype; char mtext[0]; } *msg; size_t len; size_t msgsz; ssize_t r; int msgid = checkint(L, 1); long msgtype = checklong(L, 2); const char *msgp = luaL_checklstring(L, 3, &len); int msgflg = optint(L, 4, 0); checknargs(L, 4); msgsz = sizeof(long) + len; if ((msg = lalloc(ud, NULL, 0, msgsz)) == NULL) return pusherror(L, "lalloc"); msg->mtype = msgtype; memcpy(msg->mtext, msgp, len); r = msgsnd(msgid, msg, msgsz, msgflg); lua_pushinteger(L, r); lalloc(ud, msg, msgsz, 0); return (r == -1 ? pusherror(L, NULL) : 1); }
/*** change process priority @function nice @int inc adds inc to the nice value for the calling process @treturn[1] int new nice value, if successful @return[2] nil @return[2] string error message @treturn[2] int errnum @see nice(2) */ static int Pnice(lua_State *L) { int inc = checkint(L, 1); checknargs(L, 1); return pushresult(L, nice(inc), "nice"); }
/*** Get a value for a configuration option for a filename. @function pathconf @string path optional @int key one of `_PC_LINK_MAX`, `_PC_MAX_CANON`, `_PC_NAME_MAX`, `_PC_PIPE_BUF`, `_PC_CHOWN_RESTRICTED`, `_PC_NO_TRUNC` or `_PC_VDISABLE` @treturn int associated path configuration value @see pathconf(3) @usage local unistd = require "posix.unistd" for a, b in pairs (unistd.pathconf "/dev/tty") do print(a, b) end */ static int Ppathconf(lua_State *L) { const char *path = luaL_checkstring(L, 1); checknargs(L, 2); return pushintresult(pathconf(path, checkint(L, 2))); }
/*** Parse command-line options. @function getopt @param arg command line arguments @string opts short option specifier @int[opt=0] opterr index of the option with an error @int[opt=1] optind index of the next unprocessed option @treturn option iterator, returning 3 values @see getopt(3) @see getopt.lua @usage local getopt = require "posix.getopt".getopt for opt, opterr, i in getopt (arg, "ho:v", opterr, i) do process (arg, opterr, i) end */ static int Pgetopt(lua_State *L) { int argc, i; const char *optstring; char **argv; checknargs(L, 4); checktype(L, 1, LUA_TTABLE, "list"); optstring = luaL_checkstring(L, 2); opterr = optint(L, 3, 0); optind = optint(L, 4, 1); argc = (int)lua_objlen(L, 1) + 1; lua_pushinteger(L, argc); lua_pushstring(L, optstring); argv = lua_newuserdata(L, (argc + 1) * sizeof(char *)); argv[argc] = NULL; for (i = 0; i < argc; i++) { lua_pushinteger(L, i); lua_gettable(L, 1); argv[i] = (char *)luaL_checkstring(L, -1); } /* Push remaining upvalues, and make and push closure. */ lua_pushcclosure(L, iter_getopt, 3 + argc); return 1; }
/*** Test whether a file descriptor refers to a terminal. @function isatty @int fd file descriptor to act on @treturn[1] int `1` if *fd* is open and refers to a terminal, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see isatty(3) */ static int Pisatty(lua_State *L) { int fd = checkint(L, 1); checknargs(L, 1); return pushresult(L, isatty(fd) == 0 ? -1 : 1, "isatty"); }
/*** Synchronize a file's in-core state with storage device. @function fsync @int fd @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see fsync(2) @see sync */ static int Pfsync(lua_State *L) { int fd = checkint(L, 1); checknargs(L, 1); return pushresult(L, fsync(fd), NULL); }
/*** Get list of supplementary group ids. @function getgroups @see getgroups(2) @treturn table group id */ static int Pgetgroups(lua_State *L) { int n_group_slots = getgroups(0, NULL); checknargs(L, 0); if (n_group_slots < 0) return pusherror(L, NULL); else if (n_group_slots == 0) lua_newtable(L); else { gid_t *group; int n_groups; int i; group = lua_newuserdata(L, sizeof(*group) * n_group_slots); n_groups = getgroups(n_group_slots, group); if (n_groups < 0) return pusherror(L, NULL); lua_createtable(L, n_groups, 0); for (i = 0; i < n_groups; i++) { lua_pushinteger(L, group[i]); lua_rawseti(L, -2, i + 1); } } return 1; }
/*** Close an open file descriptor. @function close @int fd file descriptor to act on @treturn[1] int `0` if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see close(2) @usage local unistd = require "posix.unistd" local ok, errmsg = unistd.close (log) if not ok then error (errmsg) end */ static int Pclose(lua_State *L) { int fd = checkint(L, 1); checknargs(L, 1); return pushresult(L, close(fd), NULL); }
static int runexec(lua_State *L, int use_shell) { char **argv; const char *path = luaL_checkstring(L, 1); int i, n; checknargs(L, 2); if (lua_type(L, 2) != LUA_TTABLE) argtypeerror(L, 2, "table"); n = lua_objlen(L, 2); argv = lua_newuserdata(L, (n + 2) * sizeof(char*)); /* Set argv[0], defaulting to command */ argv[0] = (char*) path; lua_pushinteger(L, 0); lua_gettable(L, 2); if (lua_type(L, -1) == LUA_TSTRING) argv[0] = (char*)lua_tostring(L, -1); else lua_pop(L, 1); /* Read argv[1..n] from table. */ for (i=1; i<=n; i++) { lua_pushinteger(L, i); lua_gettable(L, 2); argv[i] = (char*)lua_tostring(L, -1); } argv[n+1] = NULL; (use_shell ? execvp : execv) (path, argv); return pusherror(L, path); }
/*** Name of a terminal device. @function ttyname @see ttyname(3) @int[opt=0] fd file descriptor to process @return string name */ static int Pttyname(lua_State *L) { int fd=optint(L, 1, 0); checknargs(L, 1); return pushstringresult(ttyname(fd)); }
/*** Schedule an alarm signal. @function alarm @int seconds number of seconds to send SIGALRM in @return int number of seconds remaining in previous alarm or `0` @see alarm(2) @usage local unistd = require "posix.unistd" seconds = unistd.alarm(10) */ static int Palarm(lua_State *L) { int seconds = checkint(L, 1); checknargs(L, 1); return pushintresult(alarm(seconds)); }
/*** Commit buffer cache to disk. @function sync @see fsync @see sync(2) */ static int Psync(lua_State *L) { checknargs(L, 0); sync(); return 0; }
/*** Sleep for a number of seconds. @function sleep @int seconds minimum numebr of seconds to sleep @treturn[1] int `0` if the requested time has elapsed @treturn[2] int unslept seconds remaining, if interrupted @see sleep(3) @see posix.time.nanosleep */ static int Psleep(lua_State *L) { unsigned int seconds = checkint(L, 1); checknargs(L, 1); return pushintresult(sleep(seconds)); }
/*** Set the uid, euid, gid, egid, sid or pid & gid. @function setpid @string what one of 'u', 'U', 'g', 'G', 's', 'p' (upper-case means "effective") @int id (uid, gid or pid for every value of `what` except 's') @int[opt] gid (only for `what` value 'p') @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see setuid(2) @see seteuid(2) @see setgid(2) @see setegid(2) @see setsid(2) @see setpgid(2) */ static int Psetpid(lua_State *L) { const char *what=luaL_checkstring(L, 1); checknargs(L, *what == 'p' ? 3 : 2); switch (*what) { case 'U': return pushresult(L, seteuid(mygetuid(L, 2)), NULL); case 'u': return pushresult(L, setuid(mygetuid(L, 2)), NULL); case 'G': return pushresult(L, setegid(mygetgid(L, 2)), NULL); case 'g': return pushresult(L, setgid(mygetgid(L, 2)), NULL); case 's': return pushresult(L, setsid(), NULL); case 'p': { pid_t pid = checkint(L, 2); pid_t pgid = checkint(L, 3); return pushresult(L, setpgid(pid,pgid), NULL); } default: badoption(L, 1, "id", *what); return 0; } }
/*** Create a unique temporary directory. @function mkdtemp @string templ pattern that ends in six 'X' characters @treturn[1] string path to directory, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see mkdtemp(3) */ static int Pmkdtemp(lua_State *L) { #if defined LPOSIX_2008_COMPLIANT const char *path = luaL_checkstring(L, 1); size_t path_len = strlen(path) + 1; void *ud; lua_Alloc lalloc; char *tmppath; char *r; checknargs(L, 1); lalloc = lua_getallocf(L, &ud); if ((tmppath = lalloc(ud, NULL, 0, path_len)) == NULL) return pusherror(L, "lalloc"); strcpy(tmppath, path); if ((r = mkdtemp(tmppath))) lua_pushstring(L, tmppath); lalloc(ud, tmppath, path_len, 0); return (r == NULL) ? pusherror(L, path) : 1; #else return binding_notimplemented(L, "mkdtemp", "C"); #endif }
/*** Remove a directory. @function rmdir @string path file to act on @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see rmdir(2) */ static int Prmdir(lua_State *L) { const char *path = luaL_checkstring(L, 1); checknargs(L, 1); return pushresult(L, rmdir(path), path); }
/*** Receive message from a message queue @function msgrcv @int id message queue identifier returned by @{msgget} @int size maximum message size @int type message type (optional, default - 0) @int[opt=0] flags bitwise OR of zero or more of `IPC_NOWAIT`, `MSG_EXCEPT` and `MSG_NOERROR` @treturn[1] int message type from @{msgsnd} @treturn[1] string message text, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see msgrcv(2) */ static int Pmsgrcv(lua_State *L) { int msgid = checkint(L, 1); size_t msgsz = checkint(L, 2); long msgtyp = optint(L, 3, 0); int msgflg = optint(L, 4, 0); void *ud; lua_Alloc lalloc; struct { long mtype; char mtext[0]; } *msg; checknargs(L, 4); lalloc = lua_getallocf(L, &ud); if ((msg = lalloc(ud, NULL, 0, msgsz)) == NULL) return pusherror(L, "lalloc"); int res = msgrcv(msgid, msg, msgsz, msgtyp, msgflg); if (res != -1) { lua_pushinteger(L, msg->mtype); lua_pushlstring(L, msg->mtext, res - sizeof(long)); } lalloc(ud, msg, msgsz, 0); return (res == -1) ? pusherror(L, NULL) : 2; }
/*** Change the name or location of a file @function rename @tparam string oldpath @tparam string newpath @treturn[1] int `0` if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see rename(2) @usage local ok, errmsg = P.rename (oldpath, newpath) if not ok then error (errmsg) end */ static int Prename(lua_State *L) /** rename(oldpath, newpath) */ { const char *oldpath = luaL_checkstring(L, 1); const char *newpath = luaL_checkstring(L, 2); checknargs(L, 2); return pushresult(L, rename(oldpath, newpath), NULL); }
static int Psched_getscheduler(lua_State *L) { struct sched_param sched_param = {0}; pid_t pid = optint(L, 1, 0); checknargs(L, 1); return pushresult(L, sched_getscheduler(pid), NULL); }
/*** Write bytes to a file. @function write @int fd the file descriptor to act on @string buf containing bytes to write @treturn[1] int number of bytes written, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see write(2) */ static int Pwrite(lua_State *L) { int fd = checkint(L, 1); const char *buf = luaL_checkstring(L, 2); checknargs(L, 2); return pushresult(L, write(fd, buf, lua_objlen(L, 2)), NULL); }
/*** Duplicate one open file descriptor to another. If *newfd* references an open file already, it is closed before being reallocated to *fd*. @function dup2 @int fd an open file descriptor to act on @int newfd new descriptor to duplicate *fd* @treturn[1] int new file descriptor, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see dup2(2) */ static int Pdup2(lua_State *L) { int fd = checkint(L, 1); int newfd = checkint(L, 2); checknargs(L, 2); return pushresult(L, dup2(fd, newfd), NULL); }
/*** Send a signal to the given process group. @function killpg @int pgrp group id to act on, or `0` for the sending process`s group @int[opt=`SIGTERM`] sig signal to send @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see killpg(2) */ static int Pkillpg(lua_State *L) { int pgrp = checkint(L, 1); int sig = optint(L, 2, SIGTERM); checknargs(L, 2); return pushresult(L, killpg(pgrp, sig), NULL); }
/*** Raise a signal on this process. @function raise @int sig signal to send @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see raise(3) */ static int Praise(lua_State *L) { int sig = checkint(L, 1); checknargs(L, 1); lua_pop(L, 1); return pushintresult(raise(sig)); }
/*** Suspend transmission or receipt of data. @function tcflow @int fd terminal descriptor to act on @int action one of `TCOOFF`, `TCOON`, `TCIOFF` or `TCION` @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see tcflow(3) */ static int Ptcflow(lua_State *L) { int fd = checkint(L, 1); int action = checkint(L, 2); checknargs(L, 2); return pushresult(L, tcflow(fd, action), NULL); }
/*** Send a signal to the given process. @function kill @int pid process to act on @int[opt=`SIGTERM` sig signal to send @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see kill(2) */ static int Pkill(lua_State *L) { pid_t pid = checkint(L, 1); int sig = optint(L, 2, SIGTERM); checknargs(L, 2); return pushresult(L, kill(pid, sig), NULL); }
/*** Send a stream of zero valued bits. @function tcsendbreak @see tcsendbreak(3) @int fd terminal descriptor @int duration if non-zero, stream for some implementation defined time @return 0 if successful, otherwise nil @return error message if failed */ static int Ptcsendbreak(lua_State *L) { int fd = checkint(L, 1); int duration = checkint(L, 2); checknargs(L, 2); return pushresult(L, tcsendbreak(fd, duration), NULL); }
/*** Discard any data already written but not yet sent to the terminal. @function tcflush @int fd terminal descriptor to act on @int action one of `TCIFLUSH`, `TCOFLUSH`, `TCIOFLUSH` @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see tcflush(3) */ static int Ptcflush(lua_State *L) { int fd = checkint(L, 1); int qs = checkint(L, 2); checknargs(L, 2); return pushresult(L, tcflush(fd, qs), NULL); }
/*** Shut down part of a full-duplex connection. @function shutdown @int fd socket descriptor to act on @int how one of `SHUT_RD`, `SHUT_WR` or `SHUT_RDWR` @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see shutdown(2) @usage ok, errmsg = P.shutdown (sock, P.SHUT_RDWR) */ static int Pshutdown(lua_State *L) { int fd = checkint(L, 1); int how = checkint(L, 2); checknargs(L, 2); return pushresult(L, shutdown(fd, how), "shutdown"); }
/*** Abort the program immediately. @function abort @see abort(3) */ static int Pabort(lua_State *L) { checknargs(L, 0); abort(); return 0; /* Avoid a compiler warning (or possibly cause one if the compiler's too clever, sigh). */ }
/*** Open a pseudoterminal. @function openpt @int oflags bitwise OR of zero or more of `O_RDWR` and `O_NOCTTY` @return[1] file descriptor of pseudoterminal, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see posix_openpt(3) @see grantpt @see ptsname @see unlockpt */ static int Popenpt(lua_State *L) { int flags = checkint(L, 1); checknargs(L, 1); /* The name of the pseudo-device is specified by POSIX */ return pushresult(L, open("/dev/ptmx", flags), NULL); }