~ubuntu-branches/ubuntu/intrepid/luatex/intrepid

« back to all changes in this revision

Viewing changes to src/libs/luasocket/src/tcp.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2008-07-07 11:01:13 UTC
  • mfrom: (1.1.5 upstream) (4.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080707110113-1y7lam37zbbb7bbt
Tags: 0.28.0-1
* two new upstream releases, see the respective ANNOUCE files
* add luasocket license statement to debian/copyright
* activate the pdfluatex format
* prepare for latex based formats
  - add the ini files from TeX Live
  - add debian/formats file
  - adjust dh_installtex incantation
  the problem is that luatex dies when loading ukrhypmp.tex from 
  texlive-lang-cyrillic, but we don't want to conflict with it by now.
* policy 3.8.0, rename README.Debian-source to README.source, and add
  notes about quilt usage
* disable patch fix-pwd-inclusion (it was from svn)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=========================================================================*\
 
2
* TCP object 
 
3
* LuaSocket toolkit
 
4
*
 
5
* RCS ID: $Id: tcp.c,v 1.41 2005/10/07 04:40:59 diego Exp $
 
6
\*=========================================================================*/
 
7
#include <string.h> 
 
8
 
 
9
#include "lua.h"
 
10
#include "lauxlib.h"
 
11
 
 
12
#include "auxiliar.h"
 
13
#include "socket.h"
 
14
#include "inet.h"
 
15
#include "options.h"
 
16
#include "tcp.h"
 
17
 
 
18
/*=========================================================================*\
 
19
* Internal function prototypes
 
20
\*=========================================================================*/
 
21
static int global_create(lua_State *L);
 
22
static int meth_connect(lua_State *L);
 
23
static int meth_listen(lua_State *L);
 
24
static int meth_bind(lua_State *L);
 
25
static int meth_send(lua_State *L);
 
26
static int meth_getstats(lua_State *L);
 
27
static int meth_setstats(lua_State *L);
 
28
static int meth_getsockname(lua_State *L);
 
29
static int meth_getpeername(lua_State *L);
 
30
static int meth_shutdown(lua_State *L);
 
31
static int meth_receive(lua_State *L);
 
32
static int meth_accept(lua_State *L);
 
33
static int meth_close(lua_State *L);
 
34
static int meth_setoption(lua_State *L);
 
35
static int meth_settimeout(lua_State *L);
 
36
static int meth_getfd(lua_State *L);
 
37
static int meth_setfd(lua_State *L);
 
38
static int meth_dirty(lua_State *L);
 
39
 
 
40
/* tcp object methods */
 
41
static luaL_reg tcp[] = {
 
42
    {"__gc",        meth_close},
 
43
    {"__tostring",  auxiliar_tostring},
 
44
    {"accept",      meth_accept},
 
45
    {"bind",        meth_bind},
 
46
    {"close",       meth_close},
 
47
    {"connect",     meth_connect},
 
48
    {"dirty",       meth_dirty},
 
49
    {"getfd",       meth_getfd},
 
50
    {"getpeername", meth_getpeername},
 
51
    {"getsockname", meth_getsockname},
 
52
    {"getstats",    meth_getstats},
 
53
    {"setstats",    meth_setstats},
 
54
    {"listen",      meth_listen},
 
55
    {"receive",     meth_receive},
 
56
    {"send",        meth_send},
 
57
    {"setfd",       meth_setfd},
 
58
    {"setoption",   meth_setoption},
 
59
    {"setpeername", meth_connect},
 
60
    {"setsockname", meth_bind},
 
61
    {"settimeout",  meth_settimeout},
 
62
    {"shutdown",    meth_shutdown},
 
63
    {NULL,          NULL}
 
64
};
 
65
 
 
66
/* socket option handlers */
 
67
static t_opt opt[] = {
 
68
    {"keepalive",   opt_keepalive},
 
69
    {"reuseaddr",   opt_reuseaddr},
 
70
    {"tcp-nodelay", opt_tcp_nodelay},
 
71
    {"linger",      opt_linger},
 
72
    {NULL,          NULL}
 
73
};
 
74
 
 
75
/* functions in library namespace */
 
76
static luaL_reg func[] = {
 
77
    {"tcp", global_create},
 
78
    {NULL, NULL}
 
79
};
 
80
 
 
81
/*-------------------------------------------------------------------------*\
 
82
* Initializes module
 
83
\*-------------------------------------------------------------------------*/
 
84
int tcp_open(lua_State *L)
 
85
{
 
86
    /* create classes */
 
87
    auxiliar_newclass(L, "tcp{master}", tcp);
 
88
    auxiliar_newclass(L, "tcp{client}", tcp);
 
89
    auxiliar_newclass(L, "tcp{server}", tcp);
 
90
    /* create class groups */
 
91
    auxiliar_add2group(L, "tcp{master}", "tcp{any}");
 
92
    auxiliar_add2group(L, "tcp{client}", "tcp{any}");
 
93
    auxiliar_add2group(L, "tcp{server}", "tcp{any}");
 
94
    /* define library functions */
 
95
    luaL_openlib(L, NULL, func, 0); 
 
96
    return 0;
 
97
}
 
98
 
 
99
/*=========================================================================*\
 
100
* Lua methods
 
101
\*=========================================================================*/
 
102
/*-------------------------------------------------------------------------*\
 
103
* Just call buffered IO methods
 
104
\*-------------------------------------------------------------------------*/
 
105
static int meth_send(lua_State *L) {
 
106
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
 
107
    return buffer_meth_send(L, &tcp->buf);
 
108
}
 
109
 
 
110
static int meth_receive(lua_State *L) {
 
111
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
 
112
    return buffer_meth_receive(L, &tcp->buf);
 
113
}
 
114
 
 
115
static int meth_getstats(lua_State *L) {
 
116
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
 
117
    return buffer_meth_getstats(L, &tcp->buf);
 
118
}
 
119
 
 
120
static int meth_setstats(lua_State *L) {
 
121
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
 
122
    return buffer_meth_setstats(L, &tcp->buf);
 
123
}
 
124
 
 
125
/*-------------------------------------------------------------------------*\
 
126
* Just call option handler
 
127
\*-------------------------------------------------------------------------*/
 
128
static int meth_setoption(lua_State *L)
 
129
{
 
130
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
131
    return opt_meth_setoption(L, opt, &tcp->sock);
 
132
}
 
133
 
 
134
/*-------------------------------------------------------------------------*\
 
135
* Select support methods
 
136
\*-------------------------------------------------------------------------*/
 
137
static int meth_getfd(lua_State *L)
 
138
{
 
139
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
140
    lua_pushnumber(L, (int) tcp->sock);
 
141
    return 1;
 
142
}
 
143
 
 
144
/* this is very dangerous, but can be handy for those that are brave enough */
 
145
static int meth_setfd(lua_State *L)
 
146
{
 
147
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
148
    tcp->sock = (t_socket) luaL_checknumber(L, 2); 
 
149
    return 0;
 
150
}
 
151
 
 
152
static int meth_dirty(lua_State *L)
 
153
{
 
154
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
155
    lua_pushboolean(L, !buffer_isempty(&tcp->buf));
 
156
    return 1;
 
157
}
 
158
 
 
159
/*-------------------------------------------------------------------------*\
 
160
* Waits for and returns a client object attempting connection to the 
 
161
* server object 
 
162
\*-------------------------------------------------------------------------*/
 
163
static int meth_accept(lua_State *L)
 
164
{
 
165
    p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1);
 
166
    p_timeout tm = timeout_markstart(&server->tm);
 
167
    t_socket sock;
 
168
    int err = socket_accept(&server->sock, &sock, NULL, NULL, tm);
 
169
    /* if successful, push client socket */
 
170
    if (err == IO_DONE) {
 
171
        p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
 
172
        auxiliar_setclass(L, "tcp{client}", -1);
 
173
        /* initialize structure fields */
 
174
        socket_setnonblocking(&sock);
 
175
        clnt->sock = sock;
 
176
        io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, 
 
177
                (p_error) socket_ioerror, &clnt->sock);
 
178
        timeout_init(&clnt->tm, -1, -1);
 
179
        buffer_init(&clnt->buf, &clnt->io, &clnt->tm);
 
180
        return 1;
 
181
    } else {
 
182
        lua_pushnil(L); 
 
183
        lua_pushstring(L, socket_strerror(err));
 
184
        return 2;
 
185
    }
 
