Adjusted a few inconsistencies with the manual.

This commit is contained in:
Diego Nehab 2003-08-16 00:06:04 +00:00
parent 3099704aff
commit c51d4acf1c
20 changed files with 412 additions and 156 deletions

30
TODO
View File

@ -1,8 +1,34 @@
- Melhorar a interface de setoptions (aceitar nada como true, por exemplo) URL e URI eh a mesma coisa?
Check spelling
Fazer uma página com os exemplos.
Ajeitar links pras RFCs.
Usar DFN no lugar de <i> pra definiccoes.
Usar VAR pra argumentos?
Usar CODE pros trechos? funciona como PRE?
Usar PRE { margin-botton: 1em; } pra pular linha antes do </pre>
Trocar todos os <a name=bla> por <... id=bla>?
Make sure all .html are STRICT 4.01
Add license.txt.
Check RFC links.
Add lots of hyperlinks
Check all function names (must use . or :)
Make sure IPv4 goes away
The words function and method should follow the convention
Adjust dates in all files
Test the library on every system possible
Document socket.time and socket.sleep
Create the windows executable.
Implement time critical stuff from code module in C.
Add service name translation.
Ajeitar o protocolo da lua_socketlibopen()...
- testar os options!
- testar em várias plataformas - testar em várias plataformas
- adicionar exemplos de expansão: pipe, local, named pipe - adicionar exemplos de expansão: pipe, local, named pipe
* 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 5.0 * Ajeitar para Lua 5.0

View File

@ -32,7 +32,7 @@ end
function dict_open() function dict_open()
local sock, err = socket.connect("dict.org", 2628) local sock, err = socket.connect("dict.org", 2628)
if not sock then return nil, err end if not sock then return nil, err end
sock:timeout(10) sock:settimeout(10)
local code, par = get_status(sock, 220) local code, par = get_status(sock, 220)
if code then return nil, code end if code then return nil, code end
return sock return sock

View File

@ -82,8 +82,8 @@ function Public.get(url)
local udp, err = socket.udp() local udp, err = socket.udp()
if not udp then return nil, err end if not udp then return nil, err end
-- convert from name to ip if needed -- convert from name to ip if needed
parsed.host = socket.toip(parsed.host) parsed.host = socket.dns.toip(parsed.host)
udp:timeout(1) udp:settimeout(1)
-- first packet gives data host/port to be used for data transfers -- first packet gives data host/port to be used for data transfers
retries = 0 retries = 0
repeat repeat

210
logo.ps Normal file
View File

