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