1 /*=========================================================================*\
2 * Serial stream
3 * LuaSocket toolkit
4 \*=========================================================================*/
5 #include <string.h>
6
7 #include "lua.h"
8 #include "lauxlib.h"
9
10 #include "auxiliar.h"
11 #include "socket.h"
12 #include "options.h"
13 #include "unix.h"
14 #include <sys/un.h>
15
16 /*
17 Reuses userdata definition from unix.h, since it is useful for all
18 stream-like objects.
19
20 If we stored the serial path for use in error messages or userdata
21 printing, we might need our own userdata definition.
22
23 Group usage is semi-inherited from unix.c, but unnecessary since we
24 have only one object type.
25 */
26
27 /*=========================================================================*\
28 * Internal function prototypes
29 \*=========================================================================*/
30 static int global_create(lua_State *L);
31 static int meth_send(lua_State *L);
32 static int meth_receive(lua_State *L);
33 static int meth_close(lua_State *L);
34 static int meth_settimeout(lua_State *L);
35 static int meth_getfd(lua_State *L);
36 static int meth_setfd(lua_State *L);
37 static int meth_dirty(lua_State *L);
38 static int meth_getstats(lua_State *L);
39 static int meth_setstats(lua_State *L);
40
41 /* serial object methods */
42 static luaL_Reg serial_methods[] = {
43 {"__gc", meth_close},
44 {"__tostring", auxiliar_tostring},
45 {"close", meth_close},
46 {"dirty", meth_dirty},
47 {"getfd", meth_getfd},
48 {"getstats", meth_getstats},
49 {"setstats", meth_setstats},
50 {"receive", meth_receive},
51 {"send", meth_send},
52 {"setfd", meth_setfd},
53 {"settimeout", meth_settimeout},
54 {NULL, NULL}
55 };
56
57 /*-------------------------------------------------------------------------*\
58 * Initializes module
59 \*-------------------------------------------------------------------------*/
luaopen_socket_serial(lua_State * L)60 LUASOCKET_API int luaopen_socket_serial(lua_State *L) {
61 /* create classes */
62 auxiliar_newclass(L, "serial{client}", serial_methods);
63 /* create class groups */
64 auxiliar_add2group(L, "serial{client}", "serial{any}");
65 lua_pushcfunction(L, global_create);
66 return 1;
67 }
68
69 /*=========================================================================*\
70 * Lua methods
71 \*=========================================================================*/
72 /*-------------------------------------------------------------------------*\
73 * Just call buffered IO methods
74 \*-------------------------------------------------------------------------*/
meth_send(lua_State * L)75 static int meth_send(lua_State *L) {
76 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
77 return buffer_meth_send(L, &un->buf);
78 }
79
meth_receive(lua_State * L)80 static int meth_receive(lua_State *L) {
81 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
82 return buffer_meth_receive(L, &un->buf);
83 }
84
meth_getstats(lua_State * L)85 static int meth_getstats(lua_State *L) {
86 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
87 return buffer_meth_getstats(L, &un->buf);
88 }
89
meth_setstats(lua_State * L)90 static int meth_setstats(lua_State *L) {
91 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
92 return buffer_meth_setstats(L, &un->buf);
93 }
94
95 /*-------------------------------------------------------------------------*\
96 * Select support methods
97 \*-------------------------------------------------------------------------*/
meth_getfd(lua_State * L)98 static int meth_getfd(lua_State *L) {
99 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
100 lua_pushnumber(L, (int) un->sock);
101 return 1;
102 }
103
104 /* this is very dangerous, but can be handy for those that are brave enough */
meth_setfd(lua_State * L)105 static int meth_setfd(lua_State *L) {
106 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
107 un->sock = (t_socket) luaL_checknumber(L, 2);
108 return 0;
109 }
110
meth_dirty(lua_State * L)111 static int meth_dirty(lua_State *L) {
112 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
113 lua_pushboolean(L, !buffer_isempty(&un->buf));
114 return 1;
115 }
116
117 /*-------------------------------------------------------------------------*\
118 * Closes socket used by object
119 \*-------------------------------------------------------------------------*/
meth_close(lua_State * L)120 static int meth_close(lua_State *L)
121 {
122 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
123 socket_destroy(&un->sock);
124 lua_pushnumber(L, 1);
125 return 1;
126 }
127
128
129 /*-------------------------------------------------------------------------*\
130 * Just call tm methods
131 \*-------------------------------------------------------------------------*/
meth_settimeout(lua_State * L)132 static int meth_settimeout(lua_State *L) {
133 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
134 return timeout_meth_settimeout(L, &un->tm);
135 }
136
137 /*=========================================================================*\
138 * Library functions
139 \*=========================================================================*/
140
141
142 /*-------------------------------------------------------------------------*\
143 * Creates a serial object
144 \*-------------------------------------------------------------------------*/
global_create(lua_State * L)145 static int global_create(lua_State *L) {
146 const char* path = luaL_checkstring(L, 1);
147
148 /* allocate unix object */
149 p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix));
150
151 /* open serial device */
152 t_socket sock = open(path, O_NOCTTY|O_RDWR);
153
154 /*printf("open %s on %d\n", path, sock);*/
155
156 if (sock < 0) {
157 lua_pushnil(L);
158 lua_pushstring(L, socket_strerror(errno));
159 lua_pushnumber(L, errno);
160 return 3;
161 }
162 /* set its type as client object */
163 auxiliar_setclass(L, "serial{client}", -1);
164 /* initialize remaining structure fields */
165 socket_setnonblocking(&sock);
166 un->sock = sock;
167 io_init(&un->io, (p_send) socket_write, (p_recv) socket_read,
168 (p_error) socket_ioerror, &un->sock);
169 timeout_init(&un->tm, -1, -1);
170 buffer_init(&un->buf, &un->io, &un->tm);
171 return 1;
172 }
173