/* * POSIX library for Lua 5.1, 5.2 & 5.3. * (c) Gary V. Vaughan , 2013-2015 * (c) Reuben Thomas 2010-2013 * (c) Natanael Copa 2008-2010 * Clean up and bug fixes by Leo Razoumov 2006-10-11 * Luiz Henrique de Figueiredo 07 Apr 2006 23:17:49 * Based on original by Claudio Terra for Lua 3.x. * With contributions by Roberto Ierusalimschy. * With documentation from Steve Donovan 2012 */ /*** Unix Standard APIs. Where the underlying system does not support one of these functions, it will have a `nil` value in the module table. @module posix.unistd */ #include #if HAVE_CRYPT_H # include #endif #include #include #include #include "_helpers.c" static uid_t mygetuid(lua_State *L, int i) { if (lua_isnoneornil(L, i)) return (uid_t)-1; else if (lua_isinteger(L, i)) return (uid_t) lua_tointeger(L, i); else if (lua_isstring(L, i)) { struct passwd *p = getpwnam(lua_tostring(L, i)); return (p == NULL) ? (uid_t) -1 : p->pw_uid; } else return argtypeerror(L, i, "string, int or nil"); } static gid_t mygetgid(lua_State *L, int i) { if (lua_isnoneornil(L, i)) return (gid_t)-1; else if (lua_isinteger(L, i)) return (gid_t) lua_tointeger(L, i); else if (lua_isstring(L, i)) { struct group *g = getgrnam(lua_tostring(L, i)); return (g == NULL) ? (uid_t) -1 : g->gr_gid; } else return argtypeerror(L, i, "string, int or nil"); } /*** Terminate the calling process. @function _exit @int status process exit status @see _exit(2) */ static int P_exit(lua_State *L) { pid_t ret = checkint(L, 1); checknargs(L, 1); _exit(ret); return 0; /* Avoid a compiler warning (or possibly cause one if the compiler's too clever, sigh). */ } /*** Check real user's permissions for a file. @function access @string path file to act on @string[opt="f"] mode can contain 'r','w','x' and 'f' @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see access(2) @usage status, errstr, errno = P.access("/etc/passwd", "rw") */ static int Paccess(lua_State *L) { int mode=F_OK; const char *path=luaL_checkstring(L, 1); const char *s; checknargs(L, 2); for (s=optstring(L, 2, "f"); *s!=0 ; s++) switch (*s) { case ' ': break; case 'r': mode |= R_OK; break; case 'w': mode |= W_OK; break; case 'x': mode |= X_OK; break; case 'f': mode |= F_OK; break; default: badoption(L, 2, "mode", *s); break; } return pushresult(L, access(path, mode), path); } /*** Set the working directory. @function chdir @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 chdir(2) @usage status, errstr, errno = P.chdir("/var/tmp") */ static int Pchdir(lua_State *L) { const char *path = luaL_checkstring(L, 1); checknargs(L, 1); return pushresult(L, chdir(path), path); } /*** Change ownership of a file. @function chown @string path existing file path @tparam string|int uid new owner user id @tparam string|int gid new owner group id @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error messoge @treturn[2] int errnum @see chown(2) @usage -- will fail for a normal user, and print an error print(P.chown("/etc/passwd",100,200)) */ static int Pchown(lua_State *L) { const char *path = luaL_checkstring(L, 1); uid_t uid = mygetuid(L, 2); gid_t gid = mygetgid(L, 3); checknargs(L, 3); return pushresult(L, chown(path, uid, gid), path); } /*** 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 ok, errmsg = P.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); } #if defined HAVE_CRYPT /*** Encrypt a password. Not recommended for general encryption purposes. @function crypt @string trypass string to hash @string salt two-character string from [a-zA-Z0-9./] @return encrypted string @see crypt(3) @usage local salt, hash = pwent:match ":$6$(.-)$([^:]+)" if P.crypt (trypass, salt) ~= hash then error "wrong password" end */ static int Pcrypt(lua_State *L) { const char *str, *salt; char *r; str = luaL_checkstring(L, 1); salt = luaL_checkstring(L, 2); if (strlen(salt) < 2) luaL_error(L, "not enough salt"); checknargs(L, 2); r = crypt(str, salt); return pushstringresult(r); } #endif /*** Duplicate an open file descriptor. @function dup @int fd file descriptor to act on @treturn[1] int new file descriptor duplicating *fd*, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see dup(2) @usage local outfd = P.dup (P.fileno (io.stdout)) */ static int Pdup(lua_State *L) { int fd = checkint(L, 1); checknargs(L, 1); return pushresult(L, dup(fd), 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); } 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); } /*** Execute a program without using the shell. @function exec @string path @tparam table argt arguments (table can include index 0) @return nil @treturn string error message @see execve(2) @usage exec ("/bin/bash", {[0] = "-sh", "--norc}) */ static int Pexec(lua_State *L) { return runexec(L, 0); } /*** Execute a program using the shell. @function execp @string path @tparam table argt arguments (table can include index 0) @return nil @treturn string error message @see execve(2) */ static int Pexecp(lua_State *L) { return runexec(L, 1); } #if LPOSIX_2001_COMPLIANT #if !HAVE_DECL_FDATASYNC extern int fdatasync (); #endif /*** Synchronize a file's in-core state with storage device without metadata. @function fdatasync @int fd @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see fdatasync(2) */ static int Pfdatasync(lua_State *L) { int fd = checkint(L, 1); checknargs(L, 1); return pushresult(L, fdatasync(fd), NULL); } #endif /*** Fork this program. @function fork @treturn[1] int `0` in the resulting child process @treturn[2] int process id of child, in the calling process @return[3] nil @treturn[3] string error message @treturn[3] int errnum @see fork(2) @see fork.lua @see fork2.lua @usage local pid, errmsg = P.fork () if pid == nil then error (errmsg) elseif pid == 0 then print ("in child:", P.getpid "pid") else print (P.wait (pid)) end os.exit () */ static int Pfork(lua_State *L) { checknargs(L, 0); return pushresult(L, fork(), NULL); } /*** 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); } /*** Current working directory for this process. @function getcwd @treturn[1] string path of current working directory, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see getcwd(3) */ static int Pgetcwd(lua_State *L) { #ifdef __GNU__ char *b = get_current_dir_name(); checknargs(L, 0); if (b == NULL) /* we return the same error as below */ return pusherror(L, "."); return pushstringresult(b); #else long size = pathconf(".", _PC_PATH_MAX); void *ud; lua_Alloc lalloc; char *b, *r; checknargs(L, 0); lalloc = lua_getallocf(L, &ud); if (size == -1) size = _POSIX_PATH_MAX; /* FIXME: Retry if this is not long enough */ if ((b = lalloc(ud, NULL, 0, (size_t)size + 1)) == NULL) return pusherror(L, "lalloc"); r = getcwd(b, (size_t)size); if (r != NULL) lua_pushstring(L, b); lalloc(ud, b, (size_t)size + 1, 0); return (r == NULL) ? pusherror(L, ".") : 1; #endif } /*** Return effective group id of calling process. @function getegid @treturn int effective group id of calling process @see getgid */ static int Pgetegid(lua_State *L) { checknargs(L, 0); return pushintresult(getegid ()); } /*** Return effective user id of calling process. @function geteuid @treturn int effective user id of calling process @see getuid */ static int Pgeteuid(lua_State *L) { checknargs(L, 0); return pushintresult(geteuid ()); } /*** Return group id of calling process. @function getgid @treturn int group id of calling process @see getegid */ static int Pgetgid(lua_State *L) { checknargs(L, 0); return pushintresult(getgid ()); } #if LPOSIX_2001_COMPLIANT /*** 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; } #endif /*** Current logged-in user. @treturn[1] string username, if successful @return[2] nil @see getlogin(3) */ static int Pgetlogin(lua_State *L) { checknargs(L, 0); return pushstringresult(getlogin()); } /*** Return process group id of calling process. @function getpgrp @treturn int process group id of calling process @see getpid */ static int Pgetpgrp(lua_State *L) { checknargs(L, 0); return pushintresult(getpgrp ()); } /*** Return process id of calling process. @function getpid @treturn int process id of calling process */ static int Pgetpid(lua_State *L) { checknargs(L, 0); return pushintresult(getpid ()); } /*** Return parent process id of calling process. @function getppid @treturn int parent process id of calling process @see getpid */ static int Pgetppid(lua_State *L) { checknargs(L, 0); return pushintresult(getppid ()); } /*** Return user id of calling process. @function getuid @treturn int user id of calling process @see geteuid */ static int Pgetuid(lua_State *L) { checknargs(L, 0); return pushintresult(getuid ()); } /*** Get host id. @function gethostid @see gethostid(3) @treturn[1] int host id @return[2] nil @treturn[2] string error message */ static int Pgethostid(lua_State *L) { checknargs(L, 0); #if HAVE_GETHOSTID return pushintresult(gethostid()); #else lua_pushnil(L); lua_pushliteral(L, "unsupported by this host"); return 2; #endif } /*** 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"); } /*** Create a link. @function link @string target name @string link name @bool[opt=false] soft link @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see link(2) @see symlink(2) */ static int Plink(lua_State *L) { const char *oldpath = luaL_checkstring(L, 1); const char *newpath = luaL_checkstring(L, 2); int symbolicp = optboolean(L, 3, 0); checknargs(L, 3); return pushresult(L, (symbolicp ? symlink : link)(oldpath, newpath), NULL); } /*** reposition read/write file offset @function lseek @see lseek(2) @int fd open file descriptor to act on @int offset bytes to seek @int whence one of `SEEK_SET`, `SEEK_CUR` or `SEEK_END` @treturn[1] int new offset, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum */ static int Plseek(lua_State *L) { int fd = checkint(L, 1); int offset = checkint(L, 2); int whence = checkint(L, 3); checknargs(L, 3); return pushresult(L, lseek(fd, offset, whence), NULL); } /*** 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 for a, b in pairs (P.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))); } /*** Creates a pipe. @function pipe @treturn[1] int read end file descriptor @treturn[1] int write end file descriptor @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see pipe(2) @see fork.lua */ static int Ppipe(lua_State *L) { int pipefd[2]; int rc; checknargs(L, 0); rc = pipe(pipefd); if (rc < 0) return pusherror(L, "pipe"); lua_pushinteger(L, pipefd[0]); lua_pushinteger(L, pipefd[1]); return 2; } /*** Read bytes from a file. @function read @int fd the file descriptor to act on @int count maximum number of bytes to read @treturn[1] string string from *fd* with at most *count* bytes, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see read(2) */ static int Pread(lua_State *L) { int fd = checkint(L, 1); int count = checkint(L, 2), ret; void *ud, *buf; lua_Alloc lalloc; checknargs(L, 2); lalloc = lua_getallocf(L, &ud); /* Reset errno in case lalloc doesn't set it */ errno = 0; if ((buf = lalloc(ud, NULL, 0, count)) == NULL && count > 0) return pusherror(L, "lalloc"); ret = read(fd, buf, count); if (ret >= 0) lua_pushlstring(L, buf, ret); lalloc(ud, buf, count, 0); return (ret < 0) ? pusherror(L, NULL) : 1; } /*** Read value of a symbolic link. @function readlink @string path file to act on @treturn[1] string link target, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see readlink(2) */ static int Preadlink(lua_State *L) { char *b; struct stat s; const char *path = luaL_checkstring(L, 1); void *ud; lua_Alloc lalloc; ssize_t n; int err; checknargs(L, 1); lalloc = lua_getallocf(L, &ud); errno = 0; /* ignore outstanding unreported errors */ /* s.st_size is length of linkname, with no trailing \0 */ if (lstat(path, &s) < 0) return pusherror(L, path); /* diagnose non-symlinks */ if (!S_ISLNK(s.st_mode)) { lua_pushnil(L); lua_pushfstring(L, "%s: not a symbolic link", path); lua_pushinteger(L, EINVAL); return 3; } /* allocate a buffer for linkname, with no trailing \0 */ if ((b = lalloc(ud, NULL, 0, s.st_size)) == NULL) return pusherror(L, "lalloc"); n = readlink(path, b, s.st_size); err = errno; /* save readlink error code, if any */ if (n != -1) lua_pushlstring(L, b, s.st_size); lalloc(ud, b, s.st_size, 0); /* report new errors from this function */ if (n < 0) { errno = err; /* restore readlink error code */ return pusherror(L, "readlink"); } else if (n < s.st_size) { lua_pushnil(L); lua_pushfstring(L, "%s: readlink wrote only %d of %d bytes", path, n, s.st_size); return 2; } return 1; } /*** 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); } /*** 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; } } /*** 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)); } /*** Commit buffer cache to disk. @function sync @see fsync @see sync(2) */ static int Psync(lua_State *L) { checknargs(L, 0); sync(); return 0; } /*** Get configuration information at runtime. @function sysconf @int key one of `_SC_ARG_MAX`, `_SC_CHILD_MAX`, `_SC_CLK_TCK`, `_SC_JOB_CONTROL`, `_SC_OPEN_MAX`, `_SC_NGROUPS_MAX`, `_SC_SAVED_IDS`, `_SC_STREAM_MAX`, `_SC_TZNAME_MAX` or `_SC_VERSION`, @treturn int associated system configuration value @see sysconf(3) */ static int Psysconf(lua_State *L) { checknargs(L, 1); return pushintresult(sysconf(checkint(L, 1))); } /*** 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)); } /*** Unlink a file. @function unlink @string path @treturn[1] int `0`, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see unlink(2) */ static int Punlink(lua_State *L) { const char *path = luaL_checkstring(L, 1); checknargs(L, 1); return pushresult(L, unlink(path), path); } /*** 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); } static const luaL_Reg posix_unistd_fns[] = { LPOSIX_FUNC( P_exit ), LPOSIX_FUNC( Paccess ), LPOSIX_FUNC( Pchdir ), LPOSIX_FUNC( Pchown ), LPOSIX_FUNC( Pclose ), #if defined HAVE_CRYPT LPOSIX_FUNC( Pcrypt ), #endif LPOSIX_FUNC( Pdup ), LPOSIX_FUNC( Pdup2 ), LPOSIX_FUNC( Pexec ), LPOSIX_FUNC( Pexecp ), #if LPOSIX_2001_COMPLIANT LPOSIX_FUNC( Pfdatasync ), #endif LPOSIX_FUNC( Pfork ), LPOSIX_FUNC( Pfsync ), LPOSIX_FUNC( Pgetcwd ), #if LPOSIX_2001_COMPLIANT LPOSIX_FUNC( Pgetgroups ), #endif LPOSIX_FUNC( Pgetegid ), LPOSIX_FUNC( Pgeteuid ), LPOSIX_FUNC( Pgetgid ), LPOSIX_FUNC( Pgetlogin ), LPOSIX_FUNC( Pgetpgrp ), LPOSIX_FUNC( Pgetpid ), LPOSIX_FUNC( Pgetppid ), LPOSIX_FUNC( Pgetuid ), LPOSIX_FUNC( Pgethostid ), LPOSIX_FUNC( Pisatty ), LPOSIX_FUNC( Plink ), LPOSIX_FUNC( Plseek ), LPOSIX_FUNC( Pnice ), LPOSIX_FUNC( Ppathconf ), LPOSIX_FUNC( Ppipe ), LPOSIX_FUNC( Pread ), LPOSIX_FUNC( Preadlink ), LPOSIX_FUNC( Prmdir ), LPOSIX_FUNC( Psetpid ), LPOSIX_FUNC( Psleep ), LPOSIX_FUNC( Psync ), LPOSIX_FUNC( Psysconf ), LPOSIX_FUNC( Pttyname ), LPOSIX_FUNC( Punlink ), LPOSIX_FUNC( Pwrite ), {NULL, NULL} }; /*** Constants. @section constants */ /*** Standard constants. Any constants not available in the underlying system will be `nil` valued. @table posix.unistd @int _PC_CHOWN_RESTRICTED return 1 if chown requires appropriate privileges, 0 otherwise @int _PC_LINK_MAX maximum file link count @int _PC_MAX_CANON maximum bytes in terminal canonical input line @int _PC_MAX_INPUT maximum number of bytes in a terminal input queue @int _PC_NAME_MAX maximum number of bytes in a file name @int _PC_NO_TRUNC return 1 if over-long file names are truncated @int _PC_PATH_MAXmaximum number of bytes in a pathname @int _PC_PIPE_BUF maximum number of bytes in an atomic pipe write @int _PC_VDISABLE terminal character disabling value @int _SC_ARG_MAX maximum bytes of argument to @{posix.unistd.execp} @int _SC_CHILD_MAX maximum number of processes per user @int _SC_CLK_TCK statistics clock frequency @int _SC_JOB_CONTROL return 1 if system has job control, -1 otherwise @int _SC_NGROUPS_MAX maximum number of supplemental groups @int _SC_OPEN_MAX maximum number of open files per user @int _SC_SAVED_IDS return 1 if system supports saved user and group ids, -1 otherwise @int _SC_STREAM_MAX maximum number of streams per process @int _SC_TZNAME_MAX maximum number of timezone types @int _SC_VERSION POSIX.1 compliance version @int SEEK_CUR relative file pointer position @int SEEK_END set file pointer to the end of file @int SEEK_SET absolute file pointer position @int STDERR_FILENO standard error file descriptor @int STDIN_FILENO standard input file descriptor @int STDOUT_FILENO standard output file descriptor @usage -- Print unistd constants supported on this host. for name, value in pairs (require "posix.unistd") do if type (value) == "number" then print (name, value) end end */ LUALIB_API int luaopen_posix_unistd(lua_State *L) { luaL_register(L, "posix.unistd", posix_unistd_fns); lua_pushliteral(L, "posix.unistd for " LUA_VERSION " / " PACKAGE_STRING); lua_setfield(L, -2, "version"); /* pathconf arguments */ LPOSIX_CONST( _PC_CHOWN_RESTRICTED ); LPOSIX_CONST( _PC_LINK_MAX ); LPOSIX_CONST( _PC_MAX_CANON ); LPOSIX_CONST( _PC_MAX_INPUT ); LPOSIX_CONST( _PC_NAME_MAX ); LPOSIX_CONST( _PC_NO_TRUNC ); LPOSIX_CONST( _PC_PATH_MAX ); LPOSIX_CONST( _PC_PIPE_BUF ); LPOSIX_CONST( _PC_VDISABLE ); /* sysconf arguments */ LPOSIX_CONST( _SC_ARG_MAX ); LPOSIX_CONST( _SC_CHILD_MAX ); LPOSIX_CONST( _SC_CLK_TCK ); LPOSIX_CONST( _SC_JOB_CONTROL ); LPOSIX_CONST( _SC_OPEN_MAX ); LPOSIX_CONST( _SC_NGROUPS_MAX ); LPOSIX_CONST( _SC_SAVED_IDS ); LPOSIX_CONST( _SC_STREAM_MAX ); LPOSIX_CONST( _SC_TZNAME_MAX ); LPOSIX_CONST( _SC_VERSION ); /* lseek arguments */ LPOSIX_CONST( SEEK_CUR ); LPOSIX_CONST( SEEK_END ); LPOSIX_CONST( SEEK_SET ); /* Miscellaneous */ LPOSIX_CONST( STDERR_FILENO ); LPOSIX_CONST( STDIN_FILENO ); LPOSIX_CONST( STDOUT_FILENO ); return 1; }