mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 20:38:22 +01:00
Finished implementation of LuaSocket 2.0 alpha on Linux.
Some testing still needed.
This commit is contained in:
parent
f330540576
commit
71f6bb60bf
4
NEW
4
NEW
@ -8,7 +8,9 @@ a given domain/family and protocol. Then connect or bind if needed. Then
|
|||||||
use IO functions.
|
use IO functions.
|
||||||
|
|
||||||
All functions return a non-nil value as first return value if successful.
|
All functions return a non-nil value as first return value if successful.
|
||||||
All functions return nil followed by error message in case of error.
|
All functions return whatever could be retrieved followed by error message
|
||||||
|
in case of error. The best way to check for errors is to check for the
|
||||||
|
presence of an error message.
|
||||||
WARNING: The send function was affected.
|
WARNING: The send function was affected.
|
||||||
|
|
||||||
Better error messages and parameter checking.
|
Better error messages and parameter checking.
|
||||||
|
26
TODO
26
TODO
@ -1,24 +1,26 @@
|
|||||||
|
- Melhorar a interface de setoptions (aceitar nada como true, por exemplo)
|
||||||
- Inicializaccao das classes pode falhar?
|
- Inicializaccao das classes pode falhar?
|
||||||
- Ajeitar melhor a hierarquia de classes. Ajeitar o file...
|
- Ajeitar melhor a hierarquia de classes. Ajeitar o file...
|
||||||
|
- GARBAGE COLLECTOR!
|
||||||
|
- Adicionar um método sock:setoption???
|
||||||
|
- testar em várias plataformas
|
||||||
|
- adicionar exemplos de expansão: pipe, local, named pipe
|
||||||
|
|
||||||
* Como mostrar um erro em lua_socketlibopen()...
|
* Como mostrar um erro em lua_socketlibopen()...
|
||||||
* O location do "redirect" pode ser relativo ao servidor atual (não pode,
|
* O location do "redirect" pode ser relativo ao servidor atual (não pode,
|
||||||
mas os servidores fazem merda...)
|
mas os servidores fazem merda...)
|
||||||
* - Ajeitar para Lua 4.1
|
* Ajeitar para Lua 5.0
|
||||||
|
* Padronizar os retornos de funccao
|
||||||
|
* Separar as classes em arquivos
|
||||||
|
* Retorno de sendto em datagram sockets pode ser refused
|
||||||
|
* Fazer compilar com g++
|
||||||
|
|
||||||
- Padronizar os retornos de funccao
|
|
||||||
- Thread-safe
|
- Thread-safe
|
||||||
- proteger gethostby*.* com um mutex GLOBAL!
|
- proteger gethostby*.* com um mutex GLOBAL!
|
||||||
- proteger o atomizar o conjunto (timedout, receive), (timedout, send)
|
- proteger ou atomizar o conjunto (timedout, receive), (timedout, send)
|
||||||
- Usar "require" nos módulos
|
- inet_ntoa também é uma merda.
|
||||||
- SSL
|
- SSL
|
||||||
- Fazer compilar com g++
|
- Proxy support pro http
|
||||||
- usar lua_verror
|
|
||||||
- separar as classes em arquivos
|
|
||||||
- criar mais uma classe, a de stream, entre p_sock e p_client
|
|
||||||
- criar um internal include file ls.h
|
|
||||||
- impedir que voe quando chamar accept(udpsocket())
|
|
||||||
- trocar recv and send por read e write (ver se funciona)
|
|
||||||
|
|
||||||
- checar operações em closed sockets
|
- checar operações em closed sockets
|
||||||
- checar teste de writable socket com select
|
- checar teste de writable socket com select
|
||||||
@ -34,6 +36,4 @@
|
|||||||
- unix 92 bytes maximo no endereço, incluindo o zero
|
- unix 92 bytes maximo no endereço, incluindo o zero
|
||||||
- unix 9216 maximo de datagram size
|
- unix 9216 maximo de datagram size
|
||||||
|
|
||||||
- retorno de send/receive em datagram sockets pode ser refused...
|
|
||||||
|
|
||||||
- adicionar um método sock:setoption???
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Little program that checks links in HTML files
|
-- Little program that checks links in HTML files
|
||||||
-- LuaSocket 1.5 sample files.
|
-- LuaSocket sample files
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Little program to download DICT word definitions
|
-- Little program to download DICT word definitions
|
||||||
-- LuaSocket 1.5 sample files
|
-- LuaSocket sample files
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Little program to download files from URLs
|
-- Little program to download files from URLs
|
||||||
-- LuaSocket 1.5 sample files
|
-- LuaSocket sample files
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- TFTP support for the Lua language
|
-- TFTP support for the Lua language
|
||||||
-- LuaSocket 1.5 toolkit.
|
-- LuaSocket toolkit.
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- Conforming to: RFC 783, LTN7
|
-- Conforming to: RFC 783, LTN7
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- UDP sample: daytime protocol client
|
-- UDP sample: daytime protocol client
|
||||||
-- LuaSocket 1.5 sample files.
|
-- LuaSocket sample files
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- UDP sample: echo protocol client
|
-- UDP sample: echo protocol client
|
||||||
-- LuaSocket 1.5 sample files
|
-- LuaSocket sample files
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- UDP sample: echo protocol server
|
-- UDP sample: echo protocol server
|
||||||
-- LuaSocket 1.5 sample files
|
-- LuaSocket sample files
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- TCP sample: Little program to dump lines received at a given port
|
-- TCP sample: Little program to dump lines received at a given port
|
||||||
-- LuaSocket 1.5 sample files
|
-- LuaSocket sample files
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- TCP sample: Little program to send text lines to a given host/port
|
-- TCP sample: Little program to send text lines to a given host/port
|
||||||
-- LuaSocket 1.5 sample files
|
-- LuaSocket sample files
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Select sample: simple text line server
|
-- Select sample: simple text line server
|
||||||
-- LuaSocket 1.5 sample files.
|
-- LuaSocket sample files.
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
189
src/auxiliar.c
189
src/auxiliar.c
@ -1,142 +1,167 @@
|
|||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Auxiliar routines for class hierarchy manipulation
|
* Auxiliar routines for class hierarchy manipulation
|
||||||
|
* LuaSocket toolkit
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "luasocket.h"
|
||||||
#include "auxiliar.h"
|
#include "auxiliar.h"
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Exported functions
|
* Exported functions
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Creates a new class. A class has methods given by the func array and the
|
* Initializes the module
|
||||||
* field 'class' tells the object class. The table 'group' list the class
|
|
||||||
* groups the object belongs to.
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void aux_newclass(lua_State *L, const char *name, luaL_reg *func)
|
void aux_open(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_pushstring(L, name);
|
/* create namespace table */
|
||||||
|
lua_pushstring(L, LUASOCKET_LIBNAME);
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_pushstring(L, "__index");
|
#ifdef LUASOCKET_DEBUG
|
||||||
lua_newtable(L);
|
lua_pushstring(L, "debug");
|
||||||
luaL_openlib(L, NULL, func, 0);
|
|
||||||
lua_pushstring(L, "class");
|
|
||||||
lua_pushstring(L, name);
|
|
||||||
lua_rawset(L, -3);
|
|
||||||
lua_pushstring(L, "group");
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_rawset(L, -3);
|
|
||||||
lua_rawset(L, -3);
|
|
||||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
|
||||||
* Add group to object list of groups.
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
void aux_add2group(lua_State *L, const char *name, const char *group)
|
|
||||||
{
|
|
||||||
lua_pushstring(L, name);
|
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
|
||||||
lua_pushstring(L, "__index");
|
|
||||||
lua_rawget(L, -2);
|
|
||||||
lua_pushstring(L, "group");
|
|
||||||
lua_rawget(L, -2);
|
|
||||||
lua_pushstring(L, group);
|
|
||||||
lua_pushnumber(L, 1);
|
lua_pushnumber(L, 1);
|
||||||
lua_rawset(L, -3);
|
lua_rawset(L, -3);
|
||||||
lua_pop(L, 3);
|
#endif
|
||||||
|
lua_settable(L, LUA_GLOBALSINDEX);
|
||||||
|
/* make sure modules know what is our namespace */
|
||||||
|
lua_pushstring(L, "LUASOCKET_LIBNAME");
|
||||||
|
lua_pushstring(L, LUASOCKET_LIBNAME);
|
||||||
|
lua_settable(L, LUA_GLOBALSINDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Get a userdata making sure the object belongs to a given class.
|
* Creates a new class with given methods
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void *aux_checkclass(lua_State *L, const char *name, int objidx)
|
void aux_newclass(lua_State *L, const char *classname, luaL_reg *func)
|
||||||
{
|
{
|
||||||
void *data = aux_getclassudata(L, name, objidx);
|
luaL_newmetatable(L, classname); /* mt */
|
||||||
|
lua_pushstring(L, "__index"); /* mt,"__index" */
|
||||||
|
lua_newtable(L); /* mt,"__index",it */
|
||||||
|
luaL_openlib(L, NULL, func, 0);
|
||||||
|
#ifdef LUASOCKET_DEBUG
|
||||||
|
lua_pushstring(L, "class"); /* mt,"__index",it,"class" */
|
||||||
|
lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */
|
||||||
|
lua_rawset(L, -3); /* mt,"__index",it */
|
||||||
|
#endif
|
||||||
|
/* get __gc method from class and use it for garbage collection */
|
||||||
|
lua_pushstring(L, "__gc"); /* mt,"__index",it,"__gc" */
|
||||||
|
lua_pushstring(L, "__gc"); /* mt,"__index",it,"__gc","__gc" */
|
||||||
|
lua_rawget(L, -3); /* mt,"__index",it,"__gc",fn */
|
||||||
|
lua_rawset(L, -5); /* mt,"__index",it */
|
||||||
|
lua_rawset(L, -3); /* mt */
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Insert class into group
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
void aux_add2group(lua_State *L, const char *classname, const char *groupname)
|
||||||
|
{
|
||||||
|
luaL_getmetatable(L, classname);
|
||||||
|
lua_pushstring(L, groupname);
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Make sure argument is a boolean
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
int aux_checkboolean(lua_State *L, int objidx)
|
||||||
|
{
|
||||||
|
if (!lua_isboolean(L, objidx))
|
||||||
|
luaL_typerror(L, objidx, lua_typename(L, LUA_TBOOLEAN));
|
||||||
|
return lua_toboolean(L, objidx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Calls appropriate option handler
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
int aux_meth_setoption(lua_State *L, luaL_reg *opt)
|
||||||
|
{
|
||||||
|
const char *name = luaL_checkstring(L, 2); /* obj, name, args */
|
||||||
|
while (opt->name && strcmp(name, opt->name))
|
||||||
|
opt++;
|
||||||
|
if (!opt->func) {
|
||||||
|
char msg[45];
|
||||||
|
sprintf(msg, "unknown option `%.35s'", name);
|
||||||
|
luaL_argerror(L, 2, msg);
|
||||||
|
}
|
||||||
|
lua_remove(L, 2); /* obj, args */
|
||||||
|
lua_pushcfunction(L, opt->func); /* obj, args, func */
|
||||||
|
lua_insert(L, 1); /* func, obj, args */
|
||||||
|
lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
|
||||||
|
return lua_gettop(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Return userdata pointer if object belongs to a given class, abort with
|
||||||
|
* error otherwise
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
void *aux_checkclass(lua_State *L, const char *classname, int objidx)
|
||||||
|
{
|
||||||
|
void *data = aux_getclassudata(L, classname, objidx);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
char msg[45];
|
char msg[45];
|
||||||
sprintf(msg, "%.35s expected", name);
|
sprintf(msg, "%.35s expected", classname);
|
||||||
luaL_argerror(L, objidx, msg);
|
luaL_argerror(L, objidx, msg);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Get a userdata making sure the object belongs to a given group.
|
* Return userdata pointer if object belongs to a given group, abort with
|
||||||
|
* error otherwise
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void *aux_checkgroup(lua_State *L, const char *group, int objidx)
|
void *aux_checkgroup(lua_State *L, const char *groupname, int objidx)
|
||||||
{
|
{
|
||||||
void *data = aux_getgroupudata(L, group, objidx);
|
void *data = aux_getgroupudata(L, groupname, objidx);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
char msg[45];
|
char msg[45];
|
||||||
sprintf(msg, "%.35s expected", group);
|
sprintf(msg, "%.35s expected", groupname);
|
||||||
luaL_argerror(L, objidx, msg);
|
luaL_argerror(L, objidx, msg);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Set object class.
|
* Set object class
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void aux_setclass(lua_State *L, const char *name, int objidx)
|
void aux_setclass(lua_State *L, const char *classname, int objidx)
|
||||||
{
|
{
|
||||||
lua_pushstring(L, name);
|
luaL_getmetatable(L, classname);
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
|
||||||
if (objidx < 0) objidx--;
|
if (objidx < 0) objidx--;
|
||||||
lua_setmetatable(L, objidx);
|
lua_setmetatable(L, objidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=========================================================================*\
|
|
||||||
* Internal functions
|
|
||||||
\*=========================================================================*/
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Get a userdata if object belongs to a given group.
|
* Get a userdata pointer if object belongs to a given group. Return NULL
|
||||||
|
* otherwise
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void *aux_getgroupudata(lua_State *L, const char *group, int objidx)
|
void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx)
|
||||||
{
|
{
|
||||||
if (!lua_getmetatable(L, objidx))
|
if (!lua_getmetatable(L, objidx))
|
||||||
return NULL;
|
return NULL;
|
||||||
lua_pushstring(L, "__index");
|
lua_pushstring(L, groupname);
|
||||||
lua_rawget(L, -2);
|
|
||||||
if (!lua_istable(L, -1)) {
|
|
||||||
lua_pop(L, 2);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
lua_pushstring(L, "group");
|
|
||||||
lua_rawget(L, -2);
|
|
||||||
if (!lua_istable(L, -1)) {
|
|
||||||
lua_pop(L, 3);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
lua_pushstring(L, group);
|
|
||||||
lua_rawget(L, -2);
|
lua_rawget(L, -2);
|
||||||
if (lua_isnil(L, -1)) {
|
if (lua_isnil(L, -1)) {
|
||||||
lua_pop(L, 4);
|
lua_pop(L, 2);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
} else {
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return lua_touserdata(L, objidx);
|
||||||
}
|
}
|
||||||
lua_pop(L, 4);
|
|
||||||
return lua_touserdata(L, objidx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Get a userdata if object belongs to a given class.
|
* Get a userdata pointer if object belongs to a given class. Return NULL
|
||||||
|
* otherwise
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
void *aux_getclassudata(lua_State *L, const char *group, int objidx)
|
void *aux_getclassudata(lua_State *L, const char *classname, int objidx)
|
||||||
{
|
{
|
||||||
if (!lua_getmetatable(L, objidx))
|
return luaL_checkudata(L, objidx, classname);
|
||||||
return NULL;
|
|
||||||
lua_pushstring(L, "__index");
|
|
||||||
lua_rawget(L, -2);
|
|
||||||
if (!lua_istable(L, -1)) {
|
|
||||||
lua_pop(L, 2);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
lua_pushstring(L, "class");
|
|
||||||
lua_rawget(L, -2);
|
|
||||||
if (lua_isnil(L, -1)) {
|
|
||||||
lua_pop(L, 3);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
lua_pop(L, 3);
|
|
||||||
return lua_touserdata(L, objidx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,22 +1,37 @@
|
|||||||
|
#ifndef AUX_H
|
||||||
|
#define AUX_H
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Auxiliar routines for class hierarchy manipulation
|
* Auxiliar routines for class hierarchy manipulation
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* A LuaSocket class is a name associated with Lua metatables. A LuaSocket
|
||||||
|
* group is a name associated to a class. A class can belong to any number
|
||||||
|
* of groups. This module provides the functionality to:
|
||||||
|
*
|
||||||
|
* - create new classes
|
||||||
|
* - add classes to groups
|
||||||
|
* - set the class of object
|
||||||
|
* - check if an object belongs to a given class or group
|
||||||
|
*
|
||||||
|
* LuaSocket class names follow the convention <module>{<class>}. Modules
|
||||||
|
* can define any number of classes and groups. The module tcp.c, for
|
||||||
|
* example, defines the classes tcp{master}, tcp{client} and tcp{server} and
|
||||||
|
* the groups tcp{client, server} and tcp{any}. Module functions can then
|
||||||
|
* perform type-checking on it's arguments by either class or group.
|
||||||
|
*
|
||||||
|
* LuaSocket metatables define the __index metamethod as being a table. This
|
||||||
|
* table has one field for each method supported by the class. In DEBUG
|
||||||
|
* mode, it also has one field with the class name.
|
||||||
|
*
|
||||||
|
* The mapping from class name to the corresponding metatable and the
|
||||||
|
* reverse mapping are done using lauxlib.
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#ifndef AUX_H
|
|
||||||
#define AUX_H
|
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
|
|
||||||
void aux_newclass(lua_State *L, const char *name, luaL_reg *func);
|
|
||||||
void aux_add2group(lua_State *L, const char *name, const char *group);
|
|
||||||
void *aux_checkclass(lua_State *L, const char *name, int objidx);
|
|
||||||
void *aux_checkgroup(lua_State *L, const char *group, int objidx);
|
|
||||||
void *aux_getclassudata(lua_State *L, const char *group, int objidx);
|
|
||||||
void *aux_getgroupudata(lua_State *L, const char *group, int objidx);
|
|
||||||
void aux_setclass(lua_State *L, const char *name, int objidx);
|
|
||||||
|
|
||||||
/* min and max macros */
|
/* min and max macros */
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(x, y) ((x) < (y) ? x : y)
|
#define MIN(x, y) ((x) < (y) ? x : y)
|
||||||
@ -25,4 +40,15 @@ void aux_setclass(lua_State *L, const char *name, int objidx);
|
|||||||
#define MAX(x, y) ((x) > (y) ? x : y)
|
#define MAX(x, y) ((x) > (y) ? x : y)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
void aux_open(lua_State *L);
|
||||||
|
void aux_newclass(lua_State *L, const char *classname, luaL_reg *func);
|
||||||
|
void aux_add2group(lua_State *L, const char *classname, const char *group);
|
||||||
|
void aux_setclass(lua_State *L, const char *classname, int objidx);
|
||||||
|
void *aux_checkclass(lua_State *L, const char *classname, int objidx);
|
||||||
|
void *aux_checkgroup(lua_State *L, const char *groupname, int objidx);
|
||||||
|
void *aux_getclassudata(lua_State *L, const char *groupname, int objidx);
|
||||||
|
void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx);
|
||||||
|
int aux_meth_setoption(lua_State *L, luaL_reg *opt);
|
||||||
|
int aux_checkboolean(lua_State *L, int objidx);
|
||||||
|
|
||||||
|
#endif /* AUX_H */
|
||||||
|
33
src/buffer.c
33
src/buffer.c
@ -1,12 +1,12 @@
|
|||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Buffered input/output routines
|
* Input/Output interface for Lua programs
|
||||||
|
* LuaSocket toolkit
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
|
|
||||||
#include "error.h"
|
|
||||||
#include "auxiliar.h"
|
#include "auxiliar.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ void buf_init(p_buf buf, p_io io, p_tm tm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Send data through buffered object
|
* object:send() interface
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
int buf_meth_send(lua_State *L, p_buf buf)
|
int buf_meth_send(lua_State *L, p_buf buf)
|
||||||
{
|
{
|
||||||
@ -59,7 +59,7 @@ int buf_meth_send(lua_State *L, p_buf buf)
|
|||||||
total += sent;
|
total += sent;
|
||||||
}
|
}
|
||||||
lua_pushnumber(L, total);
|
lua_pushnumber(L, total);
|
||||||
error_push(L, err);
|
io_pusherror(L, err);
|
||||||
#ifdef LUASOCKET_DEBUG
|
#ifdef LUASOCKET_DEBUG
|
||||||
/* push time elapsed during operation as the last return value */
|
/* push time elapsed during operation as the last return value */
|
||||||
lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0);
|
lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0);
|
||||||
@ -68,7 +68,7 @@ int buf_meth_send(lua_State *L, p_buf buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Receive data from a buffered object
|
* object:receive() interface
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
int buf_meth_receive(lua_State *L, p_buf buf)
|
int buf_meth_receive(lua_State *L, p_buf buf)
|
||||||
{
|
{
|
||||||
@ -101,13 +101,13 @@ int buf_meth_receive(lua_State *L, p_buf buf)
|
|||||||
luaL_argcheck(L, 0, arg, "invalid receive pattern");
|
luaL_argcheck(L, 0, arg, "invalid receive pattern");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* raw pattern */
|
/* get a fixed number of bytes */
|
||||||
} else err = recvraw(L, buf, (size_t) lua_tonumber(L, arg));
|
} else err = recvraw(L, buf, (size_t) lua_tonumber(L, arg));
|
||||||
}
|
}
|
||||||
/* push nil for each pattern after an error */
|
/* push nil for each pattern after an error */
|
||||||
for ( ; arg <= top; arg++) lua_pushnil(L);
|
for ( ; arg <= top; arg++) lua_pushnil(L);
|
||||||
/* last return is an error code */
|
/* last return is an error code */
|
||||||
error_push(L, err);
|
io_pusherror(L, err);
|
||||||
#ifdef LUASOCKET_DEBUG
|
#ifdef LUASOCKET_DEBUG
|
||||||
/* push time elapsed during operation as the last return value */
|
/* push time elapsed during operation as the last return value */
|
||||||
lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0);
|
lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0);
|
||||||
@ -127,9 +127,10 @@ int buf_isempty(p_buf buf)
|
|||||||
* Internal functions
|
* Internal functions
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Sends a raw block of data through a buffered object.
|
* Sends a block of data (unbuffered)
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent)
|
static
|
||||||
|
int sendraw(p_buf buf, const char *data, size_t count, size_t *sent)
|
||||||
{
|
{
|
||||||
p_io io = buf->io;
|
p_io io = buf->io;
|
||||||
p_tm tm = buf->tm;
|
p_tm tm = buf->tm;
|
||||||
@ -145,7 +146,7 @@ static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Reads a raw block of data from a buffered object.
|
* Reads a fixed number of bytes (buffered)
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static
|
static
|
||||||
int recvraw(lua_State *L, p_buf buf, size_t wanted)
|
int recvraw(lua_State *L, p_buf buf, size_t wanted)
|
||||||
@ -167,7 +168,7 @@ int recvraw(lua_State *L, p_buf buf, size_t wanted)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Reads everything until the connection is closed
|
* Reads everything until the connection is closed (buffered)
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static
|
static
|
||||||
int recvall(lua_State *L, p_buf buf)
|
int recvall(lua_State *L, p_buf buf)
|
||||||
@ -187,12 +188,12 @@ int recvall(lua_State *L, p_buf buf)
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF
|
* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF
|
||||||
* are not returned by the function and are discarded from the buffer.
|
* are not returned by the function and are discarded from the buffer
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static
|
static
|
||||||
int recvline(lua_State *L, p_buf buf)
|
int recvline(lua_State *L, p_buf buf)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = IO_DONE;
|
||||||
luaL_Buffer b;
|
luaL_Buffer b;
|
||||||
luaL_buffinit(L, &b);
|
luaL_buffinit(L, &b);
|
||||||
while (err == IO_DONE) {
|
while (err == IO_DONE) {
|
||||||
@ -215,7 +216,8 @@ int recvline(lua_State *L, p_buf buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Skips a given number of bytes in read buffer
|
* Skips a given number of bytes from read buffer. No data is read from the
|
||||||
|
* transport layer
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static
|
static
|
||||||
void buf_skip(p_buf buf, size_t count)
|
void buf_skip(p_buf buf, size_t count)
|
||||||
@ -227,7 +229,7 @@ void buf_skip(p_buf buf, size_t count)
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Return any data available in buffer, or get more data from transport layer
|
* Return any data available in buffer, or get more data from transport layer
|
||||||
* if buffer is empty.
|
* if buffer is empty
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static
|
static
|
||||||
int buf_get(p_buf buf, const char **data, size_t *count)
|
int buf_get(p_buf buf, const char **data, size_t *count)
|
||||||
@ -245,3 +247,4 @@ int buf_get(p_buf buf, const char **data, size_t *count)
|
|||||||
*data = buf->data + buf->first;
|
*data = buf->data + buf->first;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
src/buffer.h
27
src/buffer.h
@ -1,21 +1,31 @@
|
|||||||
|
#ifndef BUF_H
|
||||||
|
#define BUF_H
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Buffered input/output routines
|
* Input/Output interface for Lua programs
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* Line patterns require buffering. Reading one character at a time involves
|
||||||
|
* too many system calls and is very slow. This module implements the
|
||||||
|
* LuaSocket interface for input/output on connected objects, as seen by
|
||||||
|
* Lua programs.
|
||||||
|
*
|
||||||
|
* Input is buffered. Output is *not* buffered because there was no simple
|
||||||
|
* way of making sure the buffered output data would ever be sent.
|
||||||
|
*
|
||||||
|
* The module is built on top of the I/O abstraction defined in io.h and the
|
||||||
|
* timeout management is done with the timeout.h interface.
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#ifndef BUF_H
|
|
||||||
#define BUF_H
|
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "timeout.h"
|
#include "timeout.h"
|
||||||
|
|
||||||
/* buffer size in bytes */
|
/* buffer size in bytes */
|
||||||
#define BUF_SIZE 8192
|
#define BUF_SIZE 8192
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/* buffer control structure */
|
||||||
* Buffer control structure
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
typedef struct t_buf_ {
|
typedef struct t_buf_ {
|
||||||
p_io io; /* IO driver used for this buffer */
|
p_io io; /* IO driver used for this buffer */
|
||||||
p_tm tm; /* timeout management for this buffer */
|
p_tm tm; /* timeout management for this buffer */
|
||||||
@ -24,9 +34,6 @@ typedef struct t_buf_ {
|
|||||||
} t_buf;
|
} t_buf;
|
||||||
typedef t_buf *p_buf;
|
typedef t_buf *p_buf;
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
|
||||||
* Exported functions
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
void buf_open(lua_State *L);
|
void buf_open(lua_State *L);
|
||||||
void buf_init(p_buf buf, p_io io, p_tm tm);
|
void buf_init(p_buf buf, p_io io, p_tm tm);
|
||||||
int buf_meth_send(lua_State *L, p_buf buf);
|
int buf_meth_send(lua_State *L, p_buf buf);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- FTP support for the Lua language
|
-- FTP support for the Lua language
|
||||||
-- LuaSocket 1.5 toolkit.
|
-- LuaSocket toolkit.
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- Conforming to: RFC 959, LTN7
|
-- Conforming to: RFC 959, LTN7
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- HTTP/1.1 client support for the Lua language.
|
-- HTTP/1.1 client support for the Lua language.
|
||||||
-- LuaSocket 1.5 toolkit.
|
-- LuaSocket toolkit.
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- Conforming to: RFC 2616, LTN7
|
-- Conforming to: RFC 2616, LTN7
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
|
43
src/inet.c
43
src/inet.c
@ -1,8 +1,10 @@
|
|||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Internet domain functions
|
* Internet domain functions
|
||||||
|
* LuaSocket toolkit
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
@ -16,7 +18,6 @@
|
|||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
static int inet_global_toip(lua_State *L);
|
static int inet_global_toip(lua_State *L);
|
||||||
static int inet_global_tohostname(lua_State *L);
|
static int inet_global_tohostname(lua_State *L);
|
||||||
|
|
||||||
static void inet_pushresolved(lua_State *L, struct hostent *hp);
|
static void inet_pushresolved(lua_State *L, struct hostent *hp);
|
||||||
|
|
||||||
static luaL_reg func[] = {
|
static luaL_reg func[] = {
|
||||||
@ -43,11 +44,6 @@ void inet_open(lua_State *L)
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Returns all information provided by the resolver given a host name
|
* Returns all information provided by the resolver given a host name
|
||||||
* or ip address
|
* or ip address
|
||||||
* Lua Input: address
|
|
||||||
* address: ip address or hostname to dns lookup
|
|
||||||
* Lua Returns
|
|
||||||
* On success: first IP address followed by a resolved table
|
|
||||||
* On error: nil, followed by an error message
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static int inet_global_toip(lua_State *L)
|
static int inet_global_toip(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -72,11 +68,6 @@ static int inet_global_toip(lua_State *L)
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Returns all information provided by the resolver given a host name
|
* Returns all information provided by the resolver given a host name
|
||||||
* or ip address
|
* or ip address
|
||||||
* Lua Input: address
|
|
||||||
* address: ip address or host name to reverse dns lookup
|
|
||||||
* Lua Returns
|
|
||||||
* On success: canonic name followed by a resolved table
|
|
||||||
* On error: nil, followed by an error message
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static int inet_global_tohostname(lua_State *L)
|
static int inet_global_tohostname(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -102,11 +93,6 @@ static int inet_global_tohostname(lua_State *L)
|
|||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Retrieves socket peer name
|
* Retrieves socket peer name
|
||||||
* Input:
|
|
||||||
* sock: socket
|
|
||||||
* Lua Returns
|
|
||||||
* On success: ip address and port of peer
|
|
||||||
* On error: nil
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
int inet_meth_getpeername(lua_State *L, p_sock ps)
|
int inet_meth_getpeername(lua_State *L, p_sock ps)
|
||||||
{
|
{
|
||||||
@ -123,11 +109,6 @@ int inet_meth_getpeername(lua_State *L, p_sock ps)
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Retrieves socket local name
|
* Retrieves socket local name
|
||||||
* Input:
|
|
||||||
* sock: socket
|
|
||||||
* Lua Returns
|
|
||||||
* On success: local ip address and port
|
|
||||||
* On error: nil
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
int inet_meth_getsockname(lua_State *L, p_sock ps)
|
int inet_meth_getsockname(lua_State *L, p_sock ps)
|
||||||
{
|
{
|
||||||
@ -147,8 +128,6 @@ int inet_meth_getsockname(lua_State *L, p_sock ps)
|
|||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Passes all resolver information to Lua as a table
|
* Passes all resolver information to Lua as a table
|
||||||
* Input
|
|
||||||
* hp: hostent structure returned by resolver
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static void inet_pushresolved(lua_State *L, struct hostent *hp)
|
static void inet_pushresolved(lua_State *L, struct hostent *hp)
|
||||||
{
|
{
|
||||||
@ -185,12 +164,6 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp)
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Tries to connect to remote address (address, port)
|
* Tries to connect to remote address (address, port)
|
||||||
* Input
|
|
||||||
* ps: pointer to socket
|
|
||||||
* address: host name or ip address
|
|
||||||
* port: port number to bind to
|
|
||||||
* Returns
|
|
||||||
* NULL in case of success, error message otherwise
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *inet_tryconnect(p_sock ps, const char *address,
|
const char *inet_tryconnect(p_sock ps, const char *address,
|
||||||
unsigned short port)
|
unsigned short port)
|
||||||
@ -224,12 +197,6 @@ const char *inet_tryconnect(p_sock ps, const char *address,
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Tries to bind socket to (address, port)
|
* Tries to bind socket to (address, port)
|
||||||
* Input
|
|
||||||
* sock: pointer to socket
|
|
||||||
* address: host name or ip address
|
|
||||||
* port: port number to bind to
|
|
||||||
* Returns
|
|
||||||
* NULL in case of success, error message otherwise
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *inet_trybind(p_sock ps, const char *address, unsigned short port,
|
const char *inet_trybind(p_sock ps, const char *address, unsigned short port,
|
||||||
int backlog)
|
int backlog)
|
||||||
@ -264,10 +231,6 @@ const char *inet_trybind(p_sock ps, const char *address, unsigned short port,
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Tries to create a new inet socket
|
* Tries to create a new inet socket
|
||||||
* Input
|
|
||||||
* sock: pointer to socket
|
|
||||||
* Returns
|
|
||||||
* NULL if successfull, error message on error
|
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *inet_trycreate(p_sock ps, int type)
|
const char *inet_trycreate(p_sock ps, int type)
|
||||||
{
|
{
|
||||||
@ -299,3 +262,5 @@ int inet_aton(const char *cp, struct in_addr *inp)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
23
src/inet.h
23
src/inet.h
@ -1,25 +1,30 @@
|
|||||||
|
#ifndef INET_H
|
||||||
|
#define INET_H
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Internet domain functions
|
* Internet domain functions
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* This module implements the creation and connection of internet domain
|
||||||
|
* sockets, on top of the socket.h interface, and the interface of with the
|
||||||
|
* resolver.
|
||||||
|
*
|
||||||
|
* The function inet_aton is provided for the platforms where it is not
|
||||||
|
* available. The module also implements the interface of the internet
|
||||||
|
* getpeername and getsockname functions as seen by Lua programs.
|
||||||
|
*
|
||||||
|
* The Lua functions toip and tohostname are also implemented here.
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#ifndef INET_H
|
|
||||||
#define INET_H
|
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
|
||||||
* Exported functions
|
|
||||||
\*-------------------------------------------------------------------------*/
|
|
||||||
void inet_open(lua_State *L);
|
void inet_open(lua_State *L);
|
||||||
|
|
||||||
const char *inet_tryconnect(p_sock ps, const char *address,
|
const char *inet_tryconnect(p_sock ps, const char *address,
|
||||||
unsigned short port);
|
unsigned short port);
|
||||||
const char *inet_trybind(p_sock ps, const char *address,
|
const char *inet_trybind(p_sock ps, const char *address,
|
||||||
unsigned short port, int backlog);
|
unsigned short port, int backlog);
|
||||||
const char *inet_trycreate(p_sock ps, int type);
|
const char *inet_trycreate(p_sock ps, int type);
|
||||||
|
|
||||||
int inet_meth_getpeername(lua_State *L, p_sock ps);
|
int inet_meth_getpeername(lua_State *L, p_sock ps);
|
||||||
int inet_meth_getsockname(lua_State *L, p_sock ps);
|
int inet_meth_getsockname(lua_State *L, p_sock ps);
|
||||||
|
|
||||||
@ -27,4 +32,4 @@ int inet_meth_getsockname(lua_State *L, p_sock ps);
|
|||||||
int inet_aton(const char *cp, struct in_addr *inp);
|
int inet_aton(const char *cp, struct in_addr *inp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* INET_H_ */
|
#endif /* INET_H */
|
||||||
|
40
src/io.c
40
src/io.c
@ -1,8 +1,48 @@
|
|||||||
|
/*=========================================================================*\
|
||||||
|
* Input/Output abstraction
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* RCS ID: $Id$
|
||||||
|
\*=========================================================================*/
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
|
/*=========================================================================*\
|
||||||
|
* Exported functions
|
||||||
|
\*=========================================================================*/
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Initializes C structure
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
void io_init(p_io io, p_send send, p_recv recv, void *ctx)
|
void io_init(p_io io, p_send send, p_recv recv, void *ctx)
|
||||||
{
|
{
|
||||||
io->send = send;
|
io->send = send;
|
||||||
io->recv = recv;
|
io->recv = recv;
|
||||||
io->ctx = ctx;
|
io->ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Translate error codes to Lua
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
void io_pusherror(lua_State *L, int code)
|
||||||
|
{
|
||||||
|
switch (code) {
|
||||||
|
case IO_DONE:
|
||||||
|
lua_pushnil(L);
|
||||||
|
break;
|
||||||
|
case IO_TIMEOUT:
|
||||||
|
lua_pushstring(L, "timeout");
|
||||||
|
break;
|
||||||
|
case IO_LIMITED:
|
||||||
|
lua_pushstring(L, "limited");
|
||||||
|
break;
|
||||||
|
case IO_CLOSED:
|
||||||
|
lua_pushstring(L, "closed");
|
||||||
|
break;
|
||||||
|
case IO_REFUSED:
|
||||||
|
lua_pushstring(L, "refused");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lua_pushstring(L, "unknown error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
29
src/io.h
29
src/io.h
@ -1,16 +1,30 @@
|
|||||||
#ifndef IO_H
|
#ifndef IO_H
|
||||||
#define IO_H
|
#define IO_H
|
||||||
|
/*=========================================================================*\
|
||||||
|
* Input/Output abstraction
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* This module defines the interface that LuaSocket expects from the
|
||||||
|
* transport layer for streamed input/output. The idea is that if any
|
||||||
|
* transport implements this interface, then the buffer.c functions
|
||||||
|
* automatically work on it.
|
||||||
|
*
|
||||||
|
* The module socket.h implements this interface, and thus the module tcp.h
|
||||||
|
* is very simple.
|
||||||
|
*
|
||||||
|
* RCS ID: $Id$
|
||||||
|
\*=========================================================================*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <lua.h>
|
||||||
|
|
||||||
/* IO error codes */
|
/* IO error codes */
|
||||||
enum {
|
enum {
|
||||||
IO_DONE, /* operation completed successfully */
|
IO_DONE, /* operation completed successfully */
|
||||||
IO_TIMEOUT, /* operation timed out */
|
IO_TIMEOUT, /* operation timed out */
|
||||||
IO_CLOSED, /* the connection has been closed */
|
IO_CLOSED, /* the connection has been closed */
|
||||||
IO_ERROR, /* something wrong... */
|
IO_ERROR, /* something wrong... */
|
||||||
IO_REFUSED, /* transfer has been refused */
|
IO_REFUSED, /* transfer has been refused */
|
||||||
IO_LIMITED /* maximum number of bytes reached */
|
IO_LIMITED /* maximum number of bytes reached */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* interface to send function */
|
/* interface to send function */
|
||||||
@ -39,6 +53,7 @@ typedef struct t_io_ {
|
|||||||
} t_io;
|
} t_io;
|
||||||
typedef t_io *p_io;
|
typedef t_io *p_io;
|
||||||
|
|
||||||
|
void io_pusherror(lua_State *L, int code);
|
||||||
void io_init(p_io io, p_send send, p_recv recv, void *ctx);
|
void io_init(p_io io, p_send send, p_recv recv, void *ctx);
|
||||||
|
|
||||||
#endif /* IO_H */
|
#endif /* IO_H */
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
|
* LuaSocket toolkit
|
||||||
* Networking support for the Lua language
|
* Networking support for the Lua language
|
||||||
* Diego Nehab
|
* Diego Nehab
|
||||||
* 26/11/1999
|
* 26/11/1999
|
||||||
@ -7,7 +8,7 @@
|
|||||||
* connectivity of the Lua language. The Lua interface to networking
|
* connectivity of the Lua language. The Lua interface to networking
|
||||||
* functions follows the Sockets API closely, trying to simplify all tasks
|
* functions follows the Sockets API closely, trying to simplify all tasks
|
||||||
* involved in setting up both client and server connections. The provided
|
* involved in setting up both client and server connections. The provided
|
||||||
* IO routines, however, follow the Lua style, being very similar to the
|
* IO routines, however, follow the Lua style, being very similar to the
|
||||||
* standard Lua read and write functions.
|
* standard Lua read and write functions.
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
@ -24,6 +25,7 @@
|
|||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#include "luasocket.h"
|
#include "luasocket.h"
|
||||||
|
|
||||||
|
#include "auxiliar.h"
|
||||||
#include "timeout.h"
|
#include "timeout.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
@ -38,23 +40,11 @@
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes all library modules.
|
* Initializes all library modules.
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
LUASOCKET_API int luaopen_socketlib(lua_State *L)
|
LUASOCKET_API int luaopen_socket(lua_State *L)
|
||||||
{
|
{
|
||||||
if (!sock_open()) return 0;
|
if (!sock_open()) return 0;
|
||||||
/* create namespace table */
|
|
||||||
lua_pushstring(L, LUASOCKET_LIBNAME);
|
|
||||||
lua_newtable(L);
|
|
||||||
#ifdef LUASOCKET_DEBUG
|
|
||||||
lua_pushstring(L, "debug");
|
|
||||||
lua_pushnumber(L, 1);
|
|
||||||
lua_settable(L, -3);
|
|
||||||
#endif
|
|
||||||
lua_settable(L, LUA_GLOBALSINDEX);
|
|
||||||
/* make sure modules know what is our namespace */
|
|
||||||
lua_pushstring(L, "LUASOCKET_LIBNAME");
|
|
||||||
lua_pushstring(L, LUASOCKET_LIBNAME);
|
|
||||||
lua_settable(L, LUA_GLOBALSINDEX);
|
|
||||||
/* initialize all modules */
|
/* initialize all modules */
|
||||||
|
aux_open(L);
|
||||||
tm_open(L);
|
tm_open(L);
|
||||||
buf_open(L);
|
buf_open(L);
|
||||||
inet_open(L);
|
inet_open(L);
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
|
#ifndef LUASOCKET_H
|
||||||
|
#define LUASOCKET_H
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
|
* LuaSocket toolkit
|
||||||
* Networking support for the Lua language
|
* Networking support for the Lua language
|
||||||
* Diego Nehab
|
* Diego Nehab
|
||||||
* 9/11/1999
|
* 9/11/1999
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#ifndef LUASOCKET_H
|
#include <lua.h>
|
||||||
#define LUASOCKET_H
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Current luasocket version
|
* Current luasocket version
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
#define LUASOCKET_VERSION "LuaSocket 1.5 (alpha)"
|
#define LUASOCKET_VERSION "LuaSocket 2.0 (alpha)"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Library's namespace
|
* Library's namespace
|
||||||
@ -28,6 +30,6 @@
|
|||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Initializes the library.
|
* Initializes the library.
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
LUASOCKET_API int luaopen_socketlib(lua_State *L);
|
LUASOCKET_API int luaopen_socket(lua_State *L);
|
||||||
|
|
||||||
#endif /* LUASOCKET_H */
|
#endif /* LUASOCKET_H */
|
||||||
|
52
src/select.c
52
src/select.c
@ -1,5 +1,7 @@
|
|||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Select implementation
|
* Select implementation
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -12,6 +14,9 @@
|
|||||||
#include "auxiliar.h"
|
#include "auxiliar.h"
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
|
|
||||||
|
/*=========================================================================*\
|
||||||
|
* Internal function prototypes.
|
||||||
|
\*=========================================================================*/
|
||||||
static int meth_set(lua_State *L);
|
static int meth_set(lua_State *L);
|
||||||
static int meth_isset(lua_State *L);
|
static int meth_isset(lua_State *L);
|
||||||
static int c_select(lua_State *L);
|
static int c_select(lua_State *L);
|
||||||
@ -31,6 +36,12 @@ static luaL_reg func[] = {
|
|||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*=========================================================================*\
|
||||||
|
* Internal function prototypes.
|
||||||
|
\*=========================================================================*/
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Initializes module
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
void select_open(lua_State *L)
|
void select_open(lua_State *L)
|
||||||
{
|
{
|
||||||
/* get select auxiliar lua function from lua code and register
|
/* get select auxiliar lua function from lua code and register
|
||||||
@ -45,6 +56,9 @@ void select_open(lua_State *L)
|
|||||||
aux_newclass(L, "select{fd_set}", set);
|
aux_newclass(L, "select{fd_set}", set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*=========================================================================*\
|
||||||
|
* Global Lua functions
|
||||||
|
\*=========================================================================*/
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Waits for a set of sockets until a condition is met or timeout.
|
* Waits for a set of sockets until a condition is met or timeout.
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
@ -63,10 +77,10 @@ static int global_select(lua_State *L)
|
|||||||
lua_pushvalue(L, lua_upvalueindex(1));
|
lua_pushvalue(L, lua_upvalueindex(1));
|
||||||
lua_insert(L, 1);
|
lua_insert(L, 1);
|
||||||
/* pass fd_set objects */
|
/* pass fd_set objects */
|
||||||
read_fd_set = lua_newuserdata(L, sizeof(fd_set));
|
read_fd_set = (fd_set *) lua_newuserdata(L, sizeof(fd_set));
|
||||||
FD_ZERO(read_fd_set);
|
FD_ZERO(read_fd_set);
|
||||||
aux_setclass(L, "select{fd_set}", -1);
|
aux_setclass(L, "select{fd_set}", -1);
|
||||||
write_fd_set = lua_newuserdata(L, sizeof(fd_set));
|
write_fd_set = (fd_set *) lua_newuserdata(L, sizeof(fd_set));
|
||||||
FD_ZERO(write_fd_set);
|
FD_ZERO(write_fd_set);
|
||||||
aux_setclass(L, "select{fd_set}", -1);
|
aux_setclass(L, "select{fd_set}", -1);
|
||||||
/* pass select auxiliar C function */
|
/* pass select auxiliar C function */
|
||||||
@ -76,20 +90,9 @@ static int global_select(lua_State *L)
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int c_select(lua_State *L)
|
/*=========================================================================*\
|
||||||
{
|
* Lua methods
|
||||||
int max_fd = (int) lua_tonumber(L, 1);
|
\*=========================================================================*/
|
||||||
fd_set *read_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 2);
|
|
||||||
fd_set *write_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 3);
|
|
||||||
int timeout = lua_isnil(L, 4) ? -1 : (int)(lua_tonumber(L, 4) * 1000);
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = timeout / 1000;
|
|
||||||
tv.tv_usec = (timeout % 1000) * 1000;
|
|
||||||
lua_pushnumber(L, select(max_fd, read_fd_set, write_fd_set, NULL,
|
|
||||||
timeout < 0 ? NULL : &tv));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int meth_set(lua_State *L)
|
static int meth_set(lua_State *L)
|
||||||
{
|
{
|
||||||
fd_set *set = (fd_set *) aux_checkclass(L, "select{fd_set}", 1);
|
fd_set *set = (fd_set *) aux_checkclass(L, "select{fd_set}", 1);
|
||||||
@ -107,6 +110,23 @@ static int meth_isset(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*=========================================================================*\
|
||||||
|
* Internal functions
|
||||||
|
\*=========================================================================*/
|
||||||
|
static int c_select(lua_State *L)
|
||||||
|
{
|
||||||
|
int max_fd = (int) lua_tonumber(L, 1);
|
||||||
|
fd_set *read_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 2);
|
||||||
|
fd_set *write_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 3);
|
||||||
|
int timeout = lua_isnil(L, 4) ? -1 : (int)(lua_tonumber(L, 4) * 1000);
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = timeout / 1000;
|
||||||
|
tv.tv_usec = (timeout % 1000) * 1000;
|
||||||
|
lua_pushnumber(L, select(max_fd, read_fd_set, write_fd_set, NULL,
|
||||||
|
timeout < 0 ? NULL : &tv));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void check_obj_tab(lua_State *L, int tabidx)
|
static void check_obj_tab(lua_State *L, int tabidx)
|
||||||
{
|
{
|
||||||
if (tabidx < 0) tabidx = lua_gettop(L) + tabidx + 1;
|
if (tabidx < 0) tabidx = lua_gettop(L) + tabidx + 1;
|
||||||
|
18
src/select.h
18
src/select.h
@ -1,9 +1,19 @@
|
|||||||
/*=========================================================================*\
|
|
||||||
* Select implementation
|
|
||||||
* RCS ID: $Id$
|
|
||||||
\*=========================================================================*/
|
|
||||||
#ifndef SELECT_H
|
#ifndef SELECT_H
|
||||||
#define SELECT_H
|
#define SELECT_H
|
||||||
|
/*=========================================================================*\
|
||||||
|
* Select implementation
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* To make the code as simple as possible, the select function is
|
||||||
|
* implemented int Lua, with a few helper functions written in C.
|
||||||
|
*
|
||||||
|
* Each object that can be passed to the select function has to be in the
|
||||||
|
* group select{able} and export two methods: fd() and dirty(). Fd returns
|
||||||
|
* the descriptor to be passed to the select function. Dirty() should return
|
||||||
|
* true if there is data ready for reading (required for buffered input).
|
||||||
|
*
|
||||||
|
* RCS ID: $Id$
|
||||||
|
\*=========================================================================*/
|
||||||
|
|
||||||
void select_open(lua_State *L);
|
void select_open(lua_State *L);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- SMTP support for the Lua language.
|
-- SMTP support for the Lua language.
|
||||||
-- LuaSocket 1.5 toolkit
|
-- LuaSocket toolkit
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- Conforming to: RFC 821, LTN7
|
-- Conforming to: RFC 821, LTN7
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
|
15
src/socket.h
15
src/socket.h
@ -1,11 +1,16 @@
|
|||||||
|
#ifndef SOCK_H
|
||||||
|
#define SOCK_H
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Socket compatibilization module
|
* Socket compatibilization module
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* BSD Sockets and WinSock are similar, but there are a few irritating
|
||||||
|
* differences. Also, not all *nix platforms behave the same. This module
|
||||||
|
* (and the associated usocket.h and wsocket.h) factor these differences and
|
||||||
|
* creates a interface compatible with the io.h module.
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#ifndef SOCK_H
|
|
||||||
#define SOCK_H
|
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
@ -32,7 +37,6 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
|||||||
const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len);
|
const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len);
|
||||||
const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len);
|
const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len);
|
||||||
void sock_listen(p_sock ps, int backlog);
|
void sock_listen(p_sock ps, int backlog);
|
||||||
|
|
||||||
int sock_send(p_sock ps, const char *data, size_t count,
|
int sock_send(p_sock ps, const char *data, size_t count,
|
||||||
size_t *sent, int timeout);
|
size_t *sent, int timeout);
|
||||||
int sock_recv(p_sock ps, char *data, size_t count,
|
int sock_recv(p_sock ps, char *data, size_t count,
|
||||||
@ -41,11 +45,8 @@ int sock_sendto(p_sock ps, const char *data, size_t count,
|
|||||||
size_t *sent, SA *addr, socklen_t addr_len, int timeout);
|
size_t *sent, SA *addr, socklen_t addr_len, int timeout);
|
||||||
int sock_recvfrom(p_sock ps, char *data, size_t count,
|
int sock_recvfrom(p_sock ps, char *data, size_t count,
|
||||||
size_t *got, SA *addr, socklen_t *addr_len, int timeout);
|
size_t *got, SA *addr, socklen_t *addr_len, int timeout);
|
||||||
|
|
||||||
void sock_setnonblocking(p_sock ps);
|
void sock_setnonblocking(p_sock ps);
|
||||||
void sock_setblocking(p_sock ps);
|
void sock_setblocking(p_sock ps);
|
||||||
void sock_setreuseaddr(p_sock ps);
|
|
||||||
|
|
||||||
const char *sock_hoststrerror(void);
|
const char *sock_hoststrerror(void);
|
||||||
const char *sock_createstrerror(void);
|
const char *sock_createstrerror(void);
|
||||||
const char *sock_bindstrerror(void);
|
const char *sock_bindstrerror(void);
|
||||||
|
85
src/tcp.c
85
src/tcp.c
@ -1,5 +1,6 @@
|
|||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* TCP object
|
* TCP object
|
||||||
|
* LuaSocket toolkit
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
@ -13,7 +14,6 @@
|
|||||||
#include "auxiliar.h"
|
#include "auxiliar.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "inet.h"
|
#include "inet.h"
|
||||||
#include "error.h"
|
|
||||||
#include "tcp.h"
|
#include "tcp.h"
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
@ -28,9 +28,13 @@ static int meth_getpeername(lua_State *L);
|
|||||||
static int meth_receive(lua_State *L);
|
static int meth_receive(lua_State *L);
|
||||||
static int meth_accept(lua_State *L);
|
static int meth_accept(lua_State *L);
|
||||||
static int meth_close(lua_State *L);
|
static int meth_close(lua_State *L);
|
||||||
|
static int meth_setoption(lua_State *L);
|
||||||
static int meth_timeout(lua_State *L);
|
static int meth_timeout(lua_State *L);
|
||||||
static int meth_fd(lua_State *L);
|
static int meth_fd(lua_State *L);
|
||||||
static int meth_dirty(lua_State *L);
|
static int meth_dirty(lua_State *L);
|
||||||
|
static int opt_nodelay(lua_State *L);
|
||||||
|
static int opt_keepalive(lua_State *L);
|
||||||
|
static int opt_linger(lua_State *L);
|
||||||
|
|
||||||
/* tcp object methods */
|
/* tcp object methods */
|
||||||
static luaL_reg tcp[] = {
|
static luaL_reg tcp[] = {
|
||||||
@ -45,11 +49,21 @@ static luaL_reg tcp[] = {
|
|||||||
{"getsockname", meth_getsockname},
|
{"getsockname", meth_getsockname},
|
||||||
{"timeout", meth_timeout},
|
{"timeout", meth_timeout},
|
||||||
{"close", meth_close},
|
{"close", meth_close},
|
||||||
|
{"setoption", meth_setoption},
|
||||||
|
{"__gc", meth_close},
|
||||||
{"fd", meth_fd},
|
{"fd", meth_fd},
|
||||||
{"dirty", meth_dirty},
|
{"dirty", meth_dirty},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* socket option handlers */
|
||||||
|
static luaL_reg opt[] = {
|
||||||
|
{"keepalive", opt_keepalive},
|
||||||
|
{"nodelay", opt_nodelay},
|
||||||
|
{"linger", opt_linger},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
/* functions in library namespace */
|
/* functions in library namespace */
|
||||||
static luaL_reg func[] = {
|
static luaL_reg func[] = {
|
||||||
{"tcp", global_create},
|
{"tcp", global_create},
|
||||||
@ -71,6 +85,7 @@ void tcp_open(lua_State *L)
|
|||||||
aux_add2group(L, "tcp{server}", "tcp{any}");
|
aux_add2group(L, "tcp{server}", "tcp{any}");
|
||||||
aux_add2group(L, "tcp{client}", "tcp{client, server}");
|
aux_add2group(L, "tcp{client}", "tcp{client, server}");
|
||||||
aux_add2group(L, "tcp{server}", "tcp{client, server}");
|
aux_add2group(L, "tcp{server}", "tcp{client, server}");
|
||||||
|
/* both server and client objects are selectable */
|
||||||
aux_add2group(L, "tcp{client}", "select{able}");
|
aux_add2group(L, "tcp{client}", "select{able}");
|
||||||
aux_add2group(L, "tcp{server}", "select{able}");
|
aux_add2group(L, "tcp{server}", "select{able}");
|
||||||
/* define library functions */
|
/* define library functions */
|
||||||
@ -96,19 +111,81 @@ static int meth_receive(lua_State *L)
|
|||||||
return buf_meth_receive(L, &tcp->buf);
|
return buf_meth_receive(L, &tcp->buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Option handlers
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
static int meth_setoption(lua_State *L)
|
||||||
|
{
|
||||||
|
return aux_meth_setoption(L, opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opt_boolean(lua_State *L, int level, int name)
|
||||||
|
{
|
||||||
|
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
|
||||||
|
int val = aux_checkboolean(L, 2);
|
||||||
|
if (setsockopt(tcp->sock, level, name, (char *) &val, sizeof(val)) < 0) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_pushstring(L, "setsockopt failed");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
lua_pushnumber(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disables the Nagle algorithm */
|
||||||
|
static int opt_nodelay(lua_State *L)
|
||||||
|
{
|
||||||
|
struct protoent *pe = getprotobyname("TCP");
|
||||||
|
if (!pe) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_pushstring(L, "getprotobyname");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return opt_boolean(L, pe->p_proto, TCP_NODELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opt_keepalive(lua_State *L)
|
||||||
|
{
|
||||||
|
return opt_boolean(L, SOL_SOCKET, SO_KEEPALIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int opt_linger(lua_State *L)
|
||||||
|
{
|
||||||
|
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1);
|
||||||
|
struct linger li;
|
||||||
|
if (!lua_istable(L, 2))
|
||||||
|
luaL_typerror(L, 2, lua_typename(L, LUA_TTABLE));
|
||||||
|
lua_pushstring(L, "onoff");
|
||||||
|
lua_gettable(L, 2);
|
||||||
|
if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid onoff field");
|
||||||
|
li.l_onoff = (int) lua_tonumber(L, -1);
|
||||||
|
lua_pushstring(L, "linger");
|
||||||
|
lua_gettable(L, 2);
|
||||||
|
if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid linger field");
|
||||||
|
li.l_linger = (int) lua_tonumber(L, -1);
|
||||||
|
if (setsockopt(tcp->sock, SOL_SOCKET, SO_LINGER,
|
||||||
|
(char *) &li, sizeof(li) < 0)) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_pushstring(L, "setsockopt failed");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
lua_pushnumber(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Select support methods
|
* Select support methods
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static int meth_fd(lua_State *L)
|
static int meth_fd(lua_State *L)
|
||||||
{
|
{
|
||||||
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client, server}", 1);
|
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1);
|
||||||
lua_pushnumber(L, tcp->sock);
|
lua_pushnumber(L, tcp->sock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int meth_dirty(lua_State *L)
|
static int meth_dirty(lua_State *L)
|
||||||
{
|
{
|
||||||
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client, server}", 1);
|
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1);
|
||||||
lua_pushboolean(L, !buf_isempty(&tcp->buf));
|
lua_pushboolean(L, !buf_isempty(&tcp->buf));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -207,7 +284,7 @@ static int meth_accept(lua_State *L)
|
|||||||
if (client->sock == SOCK_INVALID) {
|
if (client->sock == SOCK_INVALID) {
|
||||||
if (tm_get(tm) == 0) {
|
if (tm_get(tm) == 0) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
error_push(L, IO_TIMEOUT);
|
io_pusherror(L, IO_TIMEOUT);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
} else break;
|
} else break;
|
||||||
|
19
src/tcp.h
19
src/tcp.h
@ -1,6 +1,21 @@
|
|||||||
#ifndef TCP_H
|
#ifndef TCP_H
|
||||||
#define TCP_H
|
#define TCP_H
|
||||||
|
/*=========================================================================*\
|
||||||
|
* TCP object
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* The tcp.h module is basicly a glue that puts together modules buffer.h,
|
||||||
|
* timeout.h socket.h and inet.h to provide the LuaSocket TCP (AF_INET,
|
||||||
|
* SOCK_STREAM) support.
|
||||||
|
*
|
||||||
|
* Three classes are defined: master, client and server. The master class is
|
||||||
|
* a newly created tcp object, that has not been bound or connected. Server
|
||||||
|
* objects are tcp objects bound to some local address. Client objects are
|
||||||
|
* tcp objects either connected to some address or returned by the accept
|
||||||
|
* method of a server object.
|
||||||
|
*
|
||||||
|
* RCS ID: $Id$
|
||||||
|
\*=========================================================================*/
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
@ -17,4 +32,4 @@ typedef t_tcp *p_tcp;
|
|||||||
|
|
||||||
void tcp_open(lua_State *L);
|
void tcp_open(lua_State *L);
|
||||||
|
|
||||||
#endif
|
#endif /* TCP_H */
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Timeout management functions
|
* Timeout management functions
|
||||||
* Global Lua functions:
|
* LuaSocket toolkit
|
||||||
* _sleep
|
|
||||||
* _time
|
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
|
#ifndef TM_H
|
||||||
|
#define TM_H
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Timeout management functions
|
* Timeout management functions
|
||||||
|
* LuaSocket toolkit
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#ifndef TM_H
|
|
||||||
#define TM_H
|
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
|
||||||
/* timeout control structure */
|
/* timeout control structure */
|
||||||
@ -28,4 +28,4 @@ int tm_get(p_tm tm);
|
|||||||
int tm_gettime(void);
|
int tm_gettime(void);
|
||||||
int tm_meth_timeout(lua_State *L, p_tm tm);
|
int tm_meth_timeout(lua_State *L, p_tm tm);
|
||||||
|
|
||||||
#endif
|
#endif /* TM_H */
|
||||||
|
61
src/udp.c
61
src/udp.c
@ -1,5 +1,6 @@
|
|||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* UDP object
|
* UDP object
|
||||||
|
* LuaSocket toolkit
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
@ -13,7 +14,6 @@
|
|||||||
#include "auxiliar.h"
|
#include "auxiliar.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "inet.h"
|
#include "inet.h"
|
||||||
#include "error.h"
|
|
||||||
#include "udp.h"
|
#include "udp.h"
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
@ -29,9 +29,12 @@ static int meth_getpeername(lua_State *L);
|
|||||||
static int meth_setsockname(lua_State *L);
|
static int meth_setsockname(lua_State *L);
|
||||||
static int meth_setpeername(lua_State *L);
|
static int meth_setpeername(lua_State *L);
|
||||||
static int meth_close(lua_State *L);
|
static int meth_close(lua_State *L);
|
||||||
|
static int meth_setoption(lua_State *L);
|
||||||
static int meth_timeout(lua_State *L);
|
static int meth_timeout(lua_State *L);
|
||||||
static int meth_fd(lua_State *L);
|
static int meth_fd(lua_State *L);
|
||||||
static int meth_dirty(lua_State *L);
|
static int meth_dirty(lua_State *L);
|
||||||
|
static int opt_dontroute(lua_State *L);
|
||||||
|
static int opt_broadcast(lua_State *L);
|
||||||
|
|
||||||
/* udp object methods */
|
/* udp object methods */
|
||||||
static luaL_reg udp[] = {
|
static luaL_reg udp[] = {
|
||||||
@ -45,11 +48,20 @@ static luaL_reg udp[] = {
|
|||||||
{"receivefrom", meth_receivefrom},
|
{"receivefrom", meth_receivefrom},
|
||||||
{"timeout", meth_timeout},
|
{"timeout", meth_timeout},
|
||||||
{"close", meth_close},
|
{"close", meth_close},
|
||||||
|
{"setoption", meth_setoption},
|
||||||
|
{"__gc", meth_close},
|
||||||
{"fd", meth_fd},
|
{"fd", meth_fd},
|
||||||
{"dirty", meth_dirty},
|
{"dirty", meth_dirty},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* socket options */
|
||||||
|
static luaL_reg opt[] = {
|
||||||
|
{"dontroute", opt_dontroute},
|
||||||
|
{"broadcast", opt_broadcast},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
/* functions in library namespace */
|
/* functions in library namespace */
|
||||||
static luaL_reg func[] = {
|
static luaL_reg func[] = {
|
||||||
{"udp", global_create},
|
{"udp", global_create},
|
||||||
@ -91,7 +103,9 @@ static int meth_send(lua_State *L)
|
|||||||
err = sock_send(&udp->sock, data, count, &sent, tm_get(tm));
|
err = sock_send(&udp->sock, data, count, &sent, tm_get(tm));
|
||||||
if (err == IO_DONE) lua_pushnumber(L, sent);
|
if (err == IO_DONE) lua_pushnumber(L, sent);
|
||||||
else lua_pushnil(L);
|
else lua_pushnil(L);
|
||||||
error_push(L, err);
|
/* a 'closed' error on an unconnected means the target address was not
|
||||||
|
* accepted by the transport layer */
|
||||||
|
io_pusherror(L, err == IO_CLOSED ? IO_REFUSED : err);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +132,9 @@ static int meth_sendto(lua_State *L)
|
|||||||
(SA *) &addr, sizeof(addr), tm_get(tm));
|
(SA *) &addr, sizeof(addr), tm_get(tm));
|
||||||
if (err == IO_DONE) lua_pushnumber(L, sent);
|
if (err == IO_DONE) lua_pushnumber(L, sent);
|
||||||
else lua_pushnil(L);
|
else lua_pushnil(L);
|
||||||
error_push(L, err == IO_CLOSED ? IO_REFUSED : err);
|
/* a 'closed' error on an unconnected means the target address was not
|
||||||
|
* accepted by the transport layer */
|
||||||
|
io_pusherror(L, err == IO_CLOSED ? IO_REFUSED : err);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +153,7 @@ static int meth_receive(lua_State *L)
|
|||||||
err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm));
|
err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm));
|
||||||
if (err == IO_DONE) lua_pushlstring(L, buffer, got);
|
if (err == IO_DONE) lua_pushlstring(L, buffer, got);
|
||||||
else lua_pushnil(L);
|
else lua_pushnil(L);
|
||||||
error_push(L, err);
|
io_pusherror(L, err);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +180,7 @@ static int meth_receivefrom(lua_State *L)
|
|||||||
return 3;
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
error_push(L, err);
|
io_pusherror(L, err);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,14 +190,14 @@ static int meth_receivefrom(lua_State *L)
|
|||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
static int meth_fd(lua_State *L)
|
static int meth_fd(lua_State *L)
|
||||||
{
|
{
|
||||||
p_udp udp = (p_udp) aux_checkclass(L, "udp{any}", 1);
|
p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1);
|
||||||
lua_pushnumber(L, udp->sock);
|
lua_pushnumber(L, udp->sock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int meth_dirty(lua_State *L)
|
static int meth_dirty(lua_State *L)
|
||||||
{
|
{
|
||||||
p_udp udp = (p_udp) aux_checkclass(L, "udp{any}", 1);
|
p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1);
|
||||||
(void) udp;
|
(void) udp;
|
||||||
lua_pushboolean(L, 0);
|
lua_pushboolean(L, 0);
|
||||||
return 1;
|
return 1;
|
||||||
@ -202,6 +218,37 @@ static int meth_getsockname(lua_State *L)
|
|||||||
return inet_meth_getsockname(L, &udp->sock);
|
return inet_meth_getsockname(L, &udp->sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Option handlers
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
static int meth_setoption(lua_State *L)
|
||||||
|
{
|
||||||
|
return aux_meth_setoption(L, opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opt_boolean(lua_State *L, int level, int name)
|
||||||
|
{
|
||||||
|
p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1);
|
||||||
|
int val = aux_checkboolean(L, 2);
|
||||||
|
if (setsockopt(udp->sock, level, name, (char *) &val, sizeof(val)) < 0) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_pushstring(L, "setsockopt failed");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
lua_pushnumber(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opt_dontroute(lua_State *L)
|
||||||
|
{
|
||||||
|
return opt_boolean(L, SOL_SOCKET, SO_DONTROUTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int opt_broadcast(lua_State *L)
|
||||||
|
{
|
||||||
|
return opt_boolean(L, SOL_SOCKET, SO_BROADCAST);
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------------*\
|
||||||
* Just call tm methods
|
* Just call tm methods
|
||||||
\*-------------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------------*/
|
||||||
|
17
src/udp.h
17
src/udp.h
@ -1,6 +1,19 @@
|
|||||||
#ifndef UDP_H
|
#ifndef UDP_H
|
||||||
#define UDP_H
|
#define UDP_H
|
||||||
|
/*=========================================================================*\
|
||||||
|
* UDP object
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* The udp.h module provides LuaSocket with support for UDP protocol
|
||||||
|
* (AF_INET, SOCK_DGRAM).
|
||||||
|
*
|
||||||
|
* Two classes are defined: connected and unconnected. UDP objects are
|
||||||
|
* originally unconnected. They can be "connected" to a given address
|
||||||
|
* with a call to the setpeername function. The same function can be used to
|
||||||
|
* break the connection.
|
||||||
|
*
|
||||||
|
* RCS ID: $Id$
|
||||||
|
\*=========================================================================*/
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
|
||||||
#include "timeout.h"
|
#include "timeout.h"
|
||||||
@ -16,4 +29,4 @@ typedef t_udp *p_udp;
|
|||||||
|
|
||||||
void udp_open(lua_State *L);
|
void udp_open(lua_State *L);
|
||||||
|
|
||||||
#endif
|
#endif /* UDP_H */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- URI parsing, composition and relative URL resolution
|
-- URI parsing, composition and relative URL resolution
|
||||||
-- LuaSocket 1.5 toolkit.
|
-- LuaSocket toolkit.
|
||||||
-- Author: Diego Nehab
|
-- Author: Diego Nehab
|
||||||
-- Conforming to: RFC 2396, LTN7
|
-- Conforming to: RFC 2396, LTN7
|
||||||
-- RCS ID: $Id$
|
-- RCS ID: $Id$
|
||||||
|
@ -1,49 +1,78 @@
|
|||||||
|
/*=========================================================================*\
|
||||||
|
* Socket compatibilization module for Unix
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* RCS ID: $Id$
|
||||||
|
\*=========================================================================*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Initializes module
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_open(void)
|
int sock_open(void)
|
||||||
{
|
{
|
||||||
/* instals a handler to ignore sigpipe. */
|
/* instals a handler to ignore sigpipe or it will crash us */
|
||||||
struct sigaction new;
|
struct sigaction ignore;
|
||||||
memset(&new, 0, sizeof(new));
|
memset(&ignore, 0, sizeof(ignore));
|
||||||
new.sa_handler = SIG_IGN;
|
ignore.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &new, NULL);
|
sigaction(SIGPIPE, &ignore, NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Close and inutilize socket
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
void sock_destroy(p_sock ps)
|
void sock_destroy(p_sock ps)
|
||||||
{
|
{
|
||||||
close(*ps);
|
close(*ps);
|
||||||
|
*ps = SOCK_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Creates and sets up a socket
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_create(p_sock ps, int domain, int type, int protocol)
|
const char *sock_create(p_sock ps, int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
|
int val = 1;
|
||||||
t_sock sock = socket(domain, type, protocol);
|
t_sock sock = socket(domain, type, protocol);
|
||||||
if (sock == SOCK_INVALID) return sock_createstrerror();
|
if (sock == SOCK_INVALID) return sock_createstrerror();
|
||||||
*ps = sock;
|
*ps = sock;
|
||||||
sock_setnonblocking(ps);
|
sock_setnonblocking(ps);
|
||||||
sock_setreuseaddr(ps);
|
setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Connects or returns error message
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len)
|
const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len)
|
||||||
{
|
{
|
||||||
if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror();
|
if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror();
|
||||||
else return NULL;
|
else return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Binds or returns error message
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len)
|
const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len)
|
||||||
{
|
{
|
||||||
if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror();
|
if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror();
|
||||||
else return NULL;
|
else return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
*
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
void sock_listen(p_sock ps, int backlog)
|
void sock_listen(p_sock ps, int backlog)
|
||||||
{
|
{
|
||||||
listen(*ps, backlog);
|
listen(*ps, backlog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Accept with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
@ -65,6 +94,9 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
|||||||
else return IO_DONE;
|
else return IO_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Send with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
@ -99,6 +131,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Sendto with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
||||||
SA *addr, socklen_t addr_len, int timeout)
|
SA *addr, socklen_t addr_len, int timeout)
|
||||||
{
|
{
|
||||||
@ -133,6 +168,9 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Receive with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
||||||
{
|
{
|
||||||
t_sock sock = *ps;
|
t_sock sock = *ps;
|
||||||
@ -160,6 +198,9 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Recvfrom with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
|
int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
|
||||||
SA *addr, socklen_t *addr_len, int timeout)
|
SA *addr, socklen_t *addr_len, int timeout)
|
||||||
{
|
{
|
||||||
@ -188,6 +229,29 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Put socket into blocking mode
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
void sock_setblocking(p_sock ps)
|
||||||
|
{
|
||||||
|
int flags = fcntl(*ps, F_GETFL, 0);
|
||||||
|
flags &= (~(O_NONBLOCK));
|
||||||
|
fcntl(*ps, F_SETFL, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Put socket into non-blocking mode
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
void sock_setnonblocking(p_sock ps)
|
||||||
|
{
|
||||||
|
int flags = fcntl(*ps, F_GETFL, 0);
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
fcntl(*ps, F_SETFL, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Error translation functions
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_hoststrerror(void)
|
const char *sock_hoststrerror(void)
|
||||||
{
|
{
|
||||||
switch (h_errno) {
|
switch (h_errno) {
|
||||||
@ -238,23 +302,3 @@ const char *sock_connectstrerror(void)
|
|||||||
default: return "unknown error";
|
default: return "unknown error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sock_setreuseaddr(p_sock ps)
|
|
||||||
{
|
|
||||||
int val = 1;
|
|
||||||
setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
void sock_setblocking(p_sock ps)
|
|
||||||
{
|
|
||||||
int flags = fcntl(*ps, F_GETFL, 0);
|
|
||||||
flags &= (~(O_NONBLOCK));
|
|
||||||
fcntl(*ps, F_SETFL, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sock_setnonblocking(p_sock ps)
|
|
||||||
{
|
|
||||||
int flags = fcntl(*ps, F_GETFL, 0);
|
|
||||||
flags |= O_NONBLOCK;
|
|
||||||
fcntl(*ps, F_SETFL, flags);
|
|
||||||
}
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
#ifndef USOCKET_H
|
||||||
|
#define USOCKET_H
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Socket compatibilization module for Unix
|
* Socket compatibilization module for Unix
|
||||||
|
* LuaSocket toolkit
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#ifndef USOCKET_H
|
|
||||||
#define USOCKET_H
|
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* BSD include files
|
* BSD include files
|
||||||
@ -30,9 +31,11 @@
|
|||||||
/* IP stuff*/
|
/* IP stuff*/
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
/* TCP options (nagle algorithm disable) */
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
/* for some reason socklen_t is not defined in mac os x */
|
/* for some reason socklen_t is not defined in Mac Os X */
|
||||||
typedef int socklen_t;
|
typedef int socklen_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
|
/*=========================================================================*\
|
||||||
|
* Socket compatibilization module for Win32
|
||||||
|
* LuaSocket toolkit
|
||||||
|
*
|
||||||
|
* RCS ID: $Id$
|
||||||
|
\*=========================================================================*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Initializes module
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_open(void)
|
int sock_open(void)
|
||||||
{
|
{
|
||||||
WORD wVersionRequested;
|
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
int err;
|
WORD wVersionRequested = MAKEWORD(2, 0);
|
||||||
wVersionRequested = MAKEWORD(2, 0);
|
int err = WSAStartup(wVersionRequested, &wsaData );
|
||||||
err = WSAStartup(wVersionRequested, &wsaData );
|
|
||||||
if (err != 0) return 0;
|
if (err != 0) return 0;
|
||||||
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) {
|
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) {
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
@ -17,38 +24,58 @@ int sock_open(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Close and inutilize socket
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
void sock_destroy(p_sock ps)
|
void sock_destroy(p_sock ps)
|
||||||
{
|
{
|
||||||
closesocket(*ps);
|
closesocket(*ps);
|
||||||
|
*ps = SOCK_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Creates and sets up a socket
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_create(p_sock ps, int domain, int type, int protocol)
|
const char *sock_create(p_sock ps, int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
|
int val = 1;
|
||||||
t_sock sock = socket(domain, type, protocol);
|
t_sock sock = socket(domain, type, protocol);
|
||||||
if (sock == SOCK_INVALID) return sock_createstrerror();
|
if (sock == SOCK_INVALID) return sock_createstrerror();
|
||||||
*ps = sock;
|
*ps = sock;
|
||||||
sock_setnonblocking(ps);
|
sock_setnonblocking(ps);
|
||||||
sock_setreuseaddr(ps);
|
setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Connects or returns error message
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len)
|
const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len)
|
||||||
{
|
{
|
||||||
if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror();
|
if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror();
|
||||||
else return NULL;
|
else return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Binds or returns error message
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len)
|
const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len)
|
||||||
{
|
{
|
||||||
if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror();
|
if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror();
|
||||||
else return NULL;
|
else return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
*
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
void sock_listen(p_sock ps, int backlog)
|
void sock_listen(p_sock ps, int backlog)
|
||||||
{
|
{
|
||||||
listen(*ps, backlog);
|
listen(*ps, backlog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Accept with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
@ -70,6 +97,9 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
|
|||||||
else return IO_DONE;
|
else return IO_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Send with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
@ -104,6 +134,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Sendto with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
||||||
SA *addr, socklen_t addr_len, int timeout)
|
SA *addr, socklen_t addr_len, int timeout)
|
||||||
{
|
{
|
||||||
@ -138,6 +171,9 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Receive with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
||||||
{
|
{
|
||||||
t_sock sock = *ps;
|
t_sock sock = *ps;
|
||||||
@ -165,6 +201,9 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Recvfrom with timeout
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
|
int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
|
||||||
SA *addr, socklen_t *addr_len, int timeout)
|
SA *addr, socklen_t *addr_len, int timeout)
|
||||||
{
|
{
|
||||||
@ -193,6 +232,27 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Put socket into blocking mode
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
void sock_setblocking(p_sock ps)
|
||||||
|
{
|
||||||
|
u_long argp = 0;
|
||||||
|
ioctlsocket(*ps, FIONBIO, &argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Put socket into non-blocking mode
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
|
void sock_setnonblocking(p_sock ps)
|
||||||
|
{
|
||||||
|
u_long argp = 1;
|
||||||
|
ioctlsocket(*ps, FIONBIO, &argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*\
|
||||||
|
* Error translation functions
|
||||||
|
\*-------------------------------------------------------------------------*/
|
||||||
const char *sock_hoststrerror(void)
|
const char *sock_hoststrerror(void)
|
||||||
{
|
{
|
||||||
switch (WSAGetLastError()) {
|
switch (WSAGetLastError()) {
|
||||||
@ -241,21 +301,3 @@ const char *sock_connectstrerror(void)
|
|||||||
default: return "unknown error";
|
default: return "unknown error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sock_setreuseaddr(p_sock ps)
|
|
||||||
{
|
|
||||||
int val = 1;
|
|
||||||
setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
void sock_setblocking(p_sock ps)
|
|
||||||
{
|
|
||||||
u_long argp = 0;
|
|
||||||
ioctlsocket(*ps, FIONBIO, &argp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sock_setnonblocking(p_sock ps)
|
|
||||||
{
|
|
||||||
u_long argp = 1;
|
|
||||||
ioctlsocket(*ps, FIONBIO, &argp);
|
|
||||||
}
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
|
#ifndef WSOCKET_H
|
||||||
|
#define WSOCKET_H
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* Socket compatibilization module for Win32
|
* Socket compatibilization module for Win32
|
||||||
|
* LuaSocket toolkit
|
||||||
*
|
*
|
||||||
* RCS ID: $Id$
|
* RCS ID: $Id$
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#ifndef WSOCKET_H
|
|
||||||
#define WSOCKET_H
|
|
||||||
|
|
||||||
/*=========================================================================*\
|
/*=========================================================================*\
|
||||||
* WinSock2 include files
|
* WinSock include files
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
#include <winsock2.h>
|
#include <winsock.h>
|
||||||
#include <winbase.h>
|
|
||||||
|
|
||||||
typedef int socklen_t;
|
typedef int socklen_t;
|
||||||
typedef int ssize_t;
|
typedef int ssize_t;
|
||||||
|
@ -17,12 +17,14 @@ function warn(...)
|
|||||||
io.write("WARNING: ", s, "\n")
|
io.write("WARNING: ", s, "\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
pad = string.rep(" ", 8192)
|
||||||
|
|
||||||
function remote(...)
|
function remote(...)
|
||||||
local s = string.format(unpack(arg))
|
local s = string.format(unpack(arg))
|
||||||
s = string.gsub(s, "\n", ";")
|
s = string.gsub(s, "\n", ";")
|
||||||
s = string.gsub(s, "%s+", " ")
|
s = string.gsub(s, "%s+", " ")
|
||||||
s = string.gsub(s, "^%s*", "")
|
s = string.gsub(s, "^%s*", "")
|
||||||
control:send(s, "\n")
|
control:send(pad, s, "\n")
|
||||||
control:receive()
|
control:receive()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -82,16 +84,19 @@ function reconnect()
|
|||||||
remote [[
|
remote [[
|
||||||
if data then data:close() data = nil end
|
if data then data:close() data = nil end
|
||||||
data = server:accept()
|
data = server:accept()
|
||||||
|
data:setoption("nodelay", true)
|
||||||
]]
|
]]
|
||||||
data, err = socket.connect(host, port)
|
data, err = socket.connect(host, port)
|
||||||
if not data then fail(err)
|
if not data then fail(err)
|
||||||
else pass("connected!") end
|
else pass("connected!") end
|
||||||
|
data:setoption("nodelay", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
pass("attempting control connection...")
|
pass("attempting control connection...")
|
||||||
control, err = socket.connect(host, port)
|
control, err = socket.connect(host, port)
|
||||||
if err then fail(err)
|
if err then fail(err)
|
||||||
else pass("connected!") end
|
else pass("connected!") end
|
||||||
|
control:setoption("nodelay", true)
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
test("method registration")
|
test("method registration")
|
||||||
@ -157,16 +162,21 @@ remote "data:send(str); data:close()"
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
test_mixed(1)
|
--test_mixed(1)
|
||||||
test_mixed(17)
|
--test_mixed(17)
|
||||||
test_mixed(200)
|
--test_mixed(200)
|
||||||
test_mixed(4091)
|
--test_mixed(4091)
|
||||||
test_mixed(80199)
|
--test_mixed(80199)
|
||||||
test_mixed(4091)
|
--test_mixed(4091)
|
||||||
test_mixed(200)
|
--test_mixed(200)
|
||||||
test_mixed(17)
|
--test_mixed(17)
|
||||||
test_mixed(1)
|
--test_mixed(1)
|
||||||
|
|
||||||
|
test_mixed(4091)
|
||||||
|
test_mixed(4091)
|
||||||
|
test_mixed(4091)
|
||||||
|
test_mixed(4091)
|
||||||
|
test_mixed(4091)
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
test("character line")
|
test("character line")
|
||||||
reconnect()
|
reconnect()
|
||||||
|
@ -3,9 +3,11 @@ port = port or "8080"
|
|||||||
|
|
||||||
server, error = socket.bind(host, port)
|
server, error = socket.bind(host, port)
|
||||||
if not server then print("server: " .. tostring(error)) os.exit() end
|
if not server then print("server: " .. tostring(error)) os.exit() end
|
||||||
|
ack = "\n"
|
||||||
while 1 do
|
while 1 do
|
||||||
print("server: waiting for client connection...");
|
print("server: waiting for client connection...");
|
||||||
control = server:accept()
|
control = server:accept()
|
||||||
|
control:setoption("nodelay", true)
|
||||||
while 1 do
|
while 1 do
|
||||||
command, error = control:receive()
|
command, error = control:receive()
|
||||||
if error then
|
if error then
|
||||||
@ -13,13 +15,12 @@ while 1 do
|
|||||||
print("server: closing connection...")
|
print("server: closing connection...")
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
sent, error = control:send("\n")
|
sent, error = control:send(ack)
|
||||||
if error then
|
if error then
|
||||||
control:close()
|
control:close()
|
||||||
print("server: closing connection...")
|
print("server: closing connection...")
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
print(command);
|
|
||||||
(loadstring(command))()
|
(loadstring(command))()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user