@ -0,0 +1,210 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: Lua logo
%%Creator: lua@tecgraf.puc-rio.br
%%CreationDate: Wed Nov 29 19:04:04 EDT 2000
%%BoundingBox: -45 0 1035 1080
%%Pages: 1
%%EndComments
%%EndProlog
%------------------------------------------------------------------------------
%
% Copyright (C) 1998-2000. All rights reserved.
% Graphic design by Alexandre Nakonechny (nako@openlink.com.br).
% PostScript programming by the Lua team (lua@tecgraf.puc-rio.br).
%
% Permission is hereby granted, without written agreement and without license
% or royalty fees, to use, copy, and distribute this logo for any purpose,
% including commercial applications, subject to the following conditions:
%
% * The origin of this logo must not be misrepresented; you must not
% claim that you drew the original logo. We recommend that you give credit
% to the graphics designer in all printed matter that includes the logo.
%
% * The only modification you can make is to adapt the orbiting text to
% your product name.
%
% * The logo can be used in any scale as long as the relative proportions
% of its elements are maintained.
%
%------------------------------------------------------------------------------
/LABEL (tekcoS) def
%-- DO NOT CHANGE ANYTHING BELOW THIS LINE ------------------------------------
/PLANETCOLOR {0 0 0.5 setrgbcolor} bind def
/HOLECOLOR {1.0 setgray} bind def
/ORBITCOLOR {0.5 setgray} bind def
/LOGOFONT {/Helvetica 0.90} def
/LABELFONT {/Helvetica 0.36} def
%------------------------------------------------------------------------------
/MOONCOLOR {PLANETCOLOR} bind def
/LOGOCOLOR {HOLECOLOR} bind def
/LABELCOLOR {ORBITCOLOR} bind def
/LABELANGLE 325 def
/LOGO (Lua) def
/DASHANGLE 10 def
/HALFDASHANGLE DASHANGLE 2 div def
% moon radius. planet radius is 1.
/r 1 2 sqrt 2 div sub def
/D {0 360 arc fill} bind def
/F {exch findfont exch scalefont setfont} bind def
% place it nicely on the paper
/RESOLUTION 1024 def
RESOLUTION 2 div dup translate
RESOLUTION 2 div 2 sqrt div dup scale
%-------------------------------------------------------------------- planet --
PLANETCOLOR
0 0 1 D
%---------------------------------------------------------------------- hole --
HOLECOLOR
1 2 r mul sub dup r D
%---------------------------------------------------------------------- moon --
MOONCOLOR
1 1 r D
%---------------------------------------------------------------------- logo --
LOGOCOLOR
LOGOFONT
F
LOGO stringwidth pop 2 div neg
-0.5 moveto
LOGO show
%------------------------------------------------------------------------------
% based on code from Blue Book Program 10, on pages 167--169
% available at ftp://ftp.adobe.com/pub/adobe/displaypostscript/bluebook.shar
% str ptsize centerangle radius outsidecircletext --
/outsidecircletext {
circtextdict begin
/radius exch def
/centerangle exch def
/ptsize exch def
/str exch def
gsave
str radius ptsize findhalfangle
centerangle
add rotate
str
{ /charcode exch def
( ) dup 0 charcode put outsideplacechar
} forall
grestore
end
} def
% string radius ptsize findhalfangle halfangle
/findhalfangle {
4 div add
exch
stringwidth pop 2 div
exch
2 mul 3.1415926535 mul div 360 mul
} def
/circtextdict 16 dict def
circtextdict begin
/outsideplacechar {
/char exch def
/halfangle char radius ptsize findhalfangle def
gsave
halfangle neg rotate
1.4 0 translate
90 rotate
char stringwidth pop 2 div neg 0 moveto
char show
grestore
halfangle 2 mul neg rotate
} def
end
%--------------------------------------------------------------------- label --
LABELFONT
F
/LABELSIZE LABELFONT exch pop def
/LABELRADIUS LABELSIZE 3 div 1 r add sub neg 1.02 mul def
/HALFANGLE
LABEL LABELRADIUS LABELSIZE findhalfangle
HALFDASHANGLE div ceiling HALFDASHANGLE mul
def
/LABELANGLE
60 LABELANGLE HALFANGLE sub
lt
{
HALFANGLE
HALFANGLE DASHANGLE div floor DASHANGLE mul
eq
{LABELANGLE DASHANGLE div ceiling DASHANGLE mul}
{LABELANGLE HALFDASHANGLE sub DASHANGLE div round DASHANGLE mul HALFDASHANGLE add}
ifelse
}
{HALFANGLE 60 add}
ifelse
def
LABELCOLOR
LABEL
LABELSIZE
LABELANGLE
LABELRADIUS
outsidecircletext
%--------------------------------------------------------------------- orbit --
ORBITCOLOR
0.03 setlinewidth
[1 r add 3.1415926535 180 div HALFDASHANGLE mul mul] 0 setdash
newpath
0 0
1 r add
3 copy
30
LABELANGLE HALFANGLE add
arcn
stroke
60
LABELANGLE HALFANGLE sub
2 copy
lt {arc stroke} {4 {pop} repeat} ifelse
%------------------------------------------------------------------ copyright --
/COPYRIGHT
(Graphic design by A. Nakonechny. Copyright (c) 1998, All rights reserved.)
def
LABELCOLOR
LOGOFONT
32 div
F
2 sqrt 0.99 mul
dup
neg
moveto
COPYRIGHT
90 rotate
%show
%---------------------------------------------------------------------- done --
showpage
%%Trailer
%%EOF

View File

@ -10,7 +10,7 @@ if arg then
host = arg[1] or host host = arg[1] or host
port = arg[2] or port port = arg[2] or port
end end
host = socket.toip(host) host = socket.dns.toip(host)
udp = socket.udp() udp = socket.udp()
print("Using host '" ..host.. "' and port " ..port.. "...") print("Using host '" ..host.. "' and port " ..port.. "...")
udp:setpeername(host, port) udp:setpeername(host, port)

