~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to modules/misc/lua/libs/net.c

  • Committer: Bazaar Package Importer
  • Author(s): Benjamin Drung
  • Date: 2010-06-25 01:09:16 UTC
  • mfrom: (1.1.30 upstream)
  • Revision ID: james.westby@ubuntu.com-20100625010916-asxhep2mutg6g6pd
Tags: 1.1.0-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - build and install the libx264 plugin
  - add Xb-Npp header to vlc package
  - Add apport hook to include more vlc dependencies in bug reports
* Drop xulrunner patches.
* Drop 502_xulrunner_191.diff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * net.c: Network related functions
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2007-2008 the VideoLAN team
5
 
 * $Id: dcf21664632fdbbff14972e38c7e3ac98681409a $
 
5
 * $Id: c23f4756b5f3716c5ed9dfc39595a4bbed8da5ad $
6
6
 *
7
7
 * Authors: Antoine Cellerier <dionoea at videolan tod org>
8
8
 *
35
35
#include <vlc_common.h>
36
36
#include <vlc_network.h>
37
37
#include <vlc_url.h>
 
38
#include <vlc_fs.h>
38
39
 
39
40
#include <lua.h>        /* Low level lua C API */
40
41
#include <lauxlib.h>    /* Higher level C API */
41
42
 
 
43
#ifdef HAVE_POLL
 
44
#include <poll.h>       /* poll structures and defines */
 
45
#endif
 
46
#include <sys/stat.h>
 
47
 
 
48
#include<errno.h>
42
49
#include "../vlc.h"
43
50
#include "../libs.h"
44
51
 
79
86
 *****************************************************************************/
80
87
static int vlclua_net_listen_close( lua_State * );
81
88
static int vlclua_net_accept( lua_State * );
 
89
static int vlclua_net_fds( lua_State * );
82
90
 
83
91
static const luaL_Reg vlclua_net_listen_reg[] = {
84
92
    { "accept", vlclua_net_accept },
 
93
    { "fds", vlclua_net_fds },
85
94
    { NULL, NULL }
86
95
};
87
96
 
117
126
    return 0;
118
127
}
119
128
 
 
129
static int vlclua_net_fds( lua_State *L )
 
130
{
 
131
    int **ppi_fd = (int**)luaL_checkudata( L, 1, "net_listen" );
 
132
    int *pi_fd = *ppi_fd;
 
133
 
 
134
    int i_count = 0;
 
135
    while( pi_fd[i_count] != -1 )
 
136
        lua_pushinteger( L, pi_fd[i_count++] );
 
137
 
 
138
    return i_count;
 
139
}
 
140
 
120
141
static int vlclua_net_accept( lua_State *L )
121
142
{
122
143
    vlc_object_t *p_this = vlclua_get_this( L );
123
144
    int **ppi_fd = (int**)luaL_checkudata( L, 1, "net_listen" );
124
 
    mtime_t i_wait = luaL_optint( L, 2, -1 ); /* default to block */
125
 
    int i_fd = net_Accept( p_this, *ppi_fd, i_wait );
 
145
    int i_fd = net_Accept( p_this, *ppi_fd );
 
146
 
126
147
    lua_pushinteger( L, i_fd );
127
148
    return 1;
128
149
}
130
151
/*****************************************************************************
131
152
 *
132
153
 *****************************************************************************/
 
154
static int vlclua_net_connect_tcp( lua_State *L )
 
155
{
 
156
    vlc_object_t *p_this = vlclua_get_this( L );
 
157
    const char *psz_host = luaL_checkstring( L, 1 );
 
158
    int i_port = luaL_checkint( L, 2 );
 
159
    int i_fd = net_Connect( p_this, psz_host, i_port, SOCK_STREAM, IPPROTO_TCP );
 
160
    lua_pushinteger( L, i_fd );
 
161
    return 1;
 
162
}
 
163
 
