aboutsummaryrefslogtreecommitdiff
path: root/src/serial.c
diff options
context:
space:
mode:
authorSam Roberts <vieuxtech@gmail.com>2012-04-11 14:18:20 -0700
committerSam Roberts <vieuxtech@gmail.com>2012-04-11 14:18:20 -0700
commit4b671f4551e98ac9e1d9a7407d3dffdd7eb1d3dc (patch)
treeba92aa753ae1b145760cb1c5e69c886d3bf11328 /src/serial.c
parentf399ab25fcecad2ff96a5977e8eaf069bb45473c (diff)
parent195b2a74bb3f368b1f31f9c8bbc1ce0f54de2035 (diff)
downloadluasocket-4b671f4551e98ac9e1d9a7407d3dffdd7eb1d3dc.tar.gz
luasocket-4b671f4551e98ac9e1d9a7407d3dffdd7eb1d3dc.tar.bz2
luasocket-4b671f4551e98ac9e1d9a7407d3dffdd7eb1d3dc.zip
Merge branch 'git-sam' into diego-sam-mwild-integration
Conflicts in options.c were just due to independent small functions being close to each other. unix.c in mwild was broken, it wasn't using LUASOCKET_API. serial.c needed luaL_reg renamed, and to use LUASOCKET_API. makefile didn't respect standard DESTDIR and prefix makefile variables, and didn't allow LUAV variable to select lua version to build against. I've tested the top-level install-both target builds and installs against both lua5.1 and lua5.2, but not done further testing. Conflicts: README config gem/ltn012.tex makefile src/makefile src/options.c src/options.h src/tcp.c src/usocket.c
Diffstat (limited to 'src/serial.c')
-rw-r--r--src/serial.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/serial.c b/src/serial.c
new file mode 100644
index 0000000..5b09e76
--- /dev/null
+++ b/src/serial.c
@@ -0,0 +1,183 @@
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/*
17Reuses userdata definition from unix.h, since it is useful for all
18stream-like objects.
19
20If we stored the serial path for use in error messages or userdata
21printing, we might need our own userdata definition.
22
23Group usage is semi-inherited from unix.c, but unnecessary since we
24have only one object type.
25*/
26
27/*=========================================================================*\
28* Internal function prototypes
29\*=========================================================================*/
30static int global_create(lua_State *L);
31static int meth_send(lua_State *L);
32static int meth_receive(lua_State *L);
33static int meth_close(lua_State *L);
34static int meth_settimeout(lua_State *L);
35static int meth_getfd(lua_State *L);
36static int meth_setfd(lua_State *L);
37static int meth_dirty(lua_State *L);
38static int meth_getstats(lua_State *L);
39static int meth_setstats(lua_State *L);
40
41/* serial object methods */
42static 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/* our socket creation function */
58static luaL_Reg func[] = {
59 {"serial", global_create},
60 {NULL, NULL}
61};
62
63
64/*-------------------------------------------------------------------------*\
65* Initializes module
66\*-------------------------------------------------------------------------*/
67LUASOCKET_API int luaopen_socket_serial(lua_State *L) {
68 /* create classes */
69 auxiliar_newclass(L, "serial{client}", serial_methods);
70 /* create class groups */
71 auxiliar_add2group(L, "serial{client}", "serial{any}");
72 /* make sure the function ends up in the package table */
73 luaL_openlib(L, "socket", func, 0);
74 /* return the function instead of the 'socket' table */
75 lua_pushstring(L, "serial");
76 lua_gettable(L, -2);
77 return 1;
78}
79
80/*=========================================================================*\
81* Lua methods
82\*=========================================================================*/
83/*-------------------------------------------------------------------------*\
84* Just call buffered IO methods
85\*-------------------------------------------------------------------------*/
86static int meth_send(lua_State *L) {
87 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
88 return buffer_meth_send(L, &un->buf);
89}
90
91static int meth_receive(lua_State *L) {
92 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
93 return buffer_meth_receive(L, &un->buf);
94}
95
96static int meth_getstats(lua_State *L) {
97 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
98 return buffer_meth_getstats(L, &un->buf);
99}
100
101static int meth_setstats(lua_State *L) {
102 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
103 return buffer_meth_setstats(L, &un->buf);
104}
105
106/*-------------------------------------------------------------------------*\
107* Select support methods
108\*-------------------------------------------------------------------------*/
109static int meth_getfd(lua_State *L) {
110 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
111 lua_pushnumber(L, (int) un->sock);
112 return 1;
113}
114
115/* this is very dangerous, but can be handy for those that are brave enough */
116static int meth_setfd(lua_State *L) {
117 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
118 un->sock = (t_socket) luaL_checknumber(L, 2);
119 return 0;
120}
121
122static int meth_dirty(lua_State *L) {
123 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
124 lua_pushboolean(L, !buffer_isempty(&un->buf));
125 return 1;
126}
127
128/*-------------------------------------------------------------------------*\
129* Closes socket used by object
130\*-------------------------------------------------------------------------*/
131static int meth_close(lua_State *L)
132{
133 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
134 socket_destroy(&un->sock);
135 lua_pushnumber(L, 1);
136 return 1;
137}
138
139
140/*-------------------------------------------------------------------------*\
141* Just call tm methods
142\*-------------------------------------------------------------------------*/
143static int meth_settimeout(lua_State *L) {
144 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
145 return timeout_meth_settimeout(L, &un->tm);
146}
147
148/*=========================================================================*\
149* Library functions
150\*=========================================================================*/
151
152
153/*-------------------------------------------------------------------------*\
154* Creates a serial object
155\*-------------------------------------------------------------------------*/
156static int global_create(lua_State *L) {
157 const char* path = luaL_checkstring(L, 1);
158
159 /* allocate unix object */
160 p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix));
161
162 /* open serial device */
163 t_socket sock = open(path, O_NOCTTY|O_RDWR);
164
165 /*printf("open %s on %d\n", path, sock);*/
166
167 if (sock < 0) {
168 lua_pushnil(L);
169 lua_pushstring(L, socket_strerror(errno));
170 lua_pushnumber(L, errno);
171 return 3;
172 }
173 /* set its type as client object */
174 auxiliar_setclass(L, "serial{client}", -1);
175 /* initialize remaining structure fields */
176 socket_setnonblocking(&sock);
177 un->sock = sock;
178 io_init(&un->io, (p_send) socket_write, (p_recv) socket_read,
179 (p_error) socket_ioerror, &un->sock);
180 timeout_init(&un->tm, -1, -1);
181 buffer_init(&un->buf, &un->io, &un->tm);
182 return 1;
183}