View File

@ -10,17 +10,17 @@ if arg then
host = arg[1] or host host = arg[1] or host
port = arg[2] or port port = arg[2] or port
end end
host = socket.toip(host) host = socket.dns.toip(host)
udp, err = socket.udp() udp, err = socket.udp()
if not udp then print(err) exit() end assert(udp, err)
err = udp:setpeername(host, port) ret, err = udp:setpeername(host, port)
if err then print(err) exit() end assert(ret, err)
print("Using host '" ..host.. "' and port " .. port .. "...") print("Using host '" ..host.. "' and port " .. port .. "...")
while 1 do while 1 do
line = io.read() line = io.read()
if not line then os.exit() end if not line then os.exit() end
err = udp:send(line) ret, err = udp:send(line)
if err then print(err) os.exit() end if not ret then print(err) os.exit() end
dgram, err = udp:receive() dgram, err = udp:receive()
if not dgram then print(err) os.exit() end if not dgram then print(err) os.exit() end
print(dgram) print(dgram)

View File

@ -12,11 +12,12 @@ if arg then
end end
print("Binding to host '" ..host.. "' and port " ..port.. "...") print("Binding to host '" ..host.. "' and port " ..port.. "...")
udp, err = socket.udp() udp, err = socket.udp()
if not udp then print(err) os.exit() end assert(udp, err)
err = udp:setsockname(host, port) ret, err = udp:setsockname(host, port)
if err then print(err) os.exit() end assert(ret, err)
udp:timeout(5) udp:settimeout(5)
ip, port = udp:getsockname() ip, port = udp:getsockname()
assert(ip, port)
print("Waiting packets on " .. ip .. ":" .. port .. "...") print("Waiting packets on " .. ip .. ":" .. port .. "...")
while 1 do while 1 do
dgram, ip, port = udp:receivefrom() dgram, ip, port = udp:receivefrom()

View File

@ -15,10 +15,10 @@ end
server1, error = socket.bind(host, port1) server1, error = socket.bind(host, port1)
assert(server1, error) assert(server1, error)
server1:timeout(1) -- make sure we don't block in accept server1:settimeout(1) -- make sure we don't block in accept
server2, error = socket.bind(host, port2) server2, error = socket.bind(host, port2)
assert(server2, error) assert(server2, error)
server2:timeout(1) -- make sure we don't block in accept server2:settimeout(1) -- make sure we don't block in accept
io.write("Servers bound\n") io.write("Servers bound\n")
@ -55,7 +55,7 @@ while 1 do
io.write("Waiting for clients\n") io.write("Waiting for clients\n")
local new = input:accept() local new = input:accept()
if new then if new then
new:timeout(1) new:settimeout(1)
io.write("Inserting client in set\n") io.write("Inserting client in set\n")
set:insert(new) set:insert(new)
end end

View File

@ -224,7 +224,7 @@ function Private.port(control)
local server, ctl_ip local server, ctl_ip
ctl_ip, answer = control:getsockname() ctl_ip, answer = control:getsockname()
server, answer = socket.bind(ctl_ip, 0) server, answer = socket.bind(ctl_ip, 0)
server:timeout(Public.TIMEOUT) server:settimeout(Public.TIMEOUT)
local ip, p, ph, pl local ip, p, ph, pl
ip, p = server:getsockname() ip, p = server:getsockname()
pl = math.mod(p, 256) pl = math.mod(p, 256)
@ -404,7 +404,7 @@ function Private.open(parsed)
local control, err = socket.connect(parsed.host, parsed.port) local control, err = socket.connect(parsed.host, parsed.port)
if not control then return nil, err end if not control then return nil, err end
-- make sure we don't block forever -- make sure we don't block forever
control:timeout(Public.TIMEOUT) control:settimeout(Public.TIMEOUT)
-- check greeting -- check greeting
local code, answer = Private.greet(control) local code, answer = Private.greet(control)
if not code then return nil, answer end if not code then return nil, answer end

View File

