1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
/*
* POSIX library for Lua 5.1, 5.2, 5.3 & 5.4.
* Copyright (C) 2013-2025 Gary V. Vaughan
* Copyright (C) 2010-2013 Reuben Thomas <rrt@sc3d.org>
* Copyright (C) 2008-2010 Natanael Copa <natanael.copa@gmail.com>
* Clean up and bug fixes by Leo Razoumov <slonik.az@gmail.com> 2006-10-11
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> 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 <stdio.h>
#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
@see fileno(3)
@usage
local stdio = require "posix.stdio"
local unistd = require "posix.unistd"
assert (stdio.fileno (io.stdout) == unistd.STDOUT_FILENO)
*/
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) {
int res = -1;
luaL_Stream *p = ((luaL_Stream *)luaL_checkudata(L, 1, LUA_FILEHANDLE));
if (p->f == NULL)
return 0;
res = fclose(p->f);
p->f = NULL;
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);
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM == 501
/* PUC-Rio Lua uses lconfig_h as include guard for luaconf.h,
LuaJIT uses luaconf_h. If you use PUC-Rio's include files
but LuaJIT's library, you're on your own here! */
# if !defined(luaconf_h)
lua_createtable(L, 0, 1);
lua_pushcfunction(L, stdio_fclose);
lua_setfield(L, -2, "__close");
lua_setfenv(L, -2); /* set fenv for 'fdopen' */
# endif
#endif
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
@tparam string mode the mode in which to open the file descriptor
@treturn[1] file Lua file object *fd*, if successful
@return[2] nil
@treturn[2] string error message
@treturn[2] int errnum
@see fdopen(3)
@usage
local fdopen = require "posix.stdio".fdopen
local STDOUT_FILENO = require "posix.unistd".STDOUT_FILENO
stdout = fdopen (STDOUT_FILENO, "w")
*/
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;
}
/***
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 const luaL_Reg posix_stdio_fns[] =
{
LPOSIX_FUNC( Pctermid ),
LPOSIX_FUNC( Pfileno ),
LPOSIX_FUNC( Pfdopen ),
LPOSIX_FUNC( Prename ),
{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_newlib(L, posix_stdio_fns);
lua_pushstring(L, LPOSIX_VERSION_STRING("stdio"));
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;
}
|