diff --git a/examples/password_input.lua b/examples/password_input.lua index b6b80a8..ff4afd9 100644 --- a/examples/password_input.lua +++ b/examples/password_input.lua @@ -16,14 +16,14 @@ local function read_secret(...) if sys.isatty(io.stdin) then -- backup settings, configure echo flags - w_oldflags = sys.disableconsoleflags(io.stdin, sys.CIF_ECHO_INPUT) + w_oldflags = sys.getconsoleflags(io.stdin) p_oldflags = sys.tcgetattr(io.stdin) - sys.tcdisableattr(io.stdin, sys.TCSANOW, { - lflag = sys.L_ECHO, -- echo is off to not show password on screen - }) - sys.tcenableattr(io.stdin, sys.TCSANOW, { - lflag = sys.L_ECHONL, -- echo is off, but we still echo the final newline - }) + -- Windows: echo is off to not show password on screen (has no L_ECHONL option) + assert(sys.setconsoleflags(io.stdin, w_oldflags - sys.CIF_ECHO_INPUT)) + -- Posix: echo is off to not show password on screen, but we still echo the final newline + assert(sys.tcsetattr(io.stdin, sys.TCSANOW, { + lflag = p_oldflags.lflag - sys.L_ECHO + sys.L_ECHONL + })) end local secret, err = io.stdin:read(...) diff --git a/src/bitflags.h b/src/bitflags.h index c6ca39b..89f2f52 100644 --- a/src/bitflags.h +++ b/src/bitflags.h @@ -11,6 +11,7 @@ // Validates that the given index is a bitflag object and returns its value. // If the index is not a bitflag object, a Lua error is raised. +// The value will be left on the stack. LSBF_FLAGTYPE lsbf_checkbitflags(lua_State *L, int index); // Pushes a new bitflag object with the given value onto the stack. diff --git a/src/core.c b/src/core.c index e5f1c3c..d233ecc 100644 --- a/src/core.c +++ b/src/core.c @@ -33,10 +33,10 @@ LUAEXPORT int luaopen_system_core(lua_State *L) { lua_pushboolean(L, 0); #endif lua_rawset(L, -3); + bitflags_open(L); // must be first, used by others time_open(L); random_open(L); term_open(L); environment_open(L); - bitflags_open(L); return 1; } diff --git a/src/term.c b/src/term.c index 7c382b5..0340db3 100644 --- a/src/term.c +++ b/src/term.c @@ -7,7 +7,7 @@ #include #include #include "compat.h" - +#include "bitflags.h" #ifndef _MSC_VER # include @@ -22,7 +22,6 @@ # include #endif - #ifdef _WIN32 // after an error is returned, GetLastError() result can be passed to this function to get a string // representation of the error on the stack. @@ -286,7 +285,7 @@ static HANDLE get_console_handle(lua_State *L, int flags_optional) luaL_argerror(L, 2, "expected flags"); } - DWORD flags = (DWORD)luaL_checkinteger(L, 2); + LSBF_FLAGTYPE flags = lsbf_checkbitflags(L, 2); if ((flags & ~valid) != 0) { luaL_argerror(L, 2, "invalid flags"); } @@ -294,8 +293,8 @@ static HANDLE get_console_handle(lua_State *L, int flags_optional) return handle; } #else -// first item on the stack should be io.stdin, io.stderr, or io.stdout -// If it returns -1, then it leaves nil+err on the stack +// first item on the stack should be io.stdin, io.stderr, or io.stdout. Throws a +// Lua error if the file is not one of these. static int get_console_handle(lua_State *L) { FILE **file = (FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE); @@ -315,59 +314,8 @@ static int get_console_handle(lua_State *L) -#define SETFLAGS_AS_GIVEN 0 -#define SETFLAGS_ENABLE 1 -#define SETFLAGS_DISABLE 2 - -static int lsti_setconsoleflags(lua_State *L, int setting) -{ -#ifdef _WIN32 - HANDLE console_handle = get_console_handle(L, 0); - if (console_handle == NULL) { - return 2; // error message is already on the stack - } - DWORD flags = (DWORD)lua_tointeger(L, 2); // flags are already validated - - DWORD prev_console_mode; - if (GetConsoleMode(console_handle, &prev_console_mode) == 0) - { - termFormatError(L, GetLastError(), "failed to get console mode"); - return 2; - } - - DWORD new_console_mode = flags; - if (setting == SETFLAGS_DISABLE) { - new_console_mode = prev_console_mode & ~flags; - } else if (setting == SETFLAGS_ENABLE) { - new_console_mode = prev_console_mode | flags; - } - - int success = SetConsoleMode(console_handle, new_console_mode) != 0; - if (!success) - { - termFormatError(L, GetLastError(), "failed to set console mode"); - return 2; - } - - lua_pushinteger(L, prev_console_mode); - lua_pushinteger(L, new_console_mode); - return 2; - -#else - lua_pushinteger(L, 0); - lua_pushinteger(L, 0); - return 2; - -#endif -} - - - /*** -Sets the full set of console flags (Windows). -This sets ALL the flags as given, to enable or disable specific flags without touching -the others use `enableconsoleflags` or `disableconsoleflags`. - +Sets the console flags (Windows). The `CIF_` and `COF_` constants are available on the module table. Where `CIF` are the input flags (for use with `io.stdin`) and `COF` are the output flags (for use with `io.stdout`/`io.stderr`). @@ -378,9 +326,8 @@ Note: not all combinations of flags are allowed, as some are mutually exclusive See [setconsolemode documentation](https://learn.microsoft.com/en-us/windows/console/setconsolemode) @function setconsoleflags @tparam file file the file-handle to set the flags on -@tparam integer bitmask the flags to set/unset -@treturn[1] bitmask the old console flags (always 0 on non-Windows platforms) -@treturn[1] bitmask the new console flags (always 0 on non-Windows platforms) +@tparam bitflags bitflags the flags to set/unset +@treturn[1] boolean `true` on success @treturn[2] nil @treturn[2] string error message @usage @@ -388,85 +335,50 @@ local system = require('system') system.listconsoleflags(io.stdout) -- List all the available flags and their current status local flags = system.getconsoleflags(io.stdout) -local old_flags, new_flags = system.setconsoleflags(io.stdout, - flags | system.COF_VIRTUAL_TERMINAL_PROCESSING) +assert(system.setconsoleflags(io.stdout, + flags + system.COF_VIRTUAL_TERMINAL_PROCESSING) system.listconsoleflags(io.stdout) -- List again to check the differences */ static int lst_setconsoleflags(lua_State *L) { - return lsti_setconsoleflags(L, SETFLAGS_AS_GIVEN); -} - - +#ifdef _WIN32 + HANDLE console_handle = get_console_handle(L, 0); + if (console_handle == NULL) { + return 2; // error message is already on the stack + } + LSBF_FLAGTYPE new_console_mode = lsbf_checkbitflags(L, 2); -/*** -Enables console flags (Windows). -This is similar to `setconsoleflags`, but only enables the given flags, leaving the others -unchanged. To disable specific flags use `disableconsoleflags`. Especially useful when -the Lua version used does not have binary operators (version 5.2 and before). + DWORD prev_console_mode; + if (GetConsoleMode(console_handle, &prev_console_mode) == 0) + { + termFormatError(L, GetLastError(), "failed to get console mode"); + return 2; + } -See `setconsoleflags` for more information on flags and usage. -@function enableconsoleflags -@tparam file file the file-handle to set the flags on -@tparam integer bitmask the flags to set -@treturn[1] bitmask the old console flags (always 0 on non-Windows platforms) -@treturn[1] bitmask the new console flags (always 0 on non-Windows platforms) -@treturn[2] nil -@treturn[2] string error message -@usage -local system = require('system') + int success = SetConsoleMode(console_handle, new_console_mode) != 0; + if (!success) + { + termFormatError(L, GetLastError(), "failed to set console mode"); + return 2; + } -local old_flags, new_flags = system.enableconsoleflags(io.stdout, - system.COF_VIRTUAL_TERMINAL_PROCESSING + system.COF_PROCESSED_OUTPUT) -*/ -static int lst_enableconsoleflags(lua_State *L) -{ - return lsti_setconsoleflags(L, SETFLAGS_ENABLE); +#endif + lua_pushboolean(L, 1); + return 1; } /*** -Disables console flags (Windows). -This is similar to `setconsoleflags`, but only disables the given flags, leaving the others -unchanged. To enable specific flags use `enableconsoleflags`. Especially useful when -the Lua version used does not have binary operators (version 5.2 and before). - -See `setconsoleflags` for more information on flags and usage. - -@function disableconsoleflags -@tparam file file the file-handle to unset the flags on -@tparam integer bitmask the flags to disable -@treturn[1] bitmask the old console flags (always 0 on non-Windows platforms) -@treturn[1] bitmask the new console flags (always 0 on non-Windows platforms) +Gets console flags (Windows). +@function getconsoleflags +@tparam file file the file-handle to get the flags from. +@treturn[1] bitflags the current console flags. @treturn[2] nil @treturn[2] string error message @usage local system = require('system') - -local old_flags, new_flags = system.disableconsoleflags(io.stdout, - system.COF_VIRTUAL_TERMINAL_PROCESSING + system.COF_PROCESSED_OUTPUT) -*/ -static int lst_disableconsoleflags(lua_State *L) -{ - return lsti_setconsoleflags(L, SETFLAGS_DISABLE); -} - - -/*** -Checks console flags (Windows). -Returns the current flags set, or, if a bitmask is provided, checks if all the requested flags are set. - -@function getconsoleflags -@tparam file file the file-handle to check the flags on -@tparam[opt] integer bitmask the flags to check. If not provided, returns the combined current console flags. -@treturn[1] integer the current console flags (if no parameters are passed), always 0 on non-Windows platforms. -@treturn[2] boolean true if all the requested flags are currently set, or false if at least one is not set. Always false on non-Windows platforms. -@treturn[3] nil -@treturn[3] string error message -@usage -local system = require('system') print("Current flags:", system.getconsoleflags(io.stdout)) local set = system.getconsoleflags(io.stdout, system.COF_VIRTUAL_TERMINAL_PROCESSING + system.COF_PROCESSED_OUTPUT) if set then @@ -477,13 +389,14 @@ end */ static int lst_getconsoleflags(lua_State *L) { + DWORD console_mode = 0; + #ifdef _WIN32 HANDLE console_handle = get_console_handle(L, 1); if (console_handle == NULL) { return 2; // error message is already on the stack } - DWORD console_mode; if (GetConsoleMode(console_handle, &console_mode) == 0) { lua_pushnil(L); @@ -491,29 +404,9 @@ static int lst_getconsoleflags(lua_State *L) return 2; } - // If no flag parameters are passed, return the current console flags - if (lua_gettop(L) < 2) - { - lua_pushinteger(L, console_mode); - return 1; - } - - // If parameters are passed, check if the provided flags are currently set - DWORD flags = (DWORD)luaL_checkinteger(L, 2); // flags were already validated - int all_set = (console_mode & flags) == flags; - lua_pushboolean(L, all_set); - return 1; - -#else - if (lua_gettop(L) < 2) - { - lua_pushinteger(L, 0); - return 1; - } - lua_pushboolean(L, 0); - return 1; - #endif + lsbf_pushbitflags(L, console_mode); + return 1; } @@ -538,7 +431,7 @@ The terminal attributes is a table with the following fields: @function tcgetattr @tparam file fd file handle to operate on, one of `io.stdin`, `io.stdout`, `io.stderr` @treturn[1] termios terminal attributes, if successful. On Windows the bitflags are all 0, and the `cc` table is empty. -@return[2] nil +@treturn[2] nil @treturn[2] string error message @treturn[2] int errnum @return error message if failed @@ -556,16 +449,16 @@ static int lst_tcgetattr(lua_State *L) if (r == -1) return pusherror(L, NULL); lua_newtable(L); - lua_pushinteger(L, t.c_iflag); + lsbf_pushbitflags(L, t.c_iflag); lua_setfield(L, -2, "iflag"); - lua_pushinteger(L, t.c_oflag); + lsbf_pushbitflags(L, t.c_oflag); lua_setfield(L, -2, "oflag"); - lua_pushinteger(L, t.c_lflag); + lsbf_pushbitflags(L, t.c_lflag); lua_setfield(L, -2, "lflag"); - lua_pushinteger(L, t.c_cflag); + lsbf_pushbitflags(L, t.c_cflag); lua_setfield(L, -2, "cflag"); lua_pushinteger(L, cfgetispeed(&t)); @@ -585,12 +478,14 @@ static int lst_tcgetattr(lua_State *L) #else lua_newtable(L); - lua_pushinteger(L, 0); + lsbf_pushbitflags(L, 0); lua_setfield(L, -2, "iflag"); - lua_pushinteger(L, 0); + lsbf_pushbitflags(L, 0); lua_setfield(L, -2, "oflag"); - lua_pushinteger(L, 0); + lsbf_pushbitflags(L, 0); lua_setfield(L, -2, "lflag"); + lsbf_pushbitflags(L, 0); + lua_setfield(L, -2, "cflag"); lua_pushinteger(L, 0); lua_setfield(L, -2, "ispeed"); lua_pushinteger(L, 0); @@ -604,60 +499,58 @@ static int lst_tcgetattr(lua_State *L) -static int lsti_tcsetattr(lua_State *L, int setting) +/*** +Set termios state. +This function will set the flags as they are given. If you want to enable or disable +specific flags, use `tcenableattr` or `tcdisableattr`. + +The `I_`, `O_`, and `L_` constants are available on the module table. They are the respective +flags for the `iflags`, `oflags`, and `lflags` bitmasks. + +To see flag status and constant names check `listtermflags`. For their meaning check +[the manpage](https://www.man7.org/linux/man-pages/man3/termios.3.html). + +_Note_: not all combinations of flags are allowed, as some are mutually exclusive or mutually required. +See [setconsolemode documentation](https://learn.microsoft.com/en-us/windows/console/setconsolemode) +@function tcsetattr +@tparam file fd file handle to operate on, one of `io.stdin`, `io.stdout`, `io.stderr` +@int actions one of `TCSANOW`, `TCSADRAIN`, `TCSAFLUSH` +@tparam termios a table with bitflag fields: +@tparam[opt] bitflag termios.iflag if given will set the input flags +@tparam[opt] BitFlag termios.oflag if given will set the output flags +@tparam[opt] bitflag termios.lflag if given will set the local flags +@treturn[1] bool `true`, if successful. Always returns `true` on Windows. +@return[2] nil +@treturn[2] string error message +@treturn[2] int errnum +*/ +static int lst_tcsetattr(lua_State *L) { #ifndef _WIN32 struct termios t; int r, i; - int fd = get_console_handle(L); - int act = luaL_checkinteger(L, 2); - luaL_checktype(L, 3, LUA_TTABLE); + int fd = get_console_handle(L); // first is the console handle + int act = luaL_checkinteger(L, 2); // second is the action to take + luaL_checktype(L, 3, LUA_TTABLE); // third is the termios table with fields r = tcgetattr(fd, &t); if (r == -1) return pusherror(L, NULL); lua_getfield(L, 3, "iflag"); if (!lua_isnil(L, -1)) { - if (!lua_isnumber(L, -1)) { - return luaL_error(L, "iflag must be a number"); - } - if (setting == SETFLAGS_DISABLE) { - t.c_iflag &= ~luaL_checkinteger(L, -1); - } else if (setting == SETFLAGS_ENABLE) { - t.c_iflag |= luaL_checkinteger(L, -1); - } else { - t.c_iflag = luaL_checkinteger(L, -1); - } + t.c_iflag = lsbf_checkbitflags(L, -1); } lua_pop(L, 1); lua_getfield(L, 3, "oflag"); if (!lua_isnil(L, -1)) { - if (!lua_isnumber(L, -1)) { - return luaL_error(L, "oflag must be a number"); - } - if (setting == SETFLAGS_DISABLE) { - t.c_oflag &= ~luaL_checkinteger(L, -1); - } else if (setting == SETFLAGS_ENABLE) { - t.c_oflag |= luaL_checkinteger(L, -1); - } else { - t.c_oflag = luaL_checkinteger(L, -1); - } + t.c_oflag = lsbf_checkbitflags(L, -1); } lua_pop(L, 1); lua_getfield(L, 3, "lflag"); if (!lua_isnil(L, -1)) { - if (!lua_isnumber(L, -1)) { - return luaL_error(L, "lflag must be a number"); - } - if (setting == SETFLAGS_DISABLE) { - t.c_lflag &= ~luaL_checkinteger(L, -1); - } else if (setting == SETFLAGS_ENABLE) { - t.c_lflag |= luaL_checkinteger(L, -1); - } else { - t.c_lflag = luaL_checkinteger(L, -1); - } + t.c_lflag = lsbf_checkbitflags(L, -1); } lua_pop(L, 1); @@ -687,104 +580,12 @@ static int lsti_tcsetattr(lua_State *L, int setting) /*** -Set termios state. -This function will set the flags as they are given. If you want to enable or disable -specific flags, use `tcenableattr` or `tcdisableattr`. - -The `I_`, `O_`, and `L_` constants are available on the module table. They are the respective -flags for the `iflags`, `oflags`, and `lflags` bitmasks. - -To see flag status and constant names check `listtermflags`. For their meaning check -[the manpage](https://www.man7.org/linux/man-pages/man3/termios.3.html). - -_Warning_: some constants have multiple bits set. So most of the time they can be combined by -addition. But for some that won't work and a binary OR is required. Check `listtermflags` output to double check. - -_Note_: not all combinations of flags are allowed, as some are mutually exclusive or mutually required. -See [setconsolemode documentation](https://learn.microsoft.com/en-us/windows/console/setconsolemode) -@function tcsetattr -@tparam file fd file handle to operate on, one of `io.stdin`, `io.stdout`, `io.stderr` -@int actions one of `TCSANOW`, `TCSADRAIN`, `TCSAFLUSH` -@tparam termios a table with optional fields `iflag`, `oflag`, `cflag`, -each formed by `bor` operations with various posix constants. Omitted fields -will not be changed. -@treturn[1] bool `true`, if successful. Always returns `true` on Windows. -@return[2] nil -@treturn[2] string error message -@treturn[2] int errnum -*/ -static int lst_tcsetattr(lua_State *L) -{ - return lsti_tcsetattr(L, SETFLAGS_AS_GIVEN); -} - - -/*** -Set termios flags. -This function will enable the given flags only, not changing the others. If you -want to set the flags as they are given, use `tcsetattr`. -@function tcenableattr -@tparam file fd file handle to operate on, one of `io.stdin`, `io.stdout`, `io.stderr` -@int actions one of `TCSANOW`, `TCSADRAIN`, `TCSAFLUSH` -@tparam termios a table with optional fields `iflag`, `oflag`, `cflag`, -each formed by `bor` operations with various posix constants. Omitted fields -will not be changed. -@treturn[1] bool `true`, if successful. Always returns `true` on Windows. -@return[2] nil -@treturn[2] string error message -@treturn[2] int errnum -*/ -static int lst_tcenableattr(lua_State *L) -{ - return lsti_tcsetattr(L, SETFLAGS_ENABLE); -} - - -/*** -Clear termios flags. -This function will disable the given flags only, not changing the others. If you -want to set the flags as they are given, use `tcsetattr`. -@function tcdisableattr -@tparam file fd file handle to operate on, one of `io.stdin`, `io.stdout`, `io.stderr` -@int actions one of `TCSANOW`, `TCSADRAIN`, `TCSAFLUSH` -@tparam termios a table with optional fields `iflag`, `oflag`, `cflag`, -each formed by `bor` operations with various posix constants. Omitted fields -will not be changed. -@treturn[1] bool `true`, if successful. Always returns `true` on Windows. -@return[2] nil -@treturn[2] string error message -@treturn[2] int errnum -@usage -local system = require('system') -assert(system.tcdisableattr(io.stdin, system.TCSANOW, { - lflag = system.L_ICANON + system.L_ECHO, -})) -assert(system.setnonblock(io.stdin)) - -print "press any key to continue..." -system.readkey() - -assert(system.setblock(io.stdin)) -assert(system.tcenableattr(io.stdin, system.TCSANOW, { - lflag = system.L_ICANON + system.L_ECHO, -})) - - -*/ -static int lst_tcdisableattr(lua_State *L) -{ - return lsti_tcsetattr(L, SETFLAGS_DISABLE); -} - - - -/*** -Sets file in non-blocking mode. -See `tcdisableattr` for an example of usage. +Enables or disable non-blocking mode for a file. @function setnonblock @tparam file fd file handle to operate on, one of `io.stdin`, `io.stdout`, `io.stderr` +@tparam boolean make_non_block a truthy value will enable non-blocking mode, a falsy value will disable it. @treturn[1] bool `true`, if successful -@return[2] nil +@treturn[2] nil @treturn[2] string error message @treturn[2] int errnum @see setblock @@ -795,13 +596,19 @@ static int lst_setnonblock(lua_State *L) int fd = get_console_handle(L); - // Set O_NONBLOCK int flags = fcntl(fd, F_GETFL, 0); if (flags == -1) { return pusherror(L, "Error getting handle flags: "); } - if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { - return pusherror(L, "Error setting O_NONBLOCK: "); + if (lua_toboolean(L, 2)) { + // truthy: set non-blocking + flags |= O_NONBLOCK; + } else { + // falsy: set disable non-blocking + flags &= ~O_NONBLOCK; + } + if (fcntl(fd, F_SETFL, flags) == -1) { + return pusherror(L, "Error changing O_NONBLOCK: "); } #endif @@ -813,39 +620,38 @@ static int lst_setnonblock(lua_State *L) /*** -Sets file in blocking mode. -See `tcdisableattr` for an example of usage. -@function setblock +Gets non-blocking mode status for a file. +@function getnonblock @tparam file fd file handle to operate on, one of `io.stdin`, `io.stdout`, `io.stderr` -@treturn[1] bool `true`, if successful -@return[2] nil +@treturn[1] bool `true` if set to non-blocking, `false` if not. Always returns `false` on Windows. +@treturn[2] nil @treturn[2] string error message @treturn[2] int errnum -@see setnonblock */ -static int lst_setblock(lua_State *L) +static int lst_getnonblock(lua_State *L) { #ifndef _WIN32 int fd = get_console_handle(L); - // Unset O_NONBLOCK + // Set O_NONBLOCK int flags = fcntl(fd, F_GETFL, 0); if (flags == -1) { return pusherror(L, "Error getting handle flags: "); } - if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1) { - return pusherror(L, "Error unsetting O_NONBLOCK: "); + if (flags & O_NONBLOCK) { + lua_pushboolean(L, 1); + } else { + lua_pushboolean(L, 0); } -#endif +#else + lua_pushboolean(L, 0); - lua_pushboolean(L, 1); +#endif return 1; } - - /*------------------------------------------------------------------------- * backup/restore terminal state *-------------------------------------------------------------------------*/ @@ -1051,16 +857,12 @@ static int lst_keypressed(lua_State *L) { static luaL_Reg func[] = { { "isatty", lst_isatty }, - { "enableconsoleflags", lst_enableconsoleflags }, - { "disableconsoleflags", lst_disableconsoleflags }, { "getconsoleflags", lst_getconsoleflags }, { "setconsoleflags", lst_setconsoleflags }, { "tcgetattr", lst_tcgetattr }, { "tcsetattr", lst_tcsetattr }, - { "tcenableattr", lst_tcenableattr }, - { "tcdisableattr", lst_tcdisableattr }, + { "getnonblock", lst_setnonblock }, { "setnonblock", lst_setnonblock }, - { "setblock", lst_setblock }, { "termbackup", lst_termbackup }, { "termrestore", lst_termrestore }, { "readkey", lst_readkey }, @@ -1076,28 +878,28 @@ void term_open(lua_State *L) { // Windows flags for (int i = 0; win_console_in_flags[i].name != NULL; i++) { - lua_pushinteger(L, win_console_in_flags[i].value); + lsbf_pushbitflags(L, win_console_in_flags[i].value); lua_setfield(L, -2, win_console_in_flags[i].name); } for (int i = 0; win_console_out_flags[i].name != NULL; i++) { - lua_pushinteger(L, win_console_out_flags[i].value); + lsbf_pushbitflags(L, win_console_out_flags[i].value); lua_setfield(L, -2, win_console_out_flags[i].name); } // Unix flags for (int i = 0; nix_console_i_flags[i].name != NULL; i++) { - lua_pushinteger(L, nix_console_i_flags[i].value); + lsbf_pushbitflags(L, nix_console_i_flags[i].value); lua_setfield(L, -2, nix_console_i_flags[i].name); } for (int i = 0; nix_console_o_flags[i].name != NULL; i++) { - lua_pushinteger(L, nix_console_o_flags[i].value); + lsbf_pushbitflags(L, nix_console_o_flags[i].value); lua_setfield(L, -2, nix_console_o_flags[i].name); } for (int i = 0; nix_console_l_flags[i].name != NULL; i++) { - lua_pushinteger(L, nix_console_l_flags[i].value); + lsbf_pushbitflags(L, nix_console_l_flags[i].value); lua_setfield(L, -2, nix_console_l_flags[i].name); } // Unix tcsetattr actions