133
164
static int vlclua_net_close( lua_State *L )
134
165
{
135
166
    int i_fd = luaL_checkint( L, 1 );
153
184
    int i_fd = luaL_checkint( L, 1 );
154
185
    size_t i_len = luaL_optint( L, 2, 1 );
155
186
    char psz_buffer[i_len];
156
 
    i_len = recv( i_fd, psz_buffer, i_len, 0 );
157
 
    lua_pushlstring( L, psz_buffer, i_len );
 
187
    ssize_t i_ret = recv( i_fd, psz_buffer, i_len, 0 );
 
188
    lua_pushlstring( L, psz_buffer, (i_ret >= 0) ? i_ret : 0 );
158
189
    return 1;
159
190
}
160
191
 
161
192
/*****************************************************************************
162
193
 *
163
194
 *****************************************************************************/
164
 
static int vlclua_net_select( lua_State *L )
 
195
/* Takes a { fd : events } table as first arg and modifies it to { fd : revents } */
 
196
static int vlclua_net_poll( lua_State *L )
165
197
{
166
 
    int i_ret;
167
 
    size_t i_nfds = luaL_checkint( L, 1 );
168
 
    fd_set *fds_read = (fd_set*)luaL_checkudata( L, 2, "fd_set" );
169
 
    fd_set *fds_write = (fd_set*)luaL_checkudata( L, 3, "fd_set" );
170
 
    double f_timeout = luaL_checknumber( L, 4 );
171
 
    struct timeval timeout;
172
 
 
173
 
#ifndef WIN32
174
 
    if( i_nfds > FD_SETSIZE )
175
 
        i_nfds = FD_SETSIZE;
176
 
#endif
177
 
    timeout.tv_sec = (int)f_timeout;
178
 
    timeout.tv_usec = (int)(1e6*(f_timeout-(double)((int)f_timeout)));
179
 
    i_ret = select( i_nfds, fds_read, fds_write, 0, &timeout );
 
198
    luaL_checktype( L, 1, LUA_TTABLE );
 
199
    double f_timeout = luaL_optnumber( L, 2, -1. );
 
200
 
 
201
    int i_fds = 0;
 
202
    lua_pushnil( L );
 
203
    while( lua_next( L, 1 ) )
 
204
    {
 
205
        i_fds++;
 
206
        lua_pop( L, 1 );
 
207
    }
 
208
    struct pollfd *p_fds = malloc( i_fds * sizeof( struct pollfd ) );
 
209
    vlc_cleanup_push( free, p_fds );
 
210
    lua_pushnil( L );
 
211
    int i = 0;
 
212
    while( lua_next( L, 1 ) )
 
213
    {
 
214
        p_fds[i].fd = luaL_checkinteger( L, -2 );
 
215
        p_fds[i].events = luaL_checkinteger( L, -1 );
 
216
        p_fds[i].revents = 0;
 
217
        lua_pop( L, 1 );
 
218
        i++;
 
219
    }
 
220
 
 
221
    int i_ret = poll( p_fds, i_fds, f_timeout < 0. ? -1 : (int)(f_timeout*1000) );
 
222
    for( i = 0; i < i_fds; i++ )
 
223
    {
 
224
        lua_pushinteger( L, p_fds[i].fd );
 
225
        lua_pushinteger( L, p_fds[i].revents );
 
226
        lua_settable( L, 1 );
 
227
    }
180
228
    lua_pushinteger( L, i_ret );
181
 
    lua_pushinteger( L, (double)timeout.tv_sec+((double)timeout.tv_usec)/1e-6 );
182
 
    return 2;
183
 
}
184
 
 
185
 
/*****************************************************************************
186
 
 *
187
 
 *****************************************************************************/
188
 
static int vlclua_fd_clr( lua_State * );
189
 
static int vlclua_fd_isset( lua_State * );
190
 
static int vlclua_fd_set( lua_State * );
191
 