186
}
 
187
 
 
188
/*-------------------------------------------------------------------------*\
 
189
* Binds an object to an address 
 
190
\*-------------------------------------------------------------------------*/
 
191
static int meth_bind(lua_State *L)
 
192
{
 
193
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1);
 
194
    const char *address =  luaL_checkstring(L, 2);
 
195
    unsigned short port = (unsigned short) luaL_checknumber(L, 3);
 
196
    const char *err = inet_trybind(&tcp->sock, address, port);
 
197
    if (err) {
 
198
        lua_pushnil(L);
 
199
        lua_pushstring(L, err);
 
200
        return 2;
 
201
    }
 
202
    lua_pushnumber(L, 1);
 
203
    return 1;
 
204
}
 
205
 
 
206
/*-------------------------------------------------------------------------*\
 
207
* Turns a master tcp object into a client object.
 
208
\*-------------------------------------------------------------------------*/
 
209
static int meth_connect(lua_State *L)
 
210
{
 
211
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
212
    const char *address =  luaL_checkstring(L, 2);
 
213
    unsigned short port = (unsigned short) luaL_checknumber(L, 3);
 
214
    p_timeout tm = timeout_markstart(&tcp->tm);
 
215
    const char *err = inet_tryconnect(&tcp->sock, address, port, tm);
 
216
    /* have to set the class even if it failed due to non-blocking connects */
 
217
    auxiliar_setclass(L, "tcp{client}", 1);
 
218
    if (err) {
 
219
        lua_pushnil(L);
 
220
        lua_pushstring(L, err);
 
221
        return 2;
 
222
    }
 
223
    /* turn master object into a client object */
 
224
    lua_pushnumber(L, 1);
 
225
    return 1;
 
226
}
 
