lua的posix接口

 http://lua-users.org/lists/lua-l/2006-04/msg00162.html

 

 

A new version of my POSIX library is almost ready. I still have to write
a reasonable test and perhaps some documentation, and so I'm not ready yet
to release a tarball. However, since there are a few flavors of POSIX
around, I thought I'd ask anyone interested to try to compile this code
on their system and report any problems.

The code has been simplified and extended. The API has changed a bit.
A summary is below. I'd like to hear your impressions on what is missing
or useless. (Some candidates for removal are pathconf and sysconf.)

The code seems to compile ok under Lua 5.0 (but pipe does not work yet
in Lua 5.0).

Thanks for your feedback.
--lhf

posix library:
 access(path,[mode]) 		 kill(pid,[sig]) 
 basename(path) 		 link(old,new,[symbolic]) 
 chdir(path) 			 mkdir(path) 
 chmod(path,mode) 		 mkfifo(path) 
 chown(path,uid,gid) 		 pathconf([path,options]) 
 ctermid() 			 pipe() 
 dirname(path) 			 readlink(path) 
 dir([path]) 			 setenv(name,value,[over]) 
 dup(old,[new]) 		 setpid(option,...) 
 errno([n]) 			 sleep(seconds) 
 exec(path,[args]) 		 stat(path,[options]) 
 files([path]) 			 sysconf([options]) 
 fork() 			 times([options]) 
 getcwd() 			 ttyname([fd]) 
 getenv([name]) 		 umask([mode]) 
 getgroup(name|id) 		 uname([string]) 
 getlogin() 			 utime(path,[mtime,atime]) 
 getpasswd(name|id,[sel]) 	 version 
 getpid([options]) 		 wait([pid]) 
 hostid() 