@ -553,7 +553,7 @@ function Public.request_cb(request, response)
sock, response.error = socket.connect(parsed.host, parsed.port) sock, response.error = socket.connect(parsed.host, parsed.port)
if not sock then return response end if not sock then return response end
-- set connection timeout so that we do not hang forever -- set connection timeout so that we do not hang forever
sock:timeout(Public.TIMEOUT) sock:settimeout(Public.TIMEOUT)
-- send request message -- send request message
response.error = Private.send_request(sock, request.method, response.error = Private.send_request(sock, request.method,
Private.request_uri(parsed), request.headers, request.body_cb) Private.request_uri(parsed), request.headers, request.body_cb)

View File

@ -20,6 +20,7 @@ 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);
/* DNS functions */
static luaL_reg func[] = { static luaL_reg func[] = {
{ "toip", inet_global_toip }, { "toip", inet_global_toip },
{ "tohostname", inet_global_tohostname }, { "tohostname", inet_global_tohostname },
@ -34,7 +35,19 @@ static luaL_reg func[] = {
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
void inet_open(lua_State *L) void inet_open(lua_State *L)
{ {
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); lua_pushstring(L, LUASOCKET_LIBNAME);
lua_gettable(L, LUA_GLOBALSINDEX);
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
lua_newtable(L);
lua_pushstring(L, LUASOCKET_LIBNAME);
lua_pushvalue(L, -2);
lua_settable(L, LUA_GLOBALSINDEX);
}
lua_pushstring(L, "dns");
lua_newtable(L);
luaL_openlib(L, NULL, func, 0);
lua_settable(L, -3);
lua_pop(L, 1); lua_pop(L, 1);
} }
@ -100,10 +113,11 @@ int inet_meth_getpeername(lua_State *L, p_sock ps)
socklen_t peer_len = sizeof(peer); socklen_t peer_len = sizeof(peer);
if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
lua_pushnil(L); lua_pushnil(L);
return 1; lua_pushstring(L, "getpeername failed");
} else {
lua_pushstring(L, inet_ntoa(peer.sin_addr));
lua_pushnumber(L, ntohs(peer.sin_port));
} }
lua_pushstring(L, inet_ntoa(peer.sin_addr));
lua_pushnumber(L, ntohs(peer.sin_port));
return 2; return 2;
} }
@ -116,10 +130,11 @@ int inet_meth_getsockname(lua_State *L, p_sock ps)
socklen_t local_len = sizeof(local); socklen_t local_len = sizeof(local);
if (getsockname(*ps, (SA *) &local, &local_len) < 0) { if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
lua_pushnil(L); lua_pushnil(L);
return 1; lua_pushstring(L, "getsockname failed");
} else {
lua_pushstring(L, inet_ntoa(local.sin_addr));
lua_pushnumber(L, ntohs(local.sin_port));
} }
lua_pushstring(L, inet_ntoa(local.sin_addr));
lua_pushnumber(L, ntohs(local.sin_port));
return 2; return 2;
} }

View File

@ -243,7 +243,7 @@ function Private.open(server)
-- connect to server and make sure we won't hang -- connect to server and make sure we won't hang
local sock, err = socket.connect(server, Public.PORT) local sock, err = socket.connect(server, Public.PORT)
if not sock then return nil, err end if not sock then return nil, err end
sock:timeout(Public.TIMEOUT) sock:settimeout(Public.TIMEOUT)
-- initial server greeting -- initial server greeting
code, answer = Private.check_answer(sock, 220) code, answer = Private.check_answer(sock, 220)
if not code then return nil, answer end if not code then return nil, answer end
@ -305,10 +305,10 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function Public.mail(message) function Public.mail(message)
local sock, err = Private.open(message.server) local sock, err = Private.open(message.server)
if not sock then return err end if not sock then return nil, err end
local code, answer = Private.send(sock, message) local code, answer = Private.send(sock, message)
if not code then return answer end if not code then return nil, answer end
code, answer = Private.close(sock) code, answer = Private.close(sock)
if code then return nil end if code then return 1
return answer else return nil, answer end
end end

182
src/tcp.c
View File

