/* * lposix.c * POSIX library for Lua 5.0. Based on original by Claudio Terra for Lua 3.x. * Luiz Henrique de Figueiredo * 05 Nov 2003 22:09:10 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MYNAME "posix" #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2003" #include "lua.h" #include "lauxlib.h" #ifndef MYBUFSIZ #define MYBUFSIZ 512 #endif #include "modemuncher.c" static const char *filetype(mode_t m) { if (S_ISREG(m)) return "regular"; else if (S_ISLNK(m)) return "link"; else if (S_ISDIR(m)) return "directory"; else if (S_ISCHR(m)) return "character device"; else if (S_ISBLK(m)) return "block device"; else if (S_ISFIFO(m)) return "fifo"; else if (S_ISSOCK(m)) return "socket"; else return "?"; } typedef int (*Selector)(lua_State *L, int i, const void *data); static int doselection(lua_State *L, int i, const char *const S[], Selector F, const void *data) { if (lua_isnone(L, i)) { lua_newtable(L); for (i=0; S[i]!=NULL; i++) { lua_pushstring(L, S[i]); F(L, i, data); lua_settable(L, -3); } return 1; } else { int j=luaL_checkoption(L, i, NULL, S); if (j==-1) luaL_argerror(L, i, "unknown selector"); return F(L, j, data); } } static void storeindex(lua_State *L, int i, const char *value) { lua_pushstring(L, value); lua_rawseti(L, -2, i); } static void storestring(lua_State *L, const char *name, const char *value) { lua_pushstring(L, name); lua_pushstring(L, value); lua_settable(L, -3); } static void storenumber(lua_State *L, const char *name, lua_Number value) { lua_pushstring(L, name); lua_pushnumber(L, value); lua_settable(L, -3); } static int pusherror(lua_State *L, const char *info) { lua_pushnil(L); if (info==NULL) lua_pushstring(L, strerror(errno)); else lua_pushfstring(L, "%s: %s", info, strerror(errno)); lua_pushnumber(L, errno); return 3; } static int pushresult(lua_State *L, int i, const char *info) { if (i != -1) { lua_pushnumber(L, i); return 1; } else return pusherror(L, info); } static void badoption(lua_State *L, int i, const char *what, int option) { luaL_argerror(L, 2, lua_pushfstring(L, "unknown %s option `%c'", what, option)); } static uid_t mygetuid(lua_State *L, int i) { if (lua_isnone(L, i)) return -1; else if (lua_isnumber(L, i)) return (uid_t) lua_tonumber(L, i); else if (lua_isstring(L, i)) { struct passwd *p=getpwnam(lua_tostring(L, i)); return (p==NULL) ? -1 : p->pw_uid; } else return luaL_typerror(L, i, "string or number"); } static gid_t mygetgid(lua_State *L, int i) { if (lua_isnone(L, i)) return -1; else if (lua_isnumber(L, i)) return (gid_t) lua_tonumber(L, i); else if (lua_isstring(L, i)) { struct group *g=getgrnam(lua_tostring(L, i)); return (g==NULL) ? -1 : g->gr_gid; } else return luaL_typerror(L, i, "string or number"); } static int Perrno(lua_State *L) /** errno() */ { lua_pushstring(L, strerror(errno)); lua_pushnumber(L, errno); return 2; } static int Pdir(lua_State *L) /** dir([path]) */ { const char *path = luaL_optstring(L, 1, "."); DIR *d = opendir(path); if (d == NULL) return pusherror(L, path); else { int i; struct dirent *entry; lua_newtable(L); for (i=1; (entry = readdir(d)) != NULL; i++) storeindex(L, i, entry->d_name); closedir(d); return 1; } } static int aux_files(lua_State *L) { DIR *d = lua_touserdata(L, lua_upvalueindex(1)); struct dirent *entry; if (d == NULL) luaL_error(L, "attempt to use closed dir"); entry = readdir(d); if (entry == NULL) { closedir(d); lua_pushnil(L); lua_replace(L, lua_upvalueindex(1)); lua_pushnil(L); } else { lua_pushstring(L, entry->d_name); #if 0 #ifdef _DIRENT_HAVE_D_TYPE lua_pushstring(L, filetype(DTTOIF(entry->d_type))); return 2; #endif #endif } return 1; } static int Pfiles(lua_State *L) /** files([path]) */ { const char *path = luaL_optstring(L, 1, "."); DIR *d = opendir(path); if (d == NULL) return pusherror(L, path); else { lua_pushlightuserdata(L, d); lua_pushcclosure(L, aux_files, 1); return 1; } } static int Pgetcwd(lua_State *L) /** getcwd() */ { char buf[MYBUFSIZ]; if (getcwd(buf, sizeof(buf)) == NULL) return pusherror(L, "."); else { lua_pushstring(L, buf); return 1; } } static int Pmkdir(lua_State *L) /** mkdir(path) */ { const char *path = luaL_checkstring(L, 1); return pushresult(L, mkdir(path, 0777), path); } static int Pchdir(lua_State *L) /** chdir(path) */ { const char *path = luaL_checkstring(L, 1); return pushresult(L, chdir(path), path); } static int Prmdir(lua_State *L) /** rmdir(path) */ { const char *path = luaL_checkstring(L, 1); return pushresult(L, rmdir(path), path); } static int Punlink(lua_State *L) /** unlink(path) */ { const char *path = luaL_checkstring(L, 1); return pushresult(L, unlink(path), path); } static int Plink(lua_State *L) /** link(oldpath,newpath) */ { const char *oldpath = luaL_checkstring(L, 1); const char *newpath = luaL_checkstring(L, 2); return pushresult(L, link(oldpath, newpath), NULL); } static int Psymlink(lua_State *L) /** symlink(oldpath,newpath) */ { const char *oldpath = luaL_checkstring(L, 1); const char *newpath = luaL_checkstring(L, 2); return pushresult(L, symlink(oldpath, newpath), NULL); } static int Preadlink(lua_State *L) /** readlink(path) */ { char buf[MYBUFSIZ]; const char *path = luaL_checkstring(L, 1); int n = readlink(path, buf, sizeof(buf)); if (n==-1) return pusherror(L, path); lua_pushlstring(L, buf, n); return 1; } static int Paccess(lua_State *L) /** access(path,[mode]) */ { int mode=F_OK; const char *path=luaL_checkstring(L, 1); const char *s; for (s=luaL_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); } static int Pmkfifo(lua_State *L) /** mkfifo(path) */ { const char *path = luaL_checkstring(L, 1); return pushresult(L, mkfifo(path, 0777), path); } static int Pexec(lua_State *L) /** exec(path,[args]) */ { const char *path = luaL_checkstring(L, 1); int i,n=lua_gettop(L); char **argv = malloc((n+1)*sizeof(char*)); if (argv==NULL) luaL_error(L,"not enough memory"); argv[0] = (char*)path; for (i=1; i