summaryrefslogtreecommitdiff
path: root/source/luametatex/source/luacore/luasocket/src/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/luametatex/source/luacore/luasocket/src/serial.c')
-rw-r--r--source/luametatex/source/luacore/luasocket/src/serial.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/source/luametatex/source/luacore/luasocket/src/serial.c b/source/luametatex/source/luacore/luasocket/src/serial.c
new file mode 100644
index 000000000..21485d3e2
--- /dev/null
+++ b/source/luametatex/source/luacore/luasocket/src/serial.c
@@ -0,0 +1,171 @@
+/*=========================================================================*\
+* Serial stream
+* LuaSocket toolkit
+\*=========================================================================*/
+#include "luasocket.h"
+
+#include "auxiliar.h"
+#include "socket.h"
+#include "options.h"
+#include "unix.h"
+
+#include <string.h>
+#include <sys/un.h>
+
+/*
+Reuses userdata definition from unix.h, since it is useful for all
+stream-like objects.
+
+If we stored the serial path for use in error messages or userdata
+printing, we might need our own userdata definition.
+
+Group usage is semi-inherited from unix.c, but unnecessary since we
+have only one object type.
+*/
+
+/*=========================================================================*\
+* Internal function prototypes
+\*=========================================================================*/
+static int global_create(lua_State *L);
+static int meth_send(lua_State *L);
+static int meth_receive(lua_State *L);
+static int meth_close(lua_State *L);
+static int meth_settimeout(lua_State *L);
+static int meth_getfd(lua_State *L);
+static int meth_setfd(lua_State *L);
+static int meth_dirty(lua_State *L);
+static int meth_getstats(lua_State *L);
+static int meth_setstats(lua_State *L);
+
+/* serial object methods */
+static luaL_Reg serial_methods[] = {
+ {"__gc", meth_close},
+ {"__tostring", auxiliar_tostring},
+ {"close", meth_close},
+ {"dirty", meth_dirty},
+ {"getfd", meth_getfd},
+ {"getstats", meth_getstats},
+ {"setstats", meth_setstats},
+ {"receive", meth_receive},
+ {"send", meth_send},
+ {"setfd", meth_setfd},
+ {"settimeout", meth_settimeout},
+ {NULL, NULL}
+};
+
+/*-------------------------------------------------------------------------*\
+* Initializes module
+\*-------------------------------------------------------------------------*/
+LUASOCKET_API int luaopen_socket_serial(lua_State *L) {
+ /* create classes */
+ auxiliar_newclass(L, "serial{client}", serial_methods);
+ /* create class groups */
+ auxiliar_add2group(L, "serial{client}", "serial{any}");
+ lua_pushcfunction(L, global_create);
+ return 1;
+}
+
+/*=========================================================================*\
+* Lua methods
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Just call buffered IO methods
+\*-------------------------------------------------------------------------*/
+static int meth_send(lua_State *L) {
+ p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
+ return buffer_meth_send(L, &un->buf);
+}
+
+static int meth_receive(lua_State *L) {
+ p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
+ return buffer_meth_receive(L, &un->buf);
+}
+
+static int meth_getstats(lua_State *L) {
+ p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
+ return buffer_meth_getstats(L, &un->buf);
+}
+
+static int meth_setstats(lua_State *L) {
+ p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
+ return buffer_meth_setstats(L, &un->buf);
+}
+
+/*-------------------------------------------------------------------------*\
+* Select support methods
+\*-------------------------------------------------------------------------*/
+static int meth_getfd(lua_State *L) {
+ p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
+ lua_pushnumber(L, (int) un->sock);
+ return 1;
+}
+
+/* this is very dangerous, but can be handy for those that are brave enough */
+static int meth_setfd(lua_State *L) {
+ p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
+ un->sock = (t_socket) luaL_checknumber(L, 2);
+ return 0;
+}
+
+static int meth_dirty(lua_State *L) {
+ p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
+ lua_pushboolean(L, !buffer_isempty(&un->buf));
+ return 1;
+}
+
+/*-------------------------------------------------------------------------*\
+* Closes socket used by object
+\*-------------------------------------------------------------------------*/
+static int meth_close(lua_State *L)
+{
+ p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
+ socket_destroy(&un->sock);
+ lua_pushnumber(L, 1);
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------*\
+* Just call tm methods
+\*-------------------------------------------------------------------------*/
+static int meth_settimeout(lua_State *L) {
+ p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
+ return timeout_meth_settimeout(L, &un->tm);
+}
+
+/*=========================================================================*\
+* Library functions
+\*=========================================================================*/
+
+
+/*-------------------------------------------------------------------------*\
+* Creates a serial object
+\*-------------------------------------------------------------------------*/
+static int global_create(lua_State *L) {
+ const char* path = luaL_checkstring(L, 1);
+
+ /* allocate unix object */
+ p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix));
+
+ /* open serial device */
+ t_socket sock = open(path, O_NOCTTY|O_RDWR);
+
+ /*printf("open %s on %d\n", path, sock);*/
+
+ if (sock < 0) {
+ lua_pushnil(L);
+ lua_pushstring(L, socket_strerror(errno));
+ lua_pushnumber(L, errno);
+ return 3;
+ }
+ /* set its type as client object */
+ auxiliar_setclass(L, "serial{client}", -1);
+ /* initialize remaining structure fields */
+ socket_setnonblocking(&sock);
+ un->sock = sock;
+ io_init(&un->io, (p_send) socket_write, (p_recv) socket_read,
+ (p_error) socket_ioerror, &un->sock);
+ timeout_init(&un->tm, -1, -1);
+ buffer_init(&un->buf, &un->io, &un->tm);
+ return 1;
+}