@ -29,10 +29,10 @@ 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_setoption(lua_State *L);
static int meth_timeout(lua_State *L); static int meth_settimeout(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_tcp_nodelay(lua_State *L);
static int opt_keepalive(lua_State *L); static int opt_keepalive(lua_State *L);
static int opt_linger(lua_State *L); static int opt_linger(lua_State *L);
@ -47,7 +47,7 @@ static luaL_reg tcp[] = {
{"setsockname", meth_bind}, {"setsockname", meth_bind},
{"getpeername", meth_getpeername}, {"getpeername", meth_getpeername},
{"getsockname", meth_getsockname}, {"getsockname", meth_getsockname},
{"timeout", meth_timeout}, {"settimeout", meth_settimeout},
{"close", meth_close}, {"close", meth_close},
{"setoption", meth_setoption}, {"setoption", meth_setoption},
{"__gc", meth_close}, {"__gc", meth_close},
@ -59,7 +59,7 @@ static luaL_reg tcp[] = {
/* socket option handlers */ /* socket option handlers */
static luaL_reg opt[] = { static luaL_reg opt[] = {
{"keepalive", opt_keepalive}, {"keepalive", opt_keepalive},
{"nodelay", opt_nodelay}, {"tcp-nodelay", opt_tcp_nodelay},
{"linger", opt_linger}, {"linger", opt_linger},
{NULL, NULL} {NULL, NULL}
}; };
@ -83,8 +83,8 @@ void tcp_open(lua_State *L)
aux_add2group(L, "tcp{master}", "tcp{any}"); aux_add2group(L, "tcp{master}", "tcp{any}");
aux_add2group(L, "tcp{client}", "tcp{any}"); aux_add2group(L, "tcp{client}", "tcp{any}");
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 */ /* 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}");
@ -121,7 +121,7 @@ static int meth_setoption(lua_State *L)
static int opt_boolean(lua_State *L, int level, int name) static int opt_boolean(lua_State *L, int level, int name)
{ {
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1);
int val = aux_checkboolean(L, 2); int val = aux_checkboolean(L, 2);
if (setsockopt(tcp->sock, level, name, (char *) &val, sizeof(val)) < 0) { if (setsockopt(tcp->sock, level, name, (char *) &val, sizeof(val)) < 0) {
lua_pushnil(L); lua_pushnil(L);
@ -132,8 +132,8 @@ static int opt_boolean(lua_State *L, int level, int name)
return 1; return 1;
} }
/* disables the Nagle algorithm */ /* disables the Naggle algorithm */
static int opt_nodelay(lua_State *L) static int opt_tcp_nodelay(lua_State *L)
{ {
struct protoent *pe = getprotobyname("TCP"); struct protoent *pe = getprotobyname("TCP");
if (!pe) { if (!pe) {
@ -155,13 +155,13 @@ int opt_linger(lua_State *L)
struct linger li; struct linger li;
if (!lua_istable(L, 2)) if (!lua_istable(L, 2))
luaL_typerror(L, 2, lua_typename(L, LUA_TTABLE)); luaL_typerror(L, 2, lua_typename(L, LUA_TTABLE));
lua_pushstring(L, "onoff"); lua_pushstring(L, "on");
lua_gettable(L, 2); lua_gettable(L, 2);
if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid onoff field"); if (!lua_isboolean(L, -1)) luaL_argerror(L, 2, "invalid 'on' field");
li.l_onoff = (int) lua_tonumber(L, -1); li.l_onoff = lua_toboolean(L, -1);
lua_pushstring(L, "linger"); lua_pushstring(L, "timeout");
lua_gettable(L, 2); lua_gettable(L, 2);
if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid linger field"); if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid 'timeout' field");
li.l_linger = (int) lua_tonumber(L, -1); li.l_linger = (int) lua_tonumber(L, -1);
if (setsockopt(tcp->sock, SOL_SOCKET, SO_LINGER, if (setsockopt(tcp->sock, SOL_SOCKET, SO_LINGER,
(char *) &li, sizeof(li) < 0)) { (char *) &li, sizeof(li) < 0)) {
@ -178,93 +178,18 @@ int opt_linger(lua_State *L)
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static int meth_fd(lua_State *L) static int meth_fd(lua_State *L)
{ {
p_tcp tcp = (p_tcp) aux_checkgroup(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_checkgroup(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;
} }
/*-------------------------------------------------------------------------*\
* Just call inet methods
\*-------------------------------------------------------------------------*/
static int meth_getpeername(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1);
return inet_meth_getpeername(L, &tcp->sock);
}
static int meth_getsockname(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1);
return inet_meth_getsockname(L, &tcp->sock);
}
/*-------------------------------------------------------------------------*\
* Just call tm methods
\*-------------------------------------------------------------------------*/
static int meth_timeout(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
return tm_meth_timeout(L, &tcp->tm);
}
/*-------------------------------------------------------------------------*\
* Closes socket used by object
\*-------------------------------------------------------------------------*/
static int meth_close(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
sock_destroy(&tcp->sock);
return 0;
}
/*-------------------------------------------------------------------------*\
* Turns a master tcp object into a client object.
\*-------------------------------------------------------------------------*/
static int meth_connect(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1);
const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3);
const char *err = inet_tryconnect(&tcp->sock, address, port);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
/* turn master object into a client object */
aux_setclass(L, "tcp{client}", 1);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Turns a master object into a server object
\*-------------------------------------------------------------------------*/
static int meth_bind(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1);
const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3);
int backlog = (int) luaL_optnumber(L, 4, 1);
const char *err = inet_trybind(&tcp->sock, address, port, backlog);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
/* turn master object into a server object */
aux_setclass(L, "tcp{server}", 1);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Waits for and returns a client object attempting connection to the * Waits for and returns a client object attempting connection to the
* server object * server object
@ -296,6 +221,81 @@ static int meth_accept(lua_State *L)
return 1; return 1;
} }
/*-------------------------------------------------------------------------*\
* Turns a master object into a server object
\*-------------------------------------------------------------------------*/
static int meth_bind(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1);
const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3);
int backlog = (int) luaL_optnumber(L, 4, 1);
const char *err = inet_trybind(&tcp->sock, address, port, backlog);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
/* turn master object into a server object */
aux_setclass(L, "tcp{server}", 1);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Turns a master tcp object into a client object.
\*-------------------------------------------------------------------------*/
static int meth_connect(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1);
const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3);
const char *err = inet_tryconnect(&tcp->sock, address, port);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
/* turn master object into a client object */
aux_setclass(L, "tcp{client}", 1);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Closes socket used by object
\*-------------------------------------------------------------------------*/
static int meth_close(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
sock_destroy(&tcp->sock);
return 0;
}
/*-------------------------------------------------------------------------*\
* Just call inet methods
\*-------------------------------------------------------------------------*/
static int meth_getpeername(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1);
return inet_meth_getpeername(L, &tcp->sock);
}
static int meth_getsockname(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1);
return inet_meth_getsockname(L, &tcp->sock);
}
/*-------------------------------------------------------------------------*\
* Just call tm methods
\*-------------------------------------------------------------------------*/
static int meth_settimeout(lua_State *L)
{
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1);
return tm_meth_settimeout(L, &tcp->tm);
}
/*=========================================================================*\ /*=========================================================================*\
* Library functions * Library functions
\*=========================================================================*/ \*=========================================================================*/