/* * lposix.c * POSIX library for Lua 5.1. * 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. */ #include #include #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 " / Apr 2006" #include "lua.h" #include "lualib.h" #include "lauxlib.h" /* compatibility with Lua 5.0 */ #ifndef LUA_VERSION_NUM static int luaL_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]) { const char *name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg); int i = luaL_findstring(name, lst); if (i == -1) luaL_argerror(L, narg, lua_pushfstring(L, "invalid option '%s'", name)); return i; } #define lua_pushinteger lua_pushnumber #define lua_createtable(L,a,r) lua_newtable(L) #define LUA_FILEHANDLE "FILE*" #define lua_setfield(l,i,k) #define lua_getfield(l,i,k) #endif static const struct { char c; mode_t b; } M[] = { {'r', S_IRUSR}, {'w', S_IWUSR}, {'x', S_IXUSR}, {'r', S_IRGRP}, {'w', S_IWGRP}, {'x', S_IXGRP}, {'r', S_IROTH}, {'w', S_IWOTH}, {'x', S_IXOTH}, }; static int modemunch(mode_t *mode, const char *p) { int i; mode_t m=*mode; for (i=0; i<9; i ++) { if (p[i] == M[i].c) m |= M[i].b; else if (p[i] == '-') m &= ~M[i].b; else if (p[i]=='.') ; else if (p[i]=='s') { if (i==2) m |= S_ISUID | S_IXUSR; else if (i==5) m |= S_ISGID | S_IXGRP; else return -1; } else return -1; } *mode=m; return 0; } static void pushmode(lua_State *L, mode_t mode) { char m[9]; int i; for (i=0; i<9; i++) m[i]= (mode & M[i].b) ? M[i].c : '-'; if (mode & S_ISUID) m[2]= (mode & S_IXUSR) ? 's' : 'S'; if (mode & S_ISGID) m[5]= (mode & S_IXGRP) ? 's' : 'S'; lua_pushlstring(L, m, 9); } typedef void (*Selector)(lua_State *L, int i, const void *data); static int doselection(lua_State *L, int i, int n, const char *const S[], Selector F, const void *data) { if (lua_isnone(L, i) || lua_istable(L, i)) { int j; if (lua_isnone(L, i)) lua_createtable(L,0,n); else lua_settop(L, i); for (j=0; S[j]!=NULL; j++) { lua_pushstring(L, S[j]); F(L, j, data); lua_settable(L, -3); } return 1; } else { int k,n=lua_gettop(L); for (k=i; k<=n; k++) { int j=luaL_checkoption(L, k, NULL, S); F(L, j, data); lua_replace(L, k); } return n-i+1; } } #define doselection(L,i,S,F,d) (doselection)(L,i,sizeof(S)/sizeof(*S)-1,S,F,d) 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_pushinteger(L, errno); return 3; } static int pushresult(lua_State *L, int i, const char *info) { if (i==-1) return pusherror(L, info); lua_pushinteger(L, i); return 1; } 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([n]) */ { int n = luaL_optint(L, 1, errno); lua_pushstring(L, strerror(n)); lua_pushinteger(L, n); return 2; } static int Pbasename(lua_State *L) /** basename(path) */ { char b[PATH_MAX]; size_t len; const char *path = luaL_checklstring(L, 1, &len); if (len>=sizeof(b)) luaL_argerror(L, 1, "too long"); lua_pushstring(L, basename(strcpy(b,path))); return 1; } static int Pdirname(lua_State *L) /** dirname(path) */ { char b[PATH_MAX]; size_t len; const char *path = luaL_checklstring(L, 1, &len); if (len>=sizeof(b)) luaL_argerror(L, 1, "too long"); lua_pushstring(L, dirname(strcpy(b,path))); return 1; } 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++) { lua_pushstring(L, entry->d_name); lua_rawseti(L, -2, i); } closedir(d); lua_pushinteger(L, i-1); return 2; } } static int aux_files(lua_State *L) { DIR **p = (DIR **)lua_touserdata(L, lua_upvalueindex(1)); DIR *d = *p; struct dirent *entry; if (d == NULL) return 0; entry = readdir(d); if (entry == NULL) { closedir(d); *p=NULL; return 0; } else { lua_pushstring(L, entry->d_name); return 1; } } static int dir_gc (lua_State *L) { DIR *d = *(DIR **)lua_touserdata(L, 1); if (d!=NULL) closedir(d); return 0; } static int Pfiles(lua_State *L) /** files([path]) */ { const char *path = luaL_optstring(L, 1, "."); DIR **d = (DIR **)lua_newuserdata(L, sizeof(DIR *)); if (luaL_newmetatable(L, MYNAME " dir handle")) { lua_pushliteral(L, "__gc"); lua_pushcfunction(L, dir_gc); lua_settable(L, -3); } lua_setmetatable(L, -2); *d = opendir(path); if (*d == NULL) return pusherror(L, path); lua_pushcclosure(L, aux_files, 1); return 1; } static int Pgetcwd(lua_State *L) /** getcwd() */ { char b[PATH_MAX]; if (getcwd(b, sizeof(b)) == NULL) return pusherror(L, "."); lua_pushstring(L, b); 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 Plink(lua_State *L) /** link(old,new,[symbolic]) */ { const char *oldpath = luaL_checkstring(L, 1); const char *newpath = luaL_checkstring(L, 2); return pushresult(L, (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL); } static int Preadlink(lua_State *L) /** readlink(path) */ { char b[PATH_MAX]; const char *path = luaL_checkstring(L, 1); int n = readlink(path, b, sizeof(b)); if (n==-1) return pusherror(L, path); lua_pushlstring(L, b, 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 myfclose (lua_State *L) { FILE **p = (FILE **)lua_touserdata(L, 1); int rc = fclose(*p); if (rc == 0) *p = NULL; return pushresult(L, rc, NULL); } static int pushfile (lua_State *L, int id, const char *mode) { FILE **f = (FILE **)lua_newuserdata(L, sizeof(FILE *)); *f = NULL; luaL_getmetatable(L, LUA_FILEHANDLE); lua_setmetatable(L, -2); lua_getfield(L, LUA_REGISTRYINDEX, "POSIX_PIPEFILE"); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_pushvalue(L, -1); lua_pushcfunction(L, myfclose); lua_setfield(L, -2, "__close"); lua_setfield(L, LUA_REGISTRYINDEX, "POSIX_PIPEFILE"); } lua_setfenv(L, -2); *f = fdopen(id, mode); return (*f != NULL); } static int Ppipe(lua_State *L) /** pipe() */ { int fd[2]; if (pipe(fd)==-1) return pusherror(L, NULL); if (!pushfile(L, fd[0], "r") || !pushfile(L, fd[1], "w")) return pusherror(L, "pipe"); return 2; } static int Pdup(lua_State *L) /** dup(old,[new]) */ { int oldfd = luaL_checkint(L, 1); int newfd = luaL_optint(L, 2, -1); return pushresult(L, (newfd<0) ? dup(oldfd) : dup2(oldfd, newfd), NULL); } 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 = lua_newuserdata(L,(n+1)*sizeof(char*)); argv[0] = (char*)path; for (i=1; i

 

你可能感兴趣的:(lua的posix接口)