227
 
 
228
/*-------------------------------------------------------------------------*\
 
229
* Closes socket used by object 
 
230
\*-------------------------------------------------------------------------*/
 
231
static int meth_close(lua_State *L)
 
232
{
 
233
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
234
    socket_destroy(&tcp->sock);
 
235
    lua_pushnumber(L, 1);
 
236
    return 1;
 
237
}
 
238
 
 
239
/*-------------------------------------------------------------------------*\
 
240
* Puts the sockt in listen mode
 
241
\*-------------------------------------------------------------------------*/
 
242
static int meth_listen(lua_State *L)
 
243
{
 
244
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1);
 
245
    int backlog = (int) luaL_optnumber(L, 2, 32);
 
246
    int err = socket_listen(&tcp->sock, backlog);
 
247
    if (err != IO_DONE) {
 
248
        lua_pushnil(L);
 
249
        lua_pushstring(L, socket_strerror(err));
 
250
        return 2;
 
251
    }
 
252
    /* turn master object into a server object */
 
253
    auxiliar_setclass(L, "tcp{server}", 1);
 
254
    lua_pushnumber(L, 1);
 
255
    return 1;
 
256
}
 
257
 
 
258
/*-------------------------------------------------------------------------*\
 
259
* Shuts the connection down partially
 
260
\*-------------------------------------------------------------------------*/
 
261
static int meth_shutdown(lua_State *L)
 
262
{
 
263
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
 
264
    const char *how = luaL_optstring(L, 2, "both");
 
265
    switch (how[0]) {
 
266
        case 'b':
 
267
            if (strcmp(how, "both")) goto error;
 
268
            socket_shutdown(&tcp->sock, 2);
 
269
            break;
 
270
        case 's':
 
271
            if (strcmp(how, "send")) goto error;
 
272
            socket_shutdown(&tcp->sock, 1);
 
273
            break;
 
274
        case 'r':
 
275
            if (strcmp(how, "receive")) goto error;
 
276
            socket_shutdown(&tcp->sock, 0);
 
277
            break;
 
278
    }
 
279
    lua_pushnumber(L, 1);
 
280
    return 1;
 
281
error:
 
282
    luaL_argerror(L, 2, "invalid shutdown method");
 
283
    return 0;
 
284
}
 
285
 
 
286
/*-------------------------------------------------------------------------*\
 
287
* Just call inet methods
 
288
\*-------------------------------------------------------------------------*/
 
289
static int meth_getpeername(lua_State *L)
 
290
{
 
291
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
292
    return inet_meth_getpeername(L, &tcp->sock);
 
293
}
 
294
 
 
295
static int meth_getsockname(lua_State *L)
 
296
{
 
297
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
298
    return inet_meth_getsockname(L, &tcp->sock);
 
299
}
 
300
 
 
301
/*-------------------------------------------------------------------------*\
 
302
* Just call tm methods
 
303
\*-------------------------------------------------------------------------*/
 
304
static int meth_settimeout(lua_State *L)
 
305
{
 
306
    p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
 
307
    return timeout_meth_settimeout(L, &tcp->tm);
 
308
}
 
309
 
 
310
/*=========================================================================*\
 
311
* Library functions
 
312
\*=========================================================================*/
 
313
/*-------------------------------------------------------------------------*\
 
314
* Creates a master tcp object 
 
315
\*-------------------------------------------------------------------------*/
 
316
static int global_create(lua_State *L)
 
317
{
 
318
    t_socket sock;
 
319
    const char *err = inet_trycreate(&sock, SOCK_STREAM);
 
320
    /* try to allocate a system socket */
 
321
    if (!err) { 
 
322
        /* allocate tcp object */
 
323
        p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
 
324
        /* set its type as master object */
 
325
        auxiliar_setclass(L, "tcp{master}", -1);
 
326
        /* initialize remaining structure fields */
 
327
        socket_setnonblocking(&sock);
 
328
        tcp->sock = sock;
 
329
        io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, 
 
330
                (p_error) socket_ioerror, &tcp->sock);
 
331
        timeout_init(&tcp->tm, -1, -1);
 
332
        buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
 
333
        return 1;
 
334
    } else {
 
335
        lua_pushnil(L);
 
336
        lua_pushstring(L, err);
 
337
        return 2;
 
338
    }
 
339
}