View File

@ -125,7 +125,7 @@ void tm_open(lua_State *L)
* time: time out value in seconds * time: time out value in seconds
* mode: "b" for block timeout, "t" for total timeout. (default: b) * mode: "b" for block timeout, "t" for total timeout. (default: b)
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
int tm_meth_timeout(lua_State *L, p_tm tm) int tm_meth_settimeout(lua_State *L, p_tm tm)
{ {
int ms = lua_isnil(L, 2) ? -1 : (int) (luaL_checknumber(L, 2)*1000.0); int ms = lua_isnil(L, 2) ? -1 : (int) (luaL_checknumber(L, 2)*1000.0);
const char *mode = luaL_optstring(L, 3, "b"); const char *mode = luaL_optstring(L, 3, "b");

View File

@ -26,6 +26,6 @@ void tm_markstart(p_tm tm);
int tm_getstart(p_tm tm); int tm_getstart(p_tm tm);
int tm_get(p_tm tm); 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_settimeout(lua_State *L, p_tm tm);
#endif /* TM_H */ #endif /* TM_H */

View File

@ -30,7 +30,7 @@ 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_setoption(lua_State *L);
static int meth_timeout(lua_State *L); static int meth_settimeout(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_dontroute(lua_State *L);
@ -46,7 +46,7 @@ static luaL_reg udp[] = {
{"sendto", meth_sendto}, {"sendto", meth_sendto},
{"receive", meth_receive}, {"receive", meth_receive},
{"receivefrom", meth_receivefrom}, {"receivefrom", meth_receivefrom},
{"timeout", meth_timeout}, {"settimeout", meth_settimeout},
{"close", meth_close}, {"close", meth_close},
{"setoption", meth_setoption}, {"setoption", meth_setoption},
{"__gc", meth_close}, {"__gc", meth_close},
@ -252,10 +252,10 @@ static int opt_broadcast(lua_State *L)
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Just call tm methods * Just call tm methods
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static int meth_timeout(lua_State *L) static int meth_settimeout(lua_State *L)
{ {
p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1);
return tm_meth_timeout(L, &udp->tm); return tm_meth_settimeout(L, &udp->tm);
} }
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
@ -297,7 +297,7 @@ static int meth_close(lua_State *L)
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static int meth_setsockname(lua_State *L) static int meth_setsockname(lua_State *L)
{ {
p_udp udp = (p_udp) aux_checkclass(L, "udp{master}", 1); p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1);
const char *address = luaL_checkstring(L, 2); const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3); unsigned short port = (unsigned short) luaL_checknumber(L, 3);
const char *err = inet_trybind(&udp->sock, address, port, -1); const char *err = inet_trybind(&udp->sock, address, port, -1);

View File

@ -26,8 +26,10 @@ int sock_open(void)
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
void sock_destroy(p_sock ps) void sock_destroy(p_sock ps)
{ {
close(*ps); if (*ps != SOCK_INVALID) {
*ps = SOCK_INVALID; close(*ps);
*ps = SOCK_INVALID;
}
} }
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\

View File

@ -29,8 +29,10 @@ int sock_open(void)
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
void sock_destroy(p_sock ps) void sock_destroy(p_sock ps)
{ {
closesocket(*ps); if (*ps != SOCK_INVALID) {
*ps = SOCK_INVALID; closesocket(*ps);
*ps = SOCK_INVALID;
}
} }
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\

View File

@ -209,27 +209,27 @@ insert(sent, {
io.write("testing host not found: ") io.write("testing host not found: ")
local c, e = socket.connect("wrong.host", 25) local c, e = socket.connect("wrong.host", 25)
local err = socket.smtp.mail{ local ret, err = socket.smtp.mail{
from = from, from = from,
rcpt = rcpt, rcpt = rcpt,
server = "wrong.host" server = "wrong.host"
} }
if e ~= err then fail("wrong error message") if ret or e ~= err then fail("wrong error message")
else print("ok") end else print("ok") end
io.write("testing invalid from: ") io.write("testing invalid from: ")
local err = socket.smtp.mail{ local ret, err = socket.smtp.mail{
from = ' " " (( _ * ', from = ' " " (( _ * ',
rcpt = rcpt, rcpt = rcpt,
} }
if not err then fail("wrong error message") if ret or not err then fail("wrong error message")
else print(err) end else print(err) end
io.write("testing no rcpt: ") io.write("testing no rcpt: ")
local err = socket.smtp.mail{ local ret, err = socket.smtp.mail{
from = from, from = from,
} }
if not err then fail("wrong error message") if ret or not err then fail("wrong error message")
else print(err) end else print(err) end
io.write("clearing mailbox: ") io.write("clearing mailbox: ")
@ -238,8 +238,8 @@ print("ok")
io.write("sending messages: ") io.write("sending messages: ")
for i = 1, table.getn(sent) do for i = 1, table.getn(sent) do
err = socket.smtp.mail(sent[i]) ret, err = socket.smtp.mail(sent[i])
if err then fail(err) end if not ret then fail(err) end
io.write("+") io.write("+")
io.stdout:flush() io.stdout:flush()
end end

View File

@ -121,7 +121,7 @@ test_methods(socket.tcp(), {
"getpeername", "getpeername",
"getsockname", "getsockname",
"setoption", "setoption",
"timeout", "settimeout",
"close", "close",
}) })
@ -135,7 +135,7 @@ test_methods(socket.udp(), {
"receive", "receive",
"receivefrom", "receivefrom",
"setoption", "setoption",
"timeout", "settimeout",
"close", "close",
}) })
@ -278,7 +278,7 @@ reconnect()
-- the value is not important, we only want -- the value is not important, we only want
-- to test non-blockin I/O anyways -- to test non-blockin I/O anyways
data:timeout(200) data:settimeout(200)
test_raw(1) test_raw(1)
test_raw(17) test_raw(17)
test_raw(200) test_raw(200)
@ -298,7 +298,7 @@ function test_totaltimeoutreceive(len, tm, sl)
reconnect() reconnect()
pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl) pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl)
remote (string.format ([[ remote (string.format ([[
data:timeout(%d) data:settimeout(%d)
str = string.rep('a', %d) str = string.rep('a', %d)
data:send(str) data:send(str)
print('server: sleeping for %ds') print('server: sleeping for %ds')
@ -306,7 +306,7 @@ function test_totaltimeoutreceive(len, tm, sl)
print('server: woke up') print('server: woke up')
data:send(str) data:send(str)
]], 2*tm, len, sl, sl)) ]], 2*tm, len, sl, sl))
data:timeout(tm, "total") data:settimeout(tm, "total")
str, err, elapsed = data:receive(2*len) str, err, elapsed = data:receive(2*len)
check_timeout(tm, sl, elapsed, err, "receive", "total", check_timeout(tm, sl, elapsed, err, "receive", "total",
string.len(str) == 2*len) string.len(str) == 2*len)
@ -323,14 +323,14 @@ function test_totaltimeoutsend(len, tm, sl)
reconnect() reconnect()
pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl) pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl)
remote (string.format ([[ remote (string.format ([[
data:timeout(%d) data:settimeout(%d)
str = data:receive(%d) str = data:receive(%d)
print('server: sleeping for %ds') print('server: sleeping for %ds')
socket.sleep(%d) socket.sleep(%d)
print('server: woke up') print('server: woke up')
str = data:receive(%d) str = data:receive(%d)
]], 2*tm, len, sl, sl, len)) ]], 2*tm, len, sl, sl, len))
data:timeout(tm, "total") data:settimeout(tm, "total")
str = string.rep("a", 2*len) str = string.rep("a", 2*len)
total, err, elapsed = data:send(str) total, err, elapsed = data:send(str)
check_timeout(tm, sl, elapsed, err, "send", "total", check_timeout(tm, sl, elapsed, err, "send", "total",
@ -348,7 +348,7 @@ function test_blockingtimeoutreceive(len, tm, sl)
reconnect() reconnect()
pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
remote (string.format ([[ remote (string.format ([[
data:timeout(%d) data:settimeout(%d)
str = string.rep('a', %d) str = string.rep('a', %d)
data:send(str) data:send(str)
print('server: sleeping for %ds') print('server: sleeping for %ds')
@ -356,7 +356,7 @@ function test_blockingtimeoutreceive(len, tm, sl)
print('server: woke up') print('server: woke up')
data:send(str) data:send(str)
]], 2*tm, len, sl, sl)) ]], 2*tm, len, sl, sl))
data:timeout(tm) data:settimeout(tm)
str, err, elapsed = data:receive(2*len) str, err, elapsed = data:receive(2*len)
check_timeout(tm, sl, elapsed, err, "receive", "blocking", check_timeout(tm, sl, elapsed, err, "receive", "blocking",
string.len(str) == 2*len) string.len(str) == 2*len)
@ -373,14 +373,14 @@ function test_blockingtimeoutsend(len, tm, sl)
reconnect() reconnect()
pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
remote (string.format ([[ remote (string.format ([[
data:timeout(%d) data:settimeout(%d)
str = data:receive(%d) str = data:receive(%d)
print('server: sleeping for %ds') print('server: sleeping for %ds')
socket.sleep(%d) socket.sleep(%d)
print('server: woke up') print('server: woke up')
str = data:receive(%d) str = data:receive(%d)
]], 2*tm, len, sl, sl, len)) ]], 2*tm, len, sl, sl, len))
data:timeout(tm) data:settimeout(tm)
str = string.rep("a", 2*len) str = string.rep("a", 2*len)
total, err, elapsed = data:send(str) total, err, elapsed = data:send(str)
check_timeout(tm, sl, elapsed, err, "send", "blocking", check_timeout(tm, sl, elapsed, err, "send", "blocking",