static int vlclua_fd_zero( lua_State * );
192
 
 
193
 
static const luaL_Reg vlclua_fd_set_reg[] = {
194
 
    { "clr", vlclua_fd_clr },
195
 
    { "isset", vlclua_fd_isset },
196
 
    { "set", vlclua_fd_set },
197
 
    { "zero", vlclua_fd_zero },
198
 
    { NULL, NULL }
199
 
};
200
 
 
201
 
static int vlclua_fd_set_new( lua_State *L )
202
 
{
203
 
    fd_set *fds = (fd_set*)lua_newuserdata( L, sizeof( fd_set ) );
204
 
    FD_ZERO( fds );
205
 
 
206
 
    if( luaL_newmetatable( L, "fd_set" ) )
207
 
    {
208
 
        lua_newtable( L );
209
 
        luaL_register( L, NULL, vlclua_fd_set_reg );
210
 
        lua_setfield( L, -2, "__index" );
211
 
    }
212
 
 
213
 
    lua_setmetatable( L, -2 );
214
 
    return 1;
215
 
}
216
 
 
217
 
static int vlclua_fd_clr( lua_State *L )
218
 
{
219
 
    fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
220
 
    int i_fd = luaL_checkint( L, 2 );
221
 
    FD_CLR( i_fd, fds );
222
 
    return 0;
223
 
}
224
 
 
225
 
static int vlclua_fd_isset( lua_State *L )
226
 
{
227
 
    fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
228
 
    int i_fd = luaL_checkint( L, 2 );
229
 
    lua_pushboolean( L, FD_ISSET( i_fd, fds ) );
230
 
    return 1;
231
 
}
232
 
 
233
 
static int vlclua_fd_set( lua_State *L )
234
 
{
235
 
    fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
236
 
    size_t i_fd = luaL_checkint( L, 2 );
237
 
    /* FIXME: we should really use poll() instead here, but that breaks the
238
 
     * VLC/LUA API. On Windows, overflow protection is built-in FD_SET, not
239
 
     * on POSIX. In both cases, run-time behavior will however be wrong. */
240
 
#ifndef WIN32
241
 
    if( i_fd < FD_SETSIZE )
242
 
#endif
243
 
        FD_SET( i_fd, fds );
244
 
    return 0;
245
 
}
246
 
 
247
 
static int vlclua_fd_zero( lua_State *L )
248
 
{
249
 
    fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
250
 
    FD_ZERO( fds );
251
 
    return 0;
 
229
    vlc_cleanup_run();
 
230
    return 1;
252
231
}
253
232
 
254
233
/*****************************************************************************
277
256
    int i_fd = luaL_checkint( L, 1 );
278
257
    size_t i_len = luaL_optint( L, 2, 1 );
279
258
    char psz_buffer[i_len];
280
 
    i_len = read( i_fd, psz_buffer, i_len );
281
 
    lua_pushlstring( L, psz_buffer, i_len );
 
259
    ssize_t i_ret = read( i_fd, psz_buffer, i_len );
 
260
    lua_pushlstring( L, psz_buffer, (i_ret >= 0) ? i_ret : 0 );
282
261
    return 1;
283
262
}
284
263
 
290
269
#ifdef HAVE_SYS_STAT_H
291
270
    const char *psz_path = luaL_checkstring( L, 1 );
292
271
    struct stat s;
293
 
    if( utf8_stat( psz_path, &s ) )
 
272
    if( vlc_stat( psz_path, &s ) )
294
273
        return 0;
295
274
        //return luaL_error( L, "Couldn't stat %s.", psz_path );
296
275
    lua_newtable( L );
297
276
    if( S_ISREG( s.st_mode ) )
298
 
        lua_pushstring( L, "file" );
 
277
        lua_pushliteral( L, "file" );
299
278
    else if( S_ISDIR( s.st_mode ) )
300
 
        lua_pushstring( L, "dir" );
 
279
        lua_pushliteral( L, "dir" );
301
280
#ifdef S_ISCHR
302
281
    else if( S_ISCHR( s.st_mode ) )
303
 
        lua_pushstring( L, "character device" );
 
282
        lua_pushliteral( L, "character device" );
304
283
#endif
305
284
#ifdef S_ISBLK
306
285
    else if( S_ISBLK( s.st_mode ) )
307
 
        lua_pushstring( L, "block device" );
 
286
        lua_pushliteral( L, "block device" );
308
287
#endif
309
288
#ifdef S_ISFIFO
310
289
    else if( S_ISFIFO( s.st_mode ) )
311
 
        lua_pushstring( L, "fifo" );
 
290
        lua_pushliteral( L, "fifo" );
312
291
#endif
313
292
#ifdef S_ISLNK
314
293
    else if( S_ISLNK( s.st_mode ) )
315
 
        lua_pushstring( L, "symbolic link" );
 
294
        lua_pushliteral( L, "symbolic link" );
316
295
#endif
317
296
#ifdef S_ISSOCK
318
297
    else if( S_ISSOCK( s.st_mode ) )
319
 
        lua_pushstring( L, "socket" );
 
298
        lua_pushliteral( L, "socket" );
320
299
#endif
321
300
    else
322
 
        lua_pushstring( L, "unknown" );
 
301
        lua_pushliteral( L, "unknown" );
323
302
    lua_setfield( L, -2, "type" );
324
303
    lua_pushinteger( L, s.st_mode );
325
304
    lua_setfield( L, -2, "mode" );
348
327
    DIR *p_dir;
349
328
    int i = 0;
350
329
 
351
 
    if( ( p_dir = utf8_opendir( psz_dir ) ) == NULL )
 
330
    if( ( p_dir = vlc_opendir( psz_dir ) ) == NULL )
352
331
        return luaL_error( L, "cannot open directory `%s'.", psz_dir );
353
332
 
354
333
    lua_newtable( L );
355
334
    for( ;; )
356
335
    {
357
 
        char *psz_filename = utf8_readdir( p_dir );
 
336
        char *psz_filename = vlc_readdir( p_dir );
358
337
        if( !psz_filename ) break;
359
338
        i++;
360
339
        lua_pushstring( L, psz_filename );
371
350
static const luaL_Reg vlclua_net_reg[] = {
372
351
    { "url_parse", vlclua_url_parse },
373
352
    { "listen_tcp", vlclua_net_listen_tcp },
 
353
    { "connect_tcp", vlclua_net_connect_tcp },
374
354
    { "close", vlclua_net_close },
375
355
    { "send", vlclua_net_send },
376
356
    { "recv", vlclua_net_recv },
377
 
    { "select", vlclua_net_select },
378
 
    { "fd_set_new", vlclua_fd_set_new },
 
357
    { "poll", vlclua_net_poll },
379
358
    { "read", vlclua_fd_read },
380
359
    { "write", vlclua_fd_write },
381
360
    { "stat", vlclua_stat }, /* Not really "net" */
387
366
{
388
367
    lua_newtable( L );
389
368
    luaL_register( L, NULL, vlclua_net_reg );
 
369
#define ADD_CONSTANT( name, value )    \
 
370
    lua_pushinteger( L, value ); \
 
371
    lua_setfield( L, -2, name );
 
372
    ADD_CONSTANT( "POLLIN", POLLIN )
 
373
    ADD_CONSTANT( "POLLPRI", POLLPRI )
 
374
    ADD_CONSTANT( "POLLOUT", POLLOUT )
 
375
    ADD_CONSTANT( "POLLERR", POLLERR )
 
376
    ADD_CONSTANT( "POLLHUP", POLLHUP )
 
377
    ADD_CONSTANT( "POLLNVAL", POLLNVAL )
390
378
    lua_setfield( L, -2, "net" );
391
379
}