/* * gcsd * * gcsd the generic command sequencer daemon can be used to serialize * commands sent over various paralell communication channels to a * single command output. It can be seen as a multiplexer for any * kind of communication between a single resource and various clients * which want to submit commands to it or query information from it. * gcsd is written in C and Lua. The goal is to provide an easy to * understand high level API based on Lua which can be used to * implement the business logic of the so formed multiplexer daemon. * * * Copyright (C) 2009-2010 Markus Grueneis * Christian Pointner * * This file is part of gcsd. * * gcsd is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * gcsd is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with gcsd. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "l_rawio.h" static int l_rawio_open(lua_State *L) { const char* filename = luaL_checkstring(L,1); const char* mode_str = luaL_checkstring(L,2); int mode = 0; if(strstr(mode_str, "O_RDONLY")) mode |= O_RDONLY; if(strstr(mode_str, "O_WRONLY")) mode |= O_WRONLY; if(strstr(mode_str, "O_RDWR")) mode |= O_RDWR; int fd = open(filename, mode); lua_pushinteger(L, fd); return 1; } static int l_rawio_setnonblock(lua_State *L) { int fd = luaL_checkint(L,1); int ret = fcntl(fd, F_SETFL, O_NONBLOCK); if(ret == -1) { lua_pushnil(L); // FIXXXXXME: strerror is not threadsafe!!! lua_pushstring(L, strerror(errno)); return 2; } lua_pushboolean(L, 1); return 1; } static int l_rawio_write(lua_State *L) { int fd = luaL_checkint(L,1); size_t len = 0; const char* data = luaL_checklstring(L, 2, &len); int ret = write(fd, data, len); if(ret == -1) { lua_pushnil(L); // FIXXXXXME: strerror is not threadsafe!!! lua_pushstring(L, strerror(errno)); return 2; } lua_pushinteger(L, ret); return 1; } static int l_rawio_read(lua_State *L) { int fd = luaL_checkint(L,1); size_t len = luaL_checkint(L,2); char* data = malloc(len); if(!data) { lua_pushnil(L); lua_pushstring(L, "bad alloc"); return 2; } int ret = read(fd, data, len); if(ret == -1) { lua_pushnil(L); // FIXXXXXME: strerror is not threadsafe!!! lua_pushstring(L, strerror(errno)); free(data); return 2; } lua_pushlstring(L, data, ret); free(data); return 1; } static int l_rawio_close(lua_State *L) { close(luaL_checkint(L,1)); return 0; } static const struct luaL_Reg rawio_funcs [] = { { "open", l_rawio_open }, { "setnonblock", l_rawio_setnonblock }, { "write", l_rawio_write }, { "read", l_rawio_read }, { "close", l_rawio_close }, { NULL, NULL } }; LUALIB_API int luaopen_rawio(lua_State *L) { #if LUA_VERSION_NUM > 501 lua_newtable(L); luaL_setfuncs(L, rawio_funcs, 0); lua_pushvalue(L, -1); lua_setglobal(L, LUA_RAWIOLIBNAME); #else luaL_register(L, LUA_RAWIOLIBNAME, rawio_funcs); #endif return 1; }