/* * 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 */ /*** A few Standard I/O functions not already in Lua core. @module posix.stdio */ #include #include #include "_helpers.c" /*** Name of controlling terminal. @function ctermid @treturn string controlling terminal for current process @see ctermid(3) */ static int Pctermid(lua_State *L) { char b[L_ctermid]; checknargs(L, 0); return pushstringresult(ctermid(b)); } /*** File descriptor corresponding to a Lua file object. @function fileno @tparam file file Lua file object @treturn[1] int file descriptor for *file*, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @usage STDOUT_FILENO = P.fileno (io.stdout) */ static int Pfileno(lua_State *L) { FILE *f = *(FILE**) luaL_checkudata(L, 1, LUA_FILEHANDLE); checknargs(L, 1); return pushresult(L, fileno(f), NULL); } /* This helper function is adapted from Lua 5.3's liolib.c */ static int stdio_fclose (lua_State *L) { luaL_Stream *p = ((luaL_Stream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)); int res = fclose(p->f); return luaL_fileresult(L, (res == 0), NULL); } /* This function could be used more generally; see */ static int pushfile (lua_State *L, int fd, const char *mode) { luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream)); luaL_getmetatable(L, LUA_FILEHANDLE); lua_setmetatable(L, -2); p->closef = stdio_fclose; p->f = fdopen(fd, mode); return p->f != NULL; } /*** Create a Lua file object from a file descriptor. @function fdopen @tparam int fd file descriptor @treturn[1] file file Lua file object *fd*, if successful @return[2] nil @treturn[2] string error message @treturn[2] int errnum @usage stdout = P.fdopen (posix.STDOUT_FILENO) */ static int Pfdopen(lua_State *L) /** fdopen(fd, mode) */ { int fd = checkint(L, 1); const char *mode = luaL_checkstring(L, 2); checknargs(L, 2); if (!pushfile(L, fd, mode)) return pusherror(L, "fdopen"); return 1; } static const luaL_Reg posix_stdio_fns[] = { LPOSIX_FUNC( Pctermid ), LPOSIX_FUNC( Pfileno ), LPOSIX_FUNC( Pfdopen ), {NULL, NULL} }; /*** Constants. @section constants */ /*** Stdio constants. Any constants not available in the underlying system will be `nil` valued. @table posix.stdio @int _IOFBF fully buffered @int _IOLBF line buffered @int _IONBF unbuffered @int BUFSIZ size of buffer @int EOF end of file @int FOPEN_MAX maximum number of open files @int FILENAME_MAX maximum length of filename @usage -- Print stdio constants supported on this host. for name, value in pairs (require "posix.stdio") do if type (value) == "number" then print (name, value) end end */ LUALIB_API int luaopen_posix_stdio(lua_State *L) { luaL_register(L, "posix.stdio", posix_stdio_fns); lua_pushliteral(L, "posix.stdio for " LUA_VERSION " / " PACKAGE_STRING); lua_setfield(L, -2, "version"); /* stdio.h constants */ /* Those that are omitted already have a Lua interface, or alternative. */ LPOSIX_CONST( _IOFBF ); LPOSIX_CONST( _IOLBF ); LPOSIX_CONST( _IONBF ); LPOSIX_CONST( BUFSIZ ); LPOSIX_CONST( EOF ); LPOSIX_CONST( FOPEN_MAX ); LPOSIX_CONST( FILENAME_MAX ); return 1; }