aboutsummaryrefslogtreecommitdiffstats
path: root/main/lua-socket
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-04-06 09:56:32 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2015-04-06 09:56:32 +0000
commitef41e80032d26ca0f052f9eaec4c995efa06356f (patch)
tree763576dfdf09b36ae148c9754c1ed85be91cf331 /main/lua-socket
parent1138dee508f2cd1ab1eadd1f67107affc5456902 (diff)
downloadaports-ef41e80032d26ca0f052f9eaec4c995efa06356f.tar.bz2
aports-ef41e80032d26ca0f052f9eaec4c995efa06356f.tar.xz
main/lua-socket: upgrade to git snapshot for lua 5.3 support
Diffstat (limited to 'main/lua-socket')
-rw-r--r--main/lua-socket/APKBUILD21
-rw-r--r--main/lua-socket/git.patch1559
-rw-r--r--main/lua-socket/lua-cflags.patch12
3 files changed, 1579 insertions, 13 deletions
diff --git a/main/lua-socket/APKBUILD b/main/lua-socket/APKBUILD
index 6882347b43..d2b12515da 100644
--- a/main/lua-socket/APKBUILD
+++ b/main/lua-socket/APKBUILD
@@ -1,11 +1,12 @@
# Contributor: Mika Havela <mika.havela@gmail.com>
# Maintainer: Mika Havela <mika.havela@gmail.com>
-_luaversions="5.1 5.2"
+_luaversions="5.1 5.2 5.3"
pkgname=lua-socket
_name=luasocket
-pkgver=3.0_rc1
+pkgver=3.0_rc1_git20150301
pkgrel=0
-_ver=${pkgver/_/-}
+_ver=${pkgver%_git*}
+_ver=${_ver/_rc/-rc}
pkgdesc="Networking library for Lua"
url="http://luaforge.net/projects/luasocket/"
arch="all"
@@ -19,8 +20,10 @@ for _i in $_luaversions; do
subpackages="$subpackages lua$_i-socket:split_${_i/./_}"
done
source="luasocket-$_ver.tar.gz::https://github.com/diegonehab/luasocket/archive/v$_ver.tar.gz
+ git.patch
lua-cflags.patch
- include-luasocket.patch"
+ include-luasocket.patch
+ "
_sdir="$srcdir/$_name-$_ver"
@@ -59,6 +62,7 @@ package() {
_split() {
local d= _ver=$1
pkgdesc="Networking library for Lua $_ver"
+ install_if="lua$_ver $pkgname=$pkgver-r$pkgrel"
replaces="$pkgname"
depends=
for d in usr/lib/lua usr/share/lua; do
@@ -74,11 +78,14 @@ for _i in $_luaversions; do
done
md5sums="08bd2f265b244eb4bf5c2c36bf89b759 luasocket-3.0-rc1.tar.gz
-f869d0f81e347291405fb53dff9a408a lua-cflags.patch
+2e14aba126cec984e1824a4da35d45f8 git.patch
+8adb3bb6f4c6f63de8c56412ef623953 lua-cflags.patch
4bcbbc8d3383db94223155fc7a6d454e include-luasocket.patch"
sha256sums="8b67d9b5b545e1b694753dab7bd6cdbc24c290f2b21ba1e14c77b32817ea1249 luasocket-3.0-rc1.tar.gz
-bbcead4850fcdf6711c70b48db4db17e06fedcae45c4c53fd814ff6f0d9fe4ce lua-cflags.patch
+d64d35ba14a8b1381c20273d1390ee7c170b4ff566ad503621cac9f4c129bbb8 git.patch
+e5d38d3b1484b61ab43627efdc302f78c24733aa2d422e6745fe273b1a56d94b lua-cflags.patch
42b1a439805efaf33110e01a53798b3e8d044101470808fe9478ca3be0ae5165 include-luasocket.patch"
sha512sums="f6efce259aaacaa11472911471f8a13b118fe009b8953a82c6aa18b9ec829cd1293180904e56935cb130d36d267e3f27c91db2d78e03f7488f3e100571ed0540 luasocket-3.0-rc1.tar.gz
-58b5d3c239c8be1561060f75bf849bcfa9022626995a5234ec741dc2ae86755d9fed88c12b5644c914c604ea31b017a6679ac33a9a76392242faf139bfd59de1 lua-cflags.patch
+85a6dc3b8e674200a2928f397fcb7fb9ca0e41870d5628c9c24aabc140d8fa14c12576cfa6e8bef687ab914d378585557b9a2f3bf09173a003d51f7f8e2a0d34 git.patch
+9a155e11e117b9f0485899951051a61d21cdc088d3a5e1ec0e2d018cb257b6edaaf342f5f5304cb229160247ced5ff0fe825f880cb695a201295b4399546de84 lua-cflags.patch
34db925f9e9a1a629d01dc26072f4edec77087f7bf89dda8140326447662efbc53ce5e36087fa9127d708d498c129613f7ed82862dd3176df16796418868548d include-luasocket.patch"
diff --git a/main/lua-socket/git.patch b/main/lua-socket/git.patch
new file mode 100644
index 0000000000..65c5595a60
--- /dev/null
+++ b/main/lua-socket/git.patch
@@ -0,0 +1,1559 @@
+diff --git a/doc/reference.css b/doc/reference.css
+index b1dd25d..04e38cf 100644
+--- a/doc/reference.css
++++ b/doc/reference.css
+@@ -2,6 +2,7 @@ body {
+ margin-left: 1em;
+ margin-right: 1em;
+ font-family: "Verdana", sans-serif;
++ background: #ffffff;
+ }
+
+ tt {
+diff --git a/etc/dispatch.lua b/etc/dispatch.lua
+index cab7f59..2485415 100644
+--- a/etc/dispatch.lua
++++ b/etc/dispatch.lua
+@@ -5,6 +5,7 @@
+ -----------------------------------------------------------------------------
+ local base = _G
+ local table = require("table")
++local string = require("string")
+ local socket = require("socket")
+ local coroutine = require("coroutine")
+ module("dispatch")
+@@ -43,26 +44,32 @@ end
+ -----------------------------------------------------------------------------
+ -- Mega hack. Don't try to do this at home.
+ -----------------------------------------------------------------------------
+--- we can't yield across calls to protect, so we rewrite it with coxpcall
++-- we can't yield across calls to protect on Lua 5.1, so we rewrite it with
++-- coroutines
+ -- make sure you don't require any module that uses socket.protect before
+ -- loading our hack
+-function socket.protect(f)
+- return function(...)
+- local co = coroutine.create(f)
+- while true do
+- local results = {coroutine.resume(co, ...)}
+- local status = table.remove(results, 1)
+- if not status then
+- if base.type(results[1]) == 'table' then
+- return nil, results[1][1]
+- else base.error(results[1]) end
+- end
+- if coroutine.status(co) == "suspended" then
+- arg = {coroutine.yield(base.unpack(results))}
++if string.sub(base._VERSION, -3) == "5.1" then
++ local function _protect(co, status, ...)
++ if not status then
++ local msg = ...
++ if base.type(msg) == 'table' then
++ return nil, msg[1]
+ else
+- return base.unpack(results)
++ base.error(msg, 0)
+ end
+ end
++ if coroutine.status(co) == "suspended" then
++ return _protect(co, coroutine.resume(co, coroutine.yield(...)))
++ else
++ return ...
++ end
++ end
++
++ function socket.protect(f)
++ return function(...)
++ local co = coroutine.create(f)
++ return _protect(co, coroutine.resume(co, ...))
++ end
+ end
+ end
+
+diff --git a/makefile b/makefile
+index 04cd894..e34f5a9 100644
+--- a/makefile
++++ b/makefile
+@@ -5,12 +5,12 @@
+ # Targets:
+ # install install system independent support
+ # install-unix also install unix-only support
+-# install-both install for both lua5.1 and lua5.2
+-# install-both-unix also install unix-only
++# install-both install for lua51 lua52 lua53
++# install-both-unix also install unix-only
+ # print print the build settings
+
+ PLAT?= linux
+-PLATS= macosx linux win32 mingw
++PLATS= macosx linux win32 mingw freebsd
+
+ all: $(PLAT)
+
+@@ -24,20 +24,26 @@ test:
+ lua test/hello.lua
+
+ install-both:
+- $(MAKE) clean
++ $(MAKE) clean
+ @cd src; $(MAKE) $(PLAT) LUAV=5.1
+ @cd src; $(MAKE) install LUAV=5.1
+- $(MAKE) clean
++ $(MAKE) clean
+ @cd src; $(MAKE) $(PLAT) LUAV=5.2
+ @cd src; $(MAKE) install LUAV=5.2
++ $(MAKE) clean
++ @cd src; $(MAKE) $(PLAT) LUAV=5.3
++ @cd src; $(MAKE) install LUAV=5.3
+
+ install-both-unix:
+- $(MAKE) clean
++ $(MAKE) clean
+ @cd src; $(MAKE) $(PLAT) LUAV=5.1
+ @cd src; $(MAKE) install-unix LUAV=5.1
+- $(MAKE) clean
++ $(MAKE) clean
+ @cd src; $(MAKE) $(PLAT) LUAV=5.2
+ @cd src; $(MAKE) install-unix LUAV=5.2
++ $(MAKE) clean
++ @cd src; $(MAKE) $(PLAT) LUAV=5.3
++ @cd src; $(MAKE) install-unix LUAV=5.3
+
+ .PHONY: test
+
+diff --git a/src/buffer.c b/src/buffer.c
+index 4ef4e8e..423d804 100644
+--- a/src/buffer.c
++++ b/src/buffer.c
+@@ -78,9 +78,7 @@ int buffer_meth_send(lua_State *L, p_buffer buf) {
+ const char *data = luaL_checklstring(L, 2, &size);
+ long start = (long) luaL_optnumber(L, 3, 1);
+ long end = (long) luaL_optnumber(L, 4, -1);
+-#ifdef LUASOCKET_DEBUG
+- p_timeout tm = timeout_markstart(buf->tm);
+-#endif
++ timeout_markstart(buf->tm);
+ if (start < 0) start = (long) (size+start+1);
+ if (end < 0) end = (long) (size+end+1);
+ if (start < 1) start = (long) 1;
+@@ -98,7 +96,7 @@ int buffer_meth_send(lua_State *L, p_buffer buf) {
+ }
+ #ifdef LUASOCKET_DEBUG
+ /* push time elapsed during operation as the last return value */
+- lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm));
++ lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm));
+ #endif
+ return lua_gettop(L) - top;
+ }
+@@ -111,9 +109,7 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) {
+ luaL_Buffer b;
+ size_t size;
+ const char *part = luaL_optlstring(L, 3, "", &size);
+-#ifdef LUASOCKET_DEBUG
+- p_timeout tm = timeout_markstart(buf->tm);
+-#endif
++ timeout_markstart(buf->tm);
+ /* initialize buffer with optional extra prefix
+ * (useful for concatenating previous partial results) */
+ luaL_buffinit(L, &b);
+@@ -149,7 +145,7 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) {
+ }
+ #ifdef LUASOCKET_DEBUG
+ /* push time elapsed during operation as the last return value */
+- lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm));
++ lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm));
+ #endif
+ return lua_gettop(L) - top;
+ }
+diff --git a/src/except.c b/src/except.c
+index 002e701..4faa208 100644
+--- a/src/except.c
++++ b/src/except.c
+@@ -9,6 +9,15 @@
+
+ #include "except.h"
+
++#if LUA_VERSION_NUM < 502
++#define lua_pcallk(L, na, nr, err, ctx, cont) \
++ ((void)ctx,(void)cont,lua_pcall(L, na, nr, err))
++#endif
++
++#if LUA_VERSION_NUM < 503
++typedef int lua_KContext;
++#endif
++
+ /*=========================================================================*\
+ * Internal function prototypes.
+ \*=========================================================================*/
+@@ -73,14 +82,30 @@ static int unwrap(lua_State *L) {
+ } else return 0;
+ }
+
++static int protected_finish(lua_State *L, int status, lua_KContext ctx) {
++ (void)ctx;
++ if (status != 0 && status != LUA_YIELD) {
++ if (unwrap(L)) return 2;
++ else return lua_error(L);
++ } else return lua_gettop(L);
++}
++
++#if LUA_VERSION_NUM == 502
++static int protected_cont(lua_State *L) {
++ int ctx = 0;
++ int status = lua_getctx(L, &ctx);
++ return protected_finish(L, status, ctx);
++}
++#else
++#define protected_cont protected_finish
++#endif
++
+ static int protected_(lua_State *L) {
++ int status;
+ lua_pushvalue(L, lua_upvalueindex(1));
+ lua_insert(L, 1);
+- if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) {
+- if (unwrap(L)) return 2;
+- else lua_error(L);
+- return 0;
+- } else return lua_gettop(L);
++ status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, protected_cont);
++ return protected_finish(L, status, 0);
+ }
+
+ static int global_protect(lua_State *L) {
+diff --git a/src/ftp.lua b/src/ftp.lua
+index ea1145b..917cd89 100644
+--- a/src/ftp.lua
++++ b/src/ftp.lua
+@@ -268,7 +268,7 @@ _M.command = socket.protect(function(cmdt)
+ cmdt = override(cmdt)
+ socket.try(cmdt.host, "missing hostname")
+ socket.try(cmdt.command, "missing command")
+- local f = open(cmdt.host, cmdt.port, cmdt.create)
++ local f = _M.open(cmdt.host, cmdt.port, cmdt.create)
+ f:greet()
+ f:login(cmdt.user, cmdt.password)
+ f.try(f.tp:command(cmdt.command, cmdt.argument))
+diff --git a/src/http.lua b/src/http.lua
+index ac4b2d6..d5457f6 100644
+--- a/src/http.lua
++++ b/src/http.lua
+@@ -22,7 +22,7 @@ local _M = socket.http
+ -- Program constants
+ -----------------------------------------------------------------------------
+ -- connection timeout in seconds
+-TIMEOUT = 60
++_M.TIMEOUT = 60
+ -- default port for document retrieval
+ _M.PORT = 80
+ -- user agent field sent in request
+@@ -186,7 +186,7 @@ end
+ local function adjusturi(reqt)
+ local u = reqt
+ -- if there is a proxy, we need the full url. otherwise, just a part.
+- if not reqt.proxy and not PROXY then
++ if not reqt.proxy and not _M.PROXY then
+ u = {
+ path = socket.try(reqt.path, "invalid path 'nil'"),
+ params = reqt.params,
+@@ -198,7 +198,7 @@ local function adjusturi(reqt)
+ end
+
+ local function adjustproxy(reqt)
+- local proxy = reqt.proxy or PROXY
++ local proxy = reqt.proxy or _M.PROXY
+ if proxy then
+ proxy = url.parse(proxy)
+ return proxy.host, proxy.port or 3128
+@@ -209,9 +209,10 @@ end
+
+ local function adjustheaders(reqt)
+ -- default headers
++ local host = string.gsub(reqt.authority, "^.-@", "")
+ local lower = {
+ ["user-agent"] = _M.USERAGENT,
+- ["host"] = reqt.host,
++ ["host"] = host,
+ ["connection"] = "close, TE",
+ ["te"] = "trailers"
+ }
+@@ -351,4 +352,4 @@ _M.request = socket.protect(function(reqt, body)
+ else return trequest(reqt) end
+ end)
+
+-return _M
+\ No newline at end of file
++return _M
+diff --git a/src/inet.c b/src/inet.c
+index 1a411f6..48e654b 100644
+--- a/src/inet.c
++++ b/src/inet.c
+@@ -183,6 +183,7 @@ static int inet_global_getaddrinfo(lua_State *L)
+ ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen,
+ hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
+ if (ret){
++ freeaddrinfo(resolved);
+ lua_pushnil(L);
+ lua_pushstring(L, socket_gaistrerror(ret));
+ return 2;
+diff --git a/src/ltn12.lua b/src/ltn12.lua
+index 5b10f56..1014de2 100644
+--- a/src/ltn12.lua
++++ b/src/ltn12.lua
+@@ -139,7 +139,9 @@ function source.rewind(src)
+ end
+ end
+
+-function source.chain(src, f)
++-- chains a source with one or several filter(s)
++function source.chain(src, f, ...)
++ if ... then f=filter.chain(f, ...) end
+ base.assert(src and f)
+ local last_in, last_out = "", ""
+ local state = "feeding"
+@@ -254,8 +256,13 @@ function sink.error(err)
+ end
+ end
+
+--- chains a sink with a filter
+-function sink.chain(f, snk)
++-- chains a sink with one or several filter(s)
++function sink.chain(f, snk, ...)
++ if ... then
++ local args = { f, snk, ... }
++ snk = table.remove(args, #args)
++ f = filter.chain(unpack(args))
++ end
+ base.assert(f and snk)
+ return function(chunk, err)
+ if chunk ~= "" then
+diff --git a/src/luasocket.c b/src/luasocket.c
+index e6ee747..c4eeab3 100644
+--- a/src/luasocket.c
++++ b/src/luasocket.c
+@@ -18,7 +18,6 @@
+ #include "lua.h"
+ #include "lauxlib.h"
+
+-
+ /*=========================================================================*\
+ * LuaSocket includes
+ \*=========================================================================*/
+@@ -64,7 +63,7 @@ static luaL_Reg func[] = {
+ * Skip a few arguments
+ \*-------------------------------------------------------------------------*/
+ static int global_skip(lua_State *L) {
+- int amount = luaL_checkint(L, 1);
++ int amount = luaL_checkinteger(L, 1);
+ int ret = lua_gettop(L) - amount - 1;
+ return ret >= 0 ? ret : 0;
+ }
+@@ -78,14 +77,6 @@ static int global_unload(lua_State *L) {
+ return 0;
+ }
+
+-#if LUA_VERSION_NUM > 501
+-int luaL_typerror (lua_State *L, int narg, const char *tname) {
+- const char *msg = lua_pushfstring(L, "%s expected, got %s",
+- tname, luaL_typename(L, narg));
+- return luaL_argerror(L, narg, msg);
+-}
+-#endif
+-
+ /*-------------------------------------------------------------------------*\
+ * Setup basic stuff.
+ \*-------------------------------------------------------------------------*/
+diff --git a/src/makefile b/src/makefile
+index c24e61b..7f118a7 100644
+--- a/src/makefile
++++ b/src/makefile
+@@ -20,6 +20,12 @@ PLAT?=linux
+ # lua version to build against
+ LUAV?=5.1
+
++# MYCFLAGS: to be set by user if needed
++MYCFLAGS=
++
++# MYLDFLAGS: to be set by user if needed
++MYLDFLAGS=
++
+ # DEBUG: NODEBUG DEBUG
+ # debug mode causes luasocket to collect and returns timing information useful
+ # for testing and debugging luasocket itself
+@@ -40,7 +46,6 @@ LUAPREFIX_macosx?=/opt/local
+ CDIR_macosx?=lib/lua/$(LUAV)
+ LDIR_macosx?=share/lua/$(LUAV)
+
+-
+ # LUAINC_linux:
+ # /usr/include/lua$(LUAV)
+ # /usr/local/include
+@@ -52,8 +57,17 @@ LUAPREFIX_linux?=/usr/local
+ CDIR_linux?=lib/lua/$(LUAV)
+ LDIR_linux?=share/lua/$(LUAV)
+
++# LUAINC_freebsd:
++# /usr/local/include/lua$(LUAV)
++# where lua headers are found for linux builds
++LUAINC_freebsd_base?=/usr/local/include/
++LUAINC_freebsd?=$(LUAINC_freebsd_base)/lua$(LUAV)
++LUAPREFIX_freebsd?=/usr/local/
++CDIR_freebsd?=lib/lua/$(LUAV)
++LDIR_freebsd?=share/lua/$(LUAV)
++
+ # where lua headers are found for mingw builds
+-# LUAINC_mingw:
++# LUAINC_mingw:
+ # /opt/local/include
+ LUAINC_mingw_base?=/usr/include
+ LUAINC_mingw?=$(LUAINC_mingw_base)/lua/$(LUAV)
+@@ -133,7 +147,7 @@ DEF_macosx= -DLUASOCKET_$(DEBUG) -DUNIX_HAS_SUN_LEN -DLUA_$(COMPAT)_MODULE \
+ -DLUASOCKET_API='__attribute__((visibility("default")))' \
+ -DUNIX_API='__attribute__((visibility("default")))' \
+ -DMIME_API='__attribute__((visibility("default")))'
+-CFLAGS_macosx= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \
++CFLAGS_macosx= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \
+ -fvisibility=hidden
+ LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o
+ LD_macosx= export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc
+@@ -149,7 +163,7 @@ DEF_linux=-DLUASOCKET_$(DEBUG) -DLUA_$(COMPAT)_MODULE \
+ -DLUASOCKET_API='__attribute__((visibility("default")))' \
+ -DUNIX_API='__attribute__((visibility("default")))' \
+ -DMIME_API='__attribute__((visibility("default")))'
+-CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra \
++CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \
+ -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden
+ LDFLAGS_linux=-O -shared -fpic -o
+ LD_linux=gcc
+@@ -157,6 +171,22 @@ SOCKET_linux=usocket.o
+
+ #------
+ # Compiler and linker settings
++# for FreeBSD
++SO_freebsd=so
++O_freebsd=o
++CC_freebsd=gcc
++DEF_freebsd=-DLUASOCKET_$(DEBUG) -DLUA_$(COMPAT)_MODULE \
++ -DLUASOCKET_API='__attribute__((visibility("default")))' \
++ -DUNIX_API='__attribute__((visibility("default")))' \
++ -DMIME_API='__attribute__((visibility("default")))'
++CFLAGS_freebsd= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \
++ -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden
++LDFLAGS_freebsd=-O -shared -fpic -o
++LD_freebsd=gcc
++SOCKET_freebsd=usocket.o
++
++#------
++# Compiler and linker settings
+ # for MingW
+ SO_mingw=dll
+ O_mingw=o
+@@ -164,7 +194,7 @@ CC_mingw=gcc
+ DEF_mingw= -DLUASOCKET_INET_PTON -DLUASOCKET_$(DEBUG) -DLUA_$(COMPAT)_MODULE \
+ -DWINVER=0x0501 -DLUASOCKET_API='__declspec(dllexport)' \
+ -DMIME_API='__declspec(dllexport)'
+-CFLAGS_mingw= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \
++CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \
+ -fvisibility=hidden
+ LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lws2_32 -o
+ LD_mingw=gcc
+@@ -195,7 +225,7 @@ SOCKET_win32=wsocket.obj
+ .SUFFIXES: .obj
+
+ .c.obj:
+- $(CC) $(CFLAGS) //Fo"$@" //c $<
++ $(CC) $(LUASOCKET_CFLAGS) //Fo"$@" //c $<
+
+ #------
+ # Output file names
+@@ -215,8 +245,8 @@ SOCKET=$(SOCKET_$(PLAT))
+ #
+ CC=$(CC_$(PLAT))
+ DEF=$(DEF_$(PLAT))
+-CFLAGS=$(CFLAGS_$(PLAT))
+-LDFLAGS=$(LDFLAGS_$(PLAT))
++CFLAGS=$(MYCFLAGS) $(CFLAGS_$(PLAT))
++LDFLAGS=$(MYLDFLAGS) $(LDFLAGS_$(PLAT))
+ LD=$(LD_$(PLAT))
+ LUAINC= $(LUAINC_$(PLAT))
+ LUALIB= $(LUALIB_$(PLAT))
+@@ -259,7 +289,7 @@ UNIX_OBJS=\
+ #------
+ # Modules belonging to serial (device streams)
+ #
+-SERIAL_OBJS:=\
++SERIAL_OBJS=\
+ buffer.$(O) \
+ auxiliar.$(O) \
+ options.$(O) \
+@@ -289,6 +319,10 @@ TO_TOP_LDIR= \
+ #
+ default: $(PLAT)
+
++
++freebsd:
++ $(MAKE) all-unix PLAT=freebsd
++
+ macosx:
+ $(MAKE) all-unix PLAT=macosx
+
+diff --git a/src/mime.c b/src/mime.c
+index dd37dcf..d121e9e 100644
+--- a/src/mime.c
++++ b/src/mime.c
+@@ -41,7 +41,7 @@ static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
+ static void qpsetup(UC *class, UC *unbase);
+ static void qpquote(UC c, luaL_Buffer *buffer);
+ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
+-static size_t qpencode(UC c, UC *input, size_t size,
++static size_t qpencode(UC c, UC *input, size_t size,
+ const char *marker, luaL_Buffer *buffer);
+ static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer);
+
+@@ -103,15 +103,15 @@ MIME_API int luaopen_mime_core(lua_State *L)
+ /*-------------------------------------------------------------------------*\
+ * Incrementaly breaks a string into lines. The string can have CRLF breaks.
+ * A, n = wrp(l, B, length)
+-* A is a copy of B, broken into lines of at most 'length' bytes.
+-* 'l' is how many bytes are left for the first line of B.
+-* 'n' is the number of bytes left in the last line of A.
++* A is a copy of B, broken into lines of at most 'length' bytes.
++* 'l' is how many bytes are left for the first line of B.
++* 'n' is the number of bytes left in the last line of A.
+ \*-------------------------------------------------------------------------*/
+ static int mime_global_wrp(lua_State *L)
+ {
+ size_t size = 0;
+ int left = (int) luaL_checknumber(L, 1);
+- const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size);
++ const UC *input = (const UC *) luaL_optlstring(L, 2, NULL, &size);
+ const UC *last = input + size;
+ int length = (int) luaL_optnumber(L, 3, 76);
+ luaL_Buffer buffer;
+@@ -123,7 +123,7 @@ static int mime_global_wrp(lua_State *L)
+ else lua_pushnil(L);
+ lua_pushnumber(L, length);
+ return 2;
+- }
++ }
+ luaL_buffinit(L, &buffer);
+ while (input < last) {
+ switch (*input) {
+@@ -150,9 +150,9 @@ static int mime_global_wrp(lua_State *L)
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* Fill base64 decode map.
++* Fill base64 decode map.
+ \*-------------------------------------------------------------------------*/
+-static void b64setup(UC *unbase)
++static void b64setup(UC *unbase)
+ {
+ int i;
+ for (i = 0; i <= 255; i++) unbase[i] = (UC) 255;
+@@ -161,11 +161,11 @@ static void b64setup(UC *unbase)
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* Acumulates bytes in input buffer until 3 bytes are available.
++* Acumulates bytes in input buffer until 3 bytes are available.
+ * Translate the 3 bytes into Base64 form and append to buffer.
+ * Returns new number of bytes in buffer.
+ \*-------------------------------------------------------------------------*/
+-static size_t b64encode(UC c, UC *input, size_t size,
++static size_t b64encode(UC c, UC *input, size_t size,
+ luaL_Buffer *buffer)
+ {
+ input[size++] = c;
+@@ -174,7 +174,7 @@ static size_t b64encode(UC c, UC *input, size_t size,
+ unsigned long value = 0;
+ value += input[0]; value <<= 8;
+ value += input[1]; value <<= 8;
+- value += input[2];
++ value += input[2];
+ code[3] = b64base[value & 0x3f]; value >>= 6;
+ code[2] = b64base[value & 0x3f]; value >>= 6;
+ code[1] = b64base[value & 0x3f]; value >>= 6;
+@@ -186,11 +186,11 @@ static size_t b64encode(UC c, UC *input, size_t size,
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* Encodes the Base64 last 1 or 2 bytes and adds padding '='
++* Encodes the Base64 last 1 or 2 bytes and adds padding '='
+ * Result, if any, is appended to buffer.
+ * Returns 0.
+ \*-------------------------------------------------------------------------*/
+-static size_t b64pad(const UC *input, size_t size,
++static size_t b64pad(const UC *input, size_t size,
+ luaL_Buffer *buffer)
+ {
+ unsigned long value = 0;
+@@ -203,7 +203,7 @@ static size_t b64pad(const UC *input, size_t size,
+ luaL_addlstring(buffer, (char *) code, 4);
+ break;
+ case 2:
+- value = input[0]; value <<= 8;
++ value = input[0]; value <<= 8;
+ value |= input[1]; value <<= 2;
+ code[2] = b64base[value & 0x3f]; value >>= 6;
+ code[1] = b64base[value & 0x3f]; value >>= 6;
+@@ -217,11 +217,11 @@ static size_t b64pad(const UC *input, size_t size,
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* Acumulates bytes in input buffer until 4 bytes are available.
++* Acumulates bytes in input buffer until 4 bytes are available.
+ * Translate the 4 bytes from Base64 form and append to buffer.
+ * Returns new number of bytes in buffer.
+ \*-------------------------------------------------------------------------*/
+-static size_t b64decode(UC c, UC *input, size_t size,
++static size_t b64decode(UC c, UC *input, size_t size,
+ luaL_Buffer *buffer)
+ {
+ /* ignore invalid characters */
+@@ -239,7 +239,7 @@ static size_t b64decode(UC c, UC *input, size_t size,
+ decoded[1] = (UC) (value & 0xff); value >>= 8;
+ decoded[0] = (UC) value;
+ /* take care of paddding */
+- valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3;
++ valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3;
+ luaL_addlstring(buffer, (char *) decoded, valid);
+ return 0;
+ /* need more data */
+@@ -251,7 +251,7 @@ static size_t b64decode(UC c, UC *input, size_t size,
+ * A, B = b64(C, D)
+ * A is the encoded version of the largest prefix of C .. D that is
+ * divisible by 3. B has the remaining bytes of C .. D, *without* encoding.
+-* The easiest thing would be to concatenate the two strings and
++* The easiest thing would be to concatenate the two strings and
+ * encode the result, but we can't afford that or Lua would dupplicate
+ * every chunk we received.
+ \*-------------------------------------------------------------------------*/
+@@ -259,7 +259,7 @@ static int mime_global_b64(lua_State *L)
+ {
+ UC atom[3];
+ size_t isize = 0, asize = 0;
+- const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
++ const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize);
+ const UC *last = input + isize;
+ luaL_Buffer buffer;
+ /* end-of-input blackhole */
+@@ -272,9 +272,9 @@ static int mime_global_b64(lua_State *L)
+ lua_settop(L, 2);
+ /* process first part of the input */
+ luaL_buffinit(L, &buffer);
+- while (input < last)
++ while (input < last)
+ asize = b64encode(*input++, atom, asize, &buffer);
+- input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
++ input = (const UC *) luaL_optlstring(L, 2, NULL, &isize);
+ /* if second part is nil, we are done */
+ if (!input) {
+ size_t osize = 0;
+@@ -288,7 +288,7 @@ static int mime_global_b64(lua_State *L)
+ }
+ /* otherwise process the second part */
+ last = input + isize;
+- while (input < last)
++ while (input < last)
+ asize = b64encode(*input++, atom, asize, &buffer);
+ luaL_pushresult(&buffer);
+ lua_pushlstring(L, (char *) atom, asize);
+@@ -305,7 +305,7 @@ static int mime_global_unb64(lua_State *L)
+ {
+ UC atom[4];
+ size_t isize = 0, asize = 0;
+- const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
++ const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize);
+ const UC *last = input + isize;
+ luaL_Buffer buffer;
+ /* end-of-input blackhole */
+@@ -318,9 +318,9 @@ static int mime_global_unb64(lua_State *L)
+ lua_settop(L, 2);
+ /* process first part of the input */
+ luaL_buffinit(L, &buffer);
+- while (input < last)
++ while (input < last)
+ asize = b64decode(*input++, atom, asize, &buffer);
+- input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
++ input = (const UC *) luaL_optlstring(L, 2, NULL, &isize);
+ /* if second is nil, we are done */
+ if (!input) {
+ size_t osize = 0;
+@@ -333,7 +333,7 @@ static int mime_global_unb64(lua_State *L)
+ }
+ /* otherwise, process the rest of the input */
+ last = input + isize;
+- while (input < last)
++ while (input < last)
+ asize = b64decode(*input++, atom, asize, &buffer);
+ luaL_pushresult(&buffer);
+ lua_pushlstring(L, (char *) atom, asize);
+@@ -349,7 +349,7 @@ static int mime_global_unb64(lua_State *L)
+ * 9 and 32 can be plain, unless in the end of a line, where must be =XX
+ * encoded lines must be no longer than 76 not counting CRLF
+ * soft line-break are =CRLF
+-* To encode one byte, we need to see the next two.
++* To encode one byte, we need to see the next two.
+ * Worst case is when we see a space, and wonder if a CRLF is comming
+ \*-------------------------------------------------------------------------*/
+ /*-------------------------------------------------------------------------*\
+@@ -362,7 +362,7 @@ static void qpsetup(UC *cl, UC *unbase)
+ for (i = 0; i < 256; i++) cl[i] = QP_QUOTED;
+ for (i = 33; i <= 60; i++) cl[i] = QP_PLAIN;
+ for (i = 62; i <= 126; i++) cl[i] = QP_PLAIN;
+- cl['\t'] = QP_IF_LAST;
++ cl['\t'] = QP_IF_LAST;
+ cl[' '] = QP_IF_LAST;
+ cl['\r'] = QP_CR;
+ for (i = 0; i < 256; i++) unbase[i] = 255;
+@@ -388,9 +388,9 @@ static void qpquote(UC c, luaL_Buffer *buffer)
+
+ /*-------------------------------------------------------------------------*\
+ * Accumulate characters until we are sure about how to deal with them.
+-* Once we are sure, output to the buffer, in the correct form.
++* Once we are sure, output to the buffer, in the correct form.
+ \*-------------------------------------------------------------------------*/
+-static size_t qpencode(UC c, UC *input, size_t size,
++static size_t qpencode(UC c, UC *input, size_t size,
+ const char *marker, luaL_Buffer *buffer)
+ {
+ input[size++] = c;
+@@ -431,7 +431,7 @@ static size_t qpencode(UC c, UC *input, size_t size,
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* Deal with the final characters
++* Deal with the final characters
+ \*-------------------------------------------------------------------------*/
+ static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer)
+ {
+@@ -448,8 +448,8 @@ static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer)
+ * Incrementally converts a string to quoted-printable
+ * A, B = qp(C, D, marker)
+ * Marker is the text to be used to replace CRLF sequences found in A.
+-* A is the encoded version of the largest prefix of C .. D that
+-* can be encoded without doubts.
++* A is the encoded version of the largest prefix of C .. D that
++* can be encoded without doubts.
+ * B has the remaining bytes of C .. D, *without* encoding.
+ \*-------------------------------------------------------------------------*/
+ static int mime_global_qp(lua_State *L)
+@@ -457,7 +457,7 @@ static int mime_global_qp(lua_State *L)
+
+ size_t asize = 0, isize = 0;
+ UC atom[3];
+- const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
++ const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize);
+ const UC *last = input + isize;
+ const char *marker = luaL_optstring(L, 3, CRLF);
+ luaL_Buffer buffer;
+@@ -473,7 +473,7 @@ static int mime_global_qp(lua_State *L)
+ luaL_buffinit(L, &buffer);
+ while (input < last)
+ asize = qpencode(*input++, atom, asize, marker, &buffer);
+- input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
++ input = (const UC *) luaL_optlstring(L, 2, NULL, &isize);
+ /* if second part is nil, we are done */
+ if (!input) {
+ asize = qppad(atom, asize, &buffer);
+@@ -493,7 +493,7 @@ static int mime_global_qp(lua_State *L)
+
+ /*-------------------------------------------------------------------------*\
+ * Accumulate characters until we are sure about how to deal with them.
+-* Once we are sure, output the to the buffer, in the correct form.
++* Once we are sure, output the to the buffer, in the correct form.
+ \*-------------------------------------------------------------------------*/
+ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) {
+ int d;
+@@ -501,8 +501,8 @@ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) {
+ /* deal with all characters we can deal */
+ switch (input[0]) {
+ /* if we have an escape character */
+- case '=':
+- if (size < 3) return size;
++ case '=':
++ if (size < 3) return size;
+ /* eliminate soft line break */
+ if (input[1] == '\r' && input[2] == '\n') return 0;
+ /* decode quoted representation */
+@@ -512,7 +512,7 @@ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) {
+ else luaL_addchar(buffer, (char) ((c << 4) + d));
+ return 0;
+ case '\r':
+- if (size < 2) return size;
++ if (size < 2) return size;
+ if (input[1] == '\n') luaL_addlstring(buffer, (char *)input, 2);
+ return 0;
+ default:
+@@ -525,15 +525,15 @@ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) {
+ /*-------------------------------------------------------------------------*\
+ * Incrementally decodes a string in quoted-printable
+ * A, B = qp(C, D)
+-* A is the decoded version of the largest prefix of C .. D that
+-* can be decoded without doubts.
++* A is the decoded version of the largest prefix of C .. D that
++* can be decoded without doubts.
+ * B has the remaining bytes of C .. D, *without* decoding.
+ \*-------------------------------------------------------------------------*/
+ static int mime_global_unqp(lua_State *L)
+ {
+ size_t asize = 0, isize = 0;
+ UC atom[3];
+- const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
++ const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize);
+ const UC *last = input + isize;
+ luaL_Buffer buffer;
+ /* end-of-input blackhole */
+@@ -548,14 +548,14 @@ static int mime_global_unqp(lua_State *L)
+ luaL_buffinit(L, &buffer);
+ while (input < last)
+ asize = qpdecode(*input++, atom, asize, &buffer);
+- input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
++ input = (const UC *) luaL_optlstring(L, 2, NULL, &isize);
+ /* if second part is nil, we are done */
+ if (!input) {
+ luaL_pushresult(&buffer);
+ if (!(*lua_tostring(L, -1))) lua_pushnil(L);
+ lua_pushnil(L);
+ return 2;
+- }
++ }
+ /* otherwise process rest of input */
+ last = input + isize;
+ while (input < last)
+@@ -568,9 +568,9 @@ static int mime_global_unqp(lua_State *L)
+ /*-------------------------------------------------------------------------*\
+ * Incrementally breaks a quoted-printed string into lines
+ * A, n = qpwrp(l, B, length)
+-* A is a copy of B, broken into lines of at most 'length' bytes.
+-* 'l' is how many bytes are left for the first line of B.
+-* 'n' is the number of bytes left in the last line of A.
++* A is a copy of B, broken into lines of at most 'length' bytes.
++* 'l' is how many bytes are left for the first line of B.
++* 'n' is the number of bytes left in the last line of A.
+ * There are two complications: lines can't be broken in the middle
+ * of an encoded =XX, and there might be line breaks already
+ \*-------------------------------------------------------------------------*/
+@@ -578,7 +578,7 @@ static int mime_global_qpwrp(lua_State *L)
+ {
+ size_t size = 0;
+ int left = (int) luaL_checknumber(L, 1);
+- const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size);
++ const UC *input = (const UC *) luaL_optlstring(L, 2, NULL, &size);
+ const UC *last = input + size;
+ int length = (int) luaL_optnumber(L, 3, 76);
+ luaL_Buffer buffer;
+@@ -603,11 +603,11 @@ static int mime_global_qpwrp(lua_State *L)
+ if (left <= 3) {
+ left = length;
+ luaL_addstring(&buffer, EQCRLF);
+- }
++ }
+ luaL_addchar(&buffer, *input);
+ left--;
+ break;
+- default:
++ default:
+ if (left <= 1) {
+ left = length;
+ luaL_addstring(&buffer, EQCRLF);
+@@ -635,7 +635,7 @@ static int mime_global_qpwrp(lua_State *L)
+ * last is the previous character
+ \*-------------------------------------------------------------------------*/
+ #define eolcandidate(c) (c == '\r' || c == '\n')
+-static int eolprocess(int c, int last, const char *marker,
++static int eolprocess(int c, int last, const char *marker,
+ luaL_Buffer *buffer)
+ {
+ if (eolcandidate(c)) {
+@@ -653,15 +653,15 @@ static int eolprocess(int c, int last, const char *marker,
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* Converts a string to uniform EOL convention.
++* Converts a string to uniform EOL convention.
+ * A, n = eol(o, B, marker)
+ * A is the converted version of the largest prefix of B that can be
+-* converted unambiguously. 'o' is the context returned by the previous
++* converted unambiguously. 'o' is the context returned by the previous
+ * call. 'n' is the new context.
+ \*-------------------------------------------------------------------------*/
+ static int mime_global_eol(lua_State *L)
+ {
+- int ctx = luaL_checkint(L, 1);
++ int ctx = luaL_checkinteger(L, 1);
+ size_t isize = 0;
+ const char *input = luaL_optlstring(L, 2, NULL, &isize);
+ const char *last = input + isize;
+@@ -683,18 +683,18 @@ static int mime_global_eol(lua_State *L)
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* Takes one byte and stuff it if needed.
++* Takes one byte and stuff it if needed.
+ \*-------------------------------------------------------------------------*/
+ static size_t dot(int c, size_t state, luaL_Buffer *buffer)
+ {
+ luaL_addchar(buffer, (char) c);
+ switch (c) {
+- case '\r':
++ case '\r':
+ return 1;
+- case '\n':
+- return (state == 1)? 2: 0;
+- case '.':
+- if (state == 2)
++ case '\n':
++ return (state == 1)? 2: 0;
++ case '.':
++ if (state == 2)
+ luaL_addchar(buffer, '.');
+ default:
+ return 0;
+@@ -719,7 +719,7 @@ static int mime_global_dot(lua_State *L)
+ }
+ /* process all input */
+ luaL_buffinit(L, &buffer);
+- while (input < last)
++ while (input < last)
+ state = dot(*input++, state, &buffer);
+ luaL_pushresult(&buffer);
+ lua_pushnumber(L, (lua_Number) state);
+diff --git a/src/options.h b/src/options.h
+index 5657a06..b75db37 100644
+--- a/src/options.h
++++ b/src/options.h
+@@ -51,7 +51,8 @@ int opt_get_error(lua_State *L, p_socket ps);
+ int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps);
+ int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps);
+ int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps);
+-int opt_get_ip6_v6only(lua_State *L, p_socket ps);
++int opt_get_ip6_v6only(lua_State *L, p_socket ps);
++int opt_get_reuseport(lua_State *L, p_socket ps);
+
+ /* invokes the appropriate option handler */
+ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps);
+diff --git a/src/pierror.h b/src/pierror.h
+new file mode 100644
+index 0000000..cb773ab
+--- /dev/null
++++ b/src/pierror.h
+@@ -0,0 +1,28 @@
++#ifndef PIERROR_H
++#define PIERROR_H
++/*=========================================================================*\
++* Error messages
++* Defines platform independent error messages
++\*=========================================================================*/
++
++#define PIE_HOST_NOT_FOUND "host not found"
++#define PIE_ADDRINUSE "address already in use"
++#define PIE_ISCONN "already connected"
++#define PIE_ACCESS "permission denied"
++#define PIE_CONNREFUSED "connection refused"
++#define PIE_CONNABORTED "closed"
++#define PIE_CONNRESET "closed"
++#define PIE_TIMEDOUT "timeout"
++#define PIE_AGAIN "temporary failure in name resolution"
++#define PIE_BADFLAGS "invalid value for ai_flags"
++#define PIE_BADHINTS "invalid value for hints"
++#define PIE_FAIL "non-recoverable failure in name resolution"
++#define PIE_FAMILY "ai_family not supported"
++#define PIE_MEMORY "memory allocation failure"
++#define PIE_NONAME "host or service not provided, or not known"
++#define PIE_OVERFLOW "argument buffer overflow"
++#define PIE_PROTOCOL "resolved protocol is unknown"
++#define PIE_SERVICE "service not supported for socket type"
++#define PIE_SOCKTYPE "ai_socktype not supported"
++
++#endif
+diff --git a/src/udp.c b/src/udp.c
+index a9f2393..12e320a 100644
+--- a/src/udp.c
++++ b/src/udp.c
+@@ -131,7 +131,7 @@ int udp_open(lua_State *L)
+ /*=========================================================================*\
+ * Lua methods
+ \*=========================================================================*/
+-const char *udp_strerror(int err) {
++static const char *udp_strerror(int err) {
+ /* a 'closed' error on an unconnected means the target address was not
+ * accepted by the transport layer */
+ if (err == IO_CLOSED) return "refused";
+diff --git a/src/usocket.c b/src/usocket.c
+index 096ecd0..99e551b 100644
+--- a/src/usocket.c
++++ b/src/usocket.c
+@@ -4,12 +4,13 @@
+ *
+ * The code is now interrupt-safe.
+ * The penalty of calling select to avoid busy-wait is only paid when
+-* the I/O call fail in the first place.
++* the I/O call fail in the first place.
+ \*=========================================================================*/
+-#include <string.h>
++#include <string.h>
+ #include <signal.h>
+
+ #include "socket.h"
++#include "pierror.h"
+
+ /*-------------------------------------------------------------------------*\
+ * Wait for readable/writable/connected socket with timeout
+@@ -72,7 +73,7 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
+
+
+ /*-------------------------------------------------------------------------*\
+-* Initializes module
++* Initializes module
+ \*-------------------------------------------------------------------------*/
+ int socket_open(void) {
+ /* instals a handler to ignore sigpipe or it will crash us */
+@@ -81,7 +82,7 @@ int socket_open(void) {
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* Close module
++* Close module
+ \*-------------------------------------------------------------------------*/
+ int socket_close(void) {
+ return 1;
+@@ -92,7 +93,6 @@ int socket_close(void) {
+ \*-------------------------------------------------------------------------*/
+ void socket_destroy(p_socket ps) {
+ if (*ps != SOCKET_INVALID) {
+- socket_setblocking(ps);
+ close(*ps);
+ *ps = SOCKET_INVALID;
+ }
+@@ -101,7 +101,7 @@ void socket_destroy(p_socket ps) {
+ /*-------------------------------------------------------------------------*\
+ * Select with timeout control
+ \*-------------------------------------------------------------------------*/
+-int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
++int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
+ p_timeout tm) {
+ int ret;
+ do {
+@@ -120,8 +120,8 @@ int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
+ \*-------------------------------------------------------------------------*/
+ int socket_create(p_socket ps, int domain, int type, int protocol) {
+ *ps = socket(domain, type, protocol);
+- if (*ps != SOCKET_INVALID) return IO_DONE;
+- else return errno;
++ if (*ps != SOCKET_INVALID) return IO_DONE;
++ else return errno;
+ }
+
+ /*-------------------------------------------------------------------------*\
+@@ -130,29 +130,25 @@ int socket_create(p_socket ps, int domain, int type, int protocol) {
+ int socket_bind(p_socket ps, SA *addr, socklen_t len) {
+ int err = IO_DONE;
+ socket_setblocking(ps);
+- if (bind(*ps, addr, len) < 0) err = errno;
++ if (bind(*ps, addr, len) < 0) err = errno;
+ socket_setnonblocking(ps);
+ return err;
+ }
+
+ /*-------------------------------------------------------------------------*\
+-*
++*
+ \*-------------------------------------------------------------------------*/
+ int socket_listen(p_socket ps, int backlog) {
+- int err = IO_DONE;
+- socket_setblocking(ps);
+- if (listen(*ps, backlog)) err = errno;
+- socket_setnonblocking(ps);
++ int err = IO_DONE;
++ if (listen(*ps, backlog)) err = errno;
+ return err;
+ }
+
+ /*-------------------------------------------------------------------------*\
+-*
++*
+ \*-------------------------------------------------------------------------*/
+ void socket_shutdown(p_socket ps, int how) {
+- socket_setblocking(ps);
+ shutdown(*ps, how);
+- socket_setnonblocking(ps);
+ }
+
+ /*-------------------------------------------------------------------------*\
+@@ -166,7 +162,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
+ do if (connect(*ps, addr, len) == 0) return IO_DONE;
+ while ((err = errno) == EINTR);
+ /* if connection failed immediately, return error code */
+- if (err != EINPROGRESS && err != EAGAIN) return err;
++ if (err != EINPROGRESS && err != EAGAIN) return err;
+ /* zero timeout case optimization */
+ if (timeout_iszero(tm)) return IO_TIMEOUT;
+ /* wait until we have the result of the connection attempt or timeout */
+@@ -181,7 +177,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
+ * Accept with timeout
+ \*-------------------------------------------------------------------------*/
+ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) {
+- if (*ps == SOCKET_INVALID) return IO_CLOSED;
++ if (*ps == SOCKET_INVALID) return IO_CLOSED;
+ for ( ;; ) {
+ int err;
+ if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
+@@ -197,7 +193,7 @@ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout
+ /*-------------------------------------------------------------------------*\
+ * Send with timeout
+ \*-------------------------------------------------------------------------*/
+-int socket_send(p_socket ps, const char *data, size_t count,
++int socket_send(p_socket ps, const char *data, size_t count,
+ size_t *sent, p_timeout tm)
+ {
+ int err;
+@@ -229,14 +225,14 @@ int socket_send(p_socket ps, const char *data, size_t count,
+ /*-------------------------------------------------------------------------*\
+ * Sendto with timeout
+ \*-------------------------------------------------------------------------*/
+-int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
++int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
+ SA *addr, socklen_t len, p_timeout tm)
+ {
+ int err;
+ *sent = 0;
+ if (*ps == SOCKET_INVALID) return IO_CLOSED;
+ for ( ;; ) {
+- long put = (long) sendto(*ps, data, count, 0, addr, len);
++ long put = (long) sendto(*ps, data, count, 0, addr, len);
+ if (put >= 0) {
+ *sent = put;
+ return IO_DONE;
+@@ -266,8 +262,8 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
+ err = errno;
+ if (taken == 0) return IO_CLOSED;
+ if (err == EINTR) continue;
+- if (err != EAGAIN) return err;
+- if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
++ if (err != EAGAIN) return err;
++ if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
+ }
+ return IO_UNKNOWN;
+ }
+@@ -275,7 +271,7 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
+ /*-------------------------------------------------------------------------*\
+ * Recvfrom with timeout
+ \*-------------------------------------------------------------------------*/
+-int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
++int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
+ SA *addr, socklen_t *len, p_timeout tm) {
+ int err;
+ *got = 0;
+@@ -289,8 +285,8 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
+ err = errno;
+ if (taken == 0) return IO_CLOSED;
+ if (err == EINTR) continue;
+- if (err != EAGAIN) return err;
+- if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
++ if (err != EAGAIN) return err;
++ if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
+ }
+ return IO_UNKNOWN;
+ }
+@@ -303,7 +299,7 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
+ * with send/recv replaced with write/read. We can't just use write/read
+ * in the socket version, because behaviour when size is zero is different.
+ \*-------------------------------------------------------------------------*/
+-int socket_write(p_socket ps, const char *data, size_t count,
++int socket_write(p_socket ps, const char *data, size_t count,
+ size_t *sent, p_timeout tm)
+ {
+ int err;
+@@ -349,8 +345,8 @@ int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
+ err = errno;
+ if (taken == 0) return IO_CLOSED;
+ if (err == EINTR) continue;
+- if (err != EAGAIN) return err;
+- if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
++ if (err != EAGAIN) return err;
++ if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
+ }
+ return IO_UNKNOWN;
+ }
+@@ -374,7 +370,7 @@ void socket_setnonblocking(p_socket ps) {
+ }
+
+ /*-------------------------------------------------------------------------*\
+-* DNS helpers
++* DNS helpers
+ \*-------------------------------------------------------------------------*/
+ int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
+ *hp = gethostbyaddr(addr, len, AF_INET);
+@@ -399,7 +395,7 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) {
+ const char *socket_hoststrerror(int err) {
+ if (err <= 0) return io_strerror(err);
+ switch (err) {
+- case HOST_NOT_FOUND: return "host not found";
++ case HOST_NOT_FOUND: return PIE_HOST_NOT_FOUND;
+ default: return hstrerror(err);
+ }
+ }
+@@ -407,13 +403,13 @@ const char *socket_hoststrerror(int err) {
+ const char *socket_strerror(int err) {
+ if (err <= 0) return io_strerror(err);
+ switch (err) {
+- case EADDRINUSE: return "address already in use";
+- case EISCONN: return "already connected";
+- case EACCES: return "permission denied";
+- case ECONNREFUSED: return "connection refused";
+- case ECONNABORTED: return "closed";
+- case ECONNRESET: return "closed";
+- case ETIMEDOUT: return "timeout";
++ case EADDRINUSE: return PIE_ADDRINUSE;
++ case EISCONN: return PIE_ISCONN;
++ case EACCES: return PIE_ACCESS;
++ case ECONNREFUSED: return PIE_CONNREFUSED;
++ case ECONNABORTED: return PIE_CONNABORTED;
++ case ECONNRESET: return PIE_CONNRESET;
++ case ETIMEDOUT: return PIE_TIMEDOUT;
+ default: return strerror(err);
+ }
+ }
+@@ -421,28 +417,27 @@ const char *socket_strerror(int err) {
+ const char *socket_ioerror(p_socket ps, int err) {
+ (void) ps;
+ return socket_strerror(err);
+-}
++}
+
+ const char *socket_gaistrerror(int err) {
+- if (err == 0) return NULL;
++ if (err == 0) return NULL;
+ switch (err) {
+- case EAI_AGAIN: return "temporary failure in name resolution";
+- case EAI_BADFLAGS: return "invalid value for ai_flags";
++ case EAI_AGAIN: return PIE_AGAIN;
++ case EAI_BADFLAGS: return PIE_BADFLAGS;
+ #ifdef EAI_BADHINTS
+- case EAI_BADHINTS: return "invalid value for hints";
++ case EAI_BADHINTS: return PIE_BADHINTS;
+ #endif
+- case EAI_FAIL: return "non-recoverable failure in name resolution";
+- case EAI_FAMILY: return "ai_family not supported";
+- case EAI_MEMORY: return "memory allocation failure";
+- case EAI_NONAME:
+- return "host or service not provided, or not known";
+- case EAI_OVERFLOW: return "argument buffer overflow";
++ case EAI_FAIL: return PIE_FAIL;
++ case EAI_FAMILY: return PIE_FAMILY;
++ case EAI_MEMORY: return PIE_MEMORY;
++ case EAI_NONAME: return PIE_NONAME;
++ case EAI_OVERFLOW: return PIE_OVERFLOW;
+ #ifdef EAI_PROTOCOL
+- case EAI_PROTOCOL: return "resolved protocol is unknown";
++ case EAI_PROTOCOL: return PIE_PROTOCOL;
+ #endif
+- case EAI_SERVICE: return "service not supported for socket type";
+- case EAI_SOCKTYPE: return "ai_socktype not supported";
+- case EAI_SYSTEM: return strerror(errno);
++ case EAI_SERVICE: return PIE_SERVICE;
++ case EAI_SOCKTYPE: return PIE_SOCKTYPE;
++ case EAI_SYSTEM: return strerror(errno);
+ default: return gai_strerror(err);
+ }
+ }
+diff --git a/src/wsocket.c b/src/wsocket.c
+index b4a4384..10800e3 100644
+--- a/src/wsocket.c
++++ b/src/wsocket.c
+@@ -8,6 +8,7 @@
+ #include <string.h>
+
+ #include "socket.h"
++#include "pierror.h"
+
+ /* WinSock doesn't have a strerror... */
+ static const char *wstrerror(int err);
+@@ -330,7 +331,7 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) {
+ const char *socket_hoststrerror(int err) {
+ if (err <= 0) return io_strerror(err);
+ switch (err) {
+- case WSAHOST_NOT_FOUND: return "host not found";
++ case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND;
+ default: return wstrerror(err);
+ }
+ }
+@@ -338,13 +339,13 @@ const char *socket_hoststrerror(int err) {
+ const char *socket_strerror(int err) {
+ if (err <= 0) return io_strerror(err);
+ switch (err) {
+- case WSAEADDRINUSE: return "address already in use";
+- case WSAECONNREFUSED: return "connection refused";
+- case WSAEISCONN: return "already connected";
+- case WSAEACCES: return "permission denied";
+- case WSAECONNABORTED: return "closed";
+- case WSAECONNRESET: return "closed";
+- case WSAETIMEDOUT: return "timeout";
++ case WSAEADDRINUSE: return PIE_ADDRINUSE;
++ case WSAECONNREFUSED : return PIE_CONNREFUSED;
++ case WSAEISCONN: return PIE_ISCONN;
++ case WSAEACCES: return PIE_ACCESS;
++ case WSAECONNABORTED: return PIE_CONNABORTED;
++ case WSAECONNRESET: return PIE_CONNRESET;
++ case WSAETIMEDOUT: return PIE_TIMEDOUT;
+ default: return wstrerror(err);
+ }
+ }
+@@ -357,7 +358,7 @@ const char *socket_ioerror(p_socket ps, int err) {
+ static const char *wstrerror(int err) {
+ switch (err) {
+ case WSAEINTR: return "Interrupted function call";
+- case WSAEACCES: return "Permission denied";
++ case WSAEACCES: return PIE_ACCESS; // "Permission denied";
+ case WSAEFAULT: return "Bad address";
+ case WSAEINVAL: return "Invalid argument";
+ case WSAEMFILE: return "Too many open files";
+@@ -370,24 +371,23 @@ static const char *wstrerror(int err) {
+ case WSAEPROTOTYPE: return "Protocol wrong type for socket";
+ case WSAENOPROTOOPT: return "Bad protocol option";
+ case WSAEPROTONOSUPPORT: return "Protocol not supported";
+- case WSAESOCKTNOSUPPORT: return "Socket type not supported";
++ case WSAESOCKTNOSUPPORT: return PIE_SOCKTYPE; // "Socket type not supported";
+ case WSAEOPNOTSUPP: return "Operation not supported";
+ case WSAEPFNOSUPPORT: return "Protocol family not supported";
+- case WSAEAFNOSUPPORT:
+- return "Address family not supported by protocol family";
+- case WSAEADDRINUSE: return "Address already in use";
++ case WSAEAFNOSUPPORT: return PIE_FAMILY; // "Address family not supported by protocol family";
++ case WSAEADDRINUSE: return PIE_ADDRINUSE; // "Address already in use";
+ case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
+ case WSAENETDOWN: return "Network is down";
+ case WSAENETUNREACH: return "Network is unreachable";
+ case WSAENETRESET: return "Network dropped connection on reset";
+ case WSAECONNABORTED: return "Software caused connection abort";
+- case WSAECONNRESET: return "Connection reset by peer";
++ case WSAECONNRESET: return PIE_CONNRESET; // "Connection reset by peer";
+ case WSAENOBUFS: return "No buffer space available";
+- case WSAEISCONN: return "Socket is already connected";
++ case WSAEISCONN: return PIE_ISCONN; // "Socket is already connected";
+ case WSAENOTCONN: return "Socket is not connected";
+ case WSAESHUTDOWN: return "Cannot send after socket shutdown";
+- case WSAETIMEDOUT: return "Connection timed out";
+- case WSAECONNREFUSED: return "Connection refused";
++ case WSAETIMEDOUT: return PIE_TIMEDOUT; // "Connection timed out";
++ case WSAECONNREFUSED: return PIE_CONNREFUSED; // "Connection refused";
+ case WSAEHOSTDOWN: return "Host is down";
+ case WSAEHOSTUNREACH: return "No route to host";
+ case WSAEPROCLIM: return "Too many processes";
+@@ -396,9 +396,9 @@ static const char *wstrerror(int err) {
+ case WSANOTINITIALISED:
+ return "Successful WSAStartup not yet performed";
+ case WSAEDISCON: return "Graceful shutdown in progress";
+- case WSAHOST_NOT_FOUND: return "Host not found";
++ case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; // "Host not found";
+ case WSATRY_AGAIN: return "Nonauthoritative host not found";
+- case WSANO_RECOVERY: return "Nonrecoverable name lookup error";
++ case WSANO_RECOVERY: return PIE_FAIL; // "Nonrecoverable name lookup error";
+ case WSANO_DATA: return "Valid name, no data record of requested type";
+ default: return "Unknown error";
+ }
+@@ -407,24 +407,23 @@ static const char *wstrerror(int err) {
+ const char *socket_gaistrerror(int err) {
+ if (err == 0) return NULL;
+ switch (err) {
+- case EAI_AGAIN: return "temporary failure in name resolution";
+- case EAI_BADFLAGS: return "invalid value for ai_flags";
++ case EAI_AGAIN: return PIE_AGAIN;
++ case EAI_BADFLAGS: return PIE_BADFLAGS;
+ #ifdef EAI_BADHINTS
+- case EAI_BADHINTS: return "invalid value for hints";
++ case EAI_BADHINTS: return PIE_BADHINTS;
+ #endif
+- case EAI_FAIL: return "non-recoverable failure in name resolution";
+- case EAI_FAMILY: return "ai_family not supported";
+- case EAI_MEMORY: return "memory allocation failure";
+- case EAI_NONAME:
+- return "host or service not provided, or not known";
++ case EAI_FAIL: return PIE_FAIL;
++ case EAI_FAMILY: return PIE_FAMILY;
++ case EAI_MEMORY: return PIE_MEMORY;
++ case EAI_NONAME: return PIE_NONAME;
+ #ifdef EAI_OVERFLOW
+- case EAI_OVERFLOW: return "argument buffer overflow";
++ case EAI_OVERFLOW: return PIE_OVERFLOW;
+ #endif
+ #ifdef EAI_PROTOCOL
+- case EAI_PROTOCOL: return "resolved protocol is unknown";
++ case EAI_PROTOCOL: return PIE_PROTOCOL;
+ #endif
+- case EAI_SERVICE: return "service not supported for socket type";
+- case EAI_SOCKTYPE: return "ai_socktype not supported";
++ case EAI_SERVICE: return PIE_SERVICE;
++ case EAI_SOCKTYPE: return PIE_SOCKTYPE;
+ #ifdef EAI_SYSTEM
+ case EAI_SYSTEM: return strerror(errno);
+ #endif
+diff --git a/test/auth/.htaccess b/test/auth/.htaccess
+new file mode 100644
+index 0000000..bb2794a
+--- /dev/null
++++ b/test/auth/.htaccess
+@@ -0,0 +1,4 @@
++AuthName "test-auth"
++ AuthType Basic
++ AuthUserFile /Users/diego/impa/luasocket/test/auth/.htpasswd
++ Require valid-user
+diff --git a/test/auth/.htpasswd b/test/auth/.htpasswd
+index fd9002b..cfb2603 100644
+--- a/test/auth/.htpasswd
++++ b/test/auth/.htpasswd
+@@ -1 +1 @@
+-luasocket:l8n2npozPB.sQ
++luasocket:$apr1$47u2O.Me$.m/5BWAtt7GVoxsouIPBR1
+diff --git a/test/httptest.lua b/test/httptest.lua
+index d5fbb37..63ff921 100644
+--- a/test/httptest.lua
++++ b/test/httptest.lua
+@@ -1,4 +1,4 @@
+--- needs Alias from /home/c/diego/tec/luasocket/test to
++-- needs Alias from /home/c/diego/tec/luasocket/test to
+ -- "/luasocket-test" and "/luasocket-test/"
+ -- needs ScriptAlias from /home/c/diego/tec/luasocket/test/cgi
+ -- to "/luasocket-test-cgi" and "/luasocket-test-cgi/"
+@@ -36,22 +36,22 @@ index = readfile(index_file)
+ local check_result = function(response, expect, ignore)
+ for i,v in pairs(response) do
+ if not ignore[i] then
+- if v ~= expect[i] then
++ if v ~= expect[i] then
+ local f = io.open("err", "w")
+ f:write(tostring(v), "\n\n versus\n\n", tostring(expect[i]))
+ f:close()
+- fail(i .. " differs!")
++ fail(i .. " differs!")
+ end
+ end
+ end
+ for i,v in pairs(expect) do
+ if not ignore[i] then
+- if v ~= response[i] then
++ if v ~= response[i] then
+ local f = io.open("err", "w")
+ f:write(tostring(response[i]), "\n\n versus\n\n", tostring(v))
+ v = string.sub(type(v) == "string" and v or "", 1, 70)
+ f:close()
+- fail(i .. " differs!")
++ fail(i .. " differs!")
+ end
+ end
+ end
+@@ -61,10 +61,10 @@ end
+ local check_request = function(request, expect, ignore)
+ local t
+ if not request.sink then request.sink, t = ltn12.sink.table() end
+- request.source = request.source or
++ request.source = request.source or
+ (request.body and ltn12.source.string(request.body))
+ local response = {}
+- response.code, response.headers, response.status =
++ response.code, response.headers, response.status =
+ socket.skip(1, http.request(request))
+ if t and #t > 0 then response.body = table.concat(t) end
+ check_result(response, expect, ignore)
+@@ -82,7 +82,7 @@ else fail(back.query) end
+ ------------------------------------------------------------------------
+ io.write("testing query string correctness: ")
+ forth = "this+is+the+query+string"
+-back = http.request("http://" .. host .. cgiprefix ..
++back = http.request("http://" .. host .. cgiprefix ..
+ "/query-string?" .. forth)
+ if similar(back, forth) then print("ok")
+ else fail("failed!") end
+@@ -120,10 +120,10 @@ check_request(request, expect, ignore)
+ ------------------------------------------------------------------------
+ io.write("testing invalid url: ")
+ local r, e = http.request{url = host .. prefix}
+-assert(r == nil and e == "invalid host ''")
++assert(r == nil and e == "invalid host ''")
+ r, re = http.request(host .. prefix)
+-assert(r == nil and e == re, tostring(r) ..", " .. tostring(re) ..
+- " vs " .. tostring(e))
++assert(r == nil and e == re, tostring(r) ..", " .. tostring(re) ..
++ " vs " .. tostring(e))
+ print("ok")
+
+ io.write("testing invalid empty port: ")
+@@ -212,7 +212,7 @@ os.remove(index_file .. "-back")
+ io.write("testing ltn12.(sink|source).chain and mime.(encode|decode): ")
+
+ local function b64length(len)
+- local a = math.ceil(len/3)*4
++ local a = math.ceil(len/3)*4
+ local l = math.ceil(a/76)
+ return a + l*2
+ end
+@@ -313,7 +313,7 @@ ignore = {
+ headers = 1
+ }
+ check_request(request, expect, ignore)
+-
++
+ ------------------------------------------------------------------------
+ io.write("testing document not found: ")
+ request = {
+@@ -429,9 +429,9 @@ print("ok")
+ io.write("testing host not found: ")
+ local c, e = socket.connect("example.invalid", 80)
+ local r, re = http.request{url = "http://example.invalid/does/not/exist"}
+-assert(r == nil and e == re, tostring(r) .. " " .. tostring(re))
++assert(r == nil and e == re, tostring(r) .. " " .. tostring(re))
+ r, re = http.request("http://example.invalid/does/not/exist")
+-assert(r == nil and e == re)
++assert(r == nil and e == re)
+ print("ok")
+
+ ------------------------------------------------------------------------
+diff --git a/test/ltn12test.lua b/test/ltn12test.lua
+index 74a45e8..e3f85fb 100644
+--- a/test/ltn12test.lua
++++ b/test/ltn12test.lua
+@@ -192,6 +192,21 @@ assert(filter(nil, 1), "filter not empty")
+ print("ok")
+
+ --------------------------------
++io.write("testing source.chain (with several filters): ")
++local function double(x) -- filter turning "ABC" into "AABBCC"
++ if not x then return end
++ local b={}
++ for k in x:gmatch'.' do table.insert(b, k..k) end
++ return table.concat(b)
++end
++source = ltn12.source.string(s)
++source = ltn12.source.chain(source, double, double, double)
++sink, t = ltn12.sink.table()
++assert(ltn12.pump.all(source, sink), "returned error")
++assert(table.concat(t) == double(double(double(s))), "mismatch")
++print("ok")
++
++--------------------------------
+ io.write("testing source.chain (with split) and sink.chain (with merge): ")
+ source = ltn12.source.string(s)
+ filter = split(5)
+@@ -206,6 +221,15 @@ assert(filter2(nil, 1), "filter2 not empty")
+ print("ok")
+
+ --------------------------------
++io.write("testing sink.chain (with several filters): ")
++source = ltn12.source.string(s)
++sink, t = ltn12.sink.table()
++sink = ltn12.sink.chain(double, double, double, sink)
++assert(ltn12.pump.all(source, sink), "returned error")
++assert(table.concat(t) == double(double(double(s))), "mismatch")
++print("ok")
++
++--------------------------------
+ io.write("testing filter.chain (and sink.chain, with split, merge): ")
+ source = ltn12.source.string(s)
+ filter = split(5)
+@@ -272,3 +296,4 @@ assert(filter3(nil, 1), "filter3 not empty")
+ assert(filter4(nil, 1), "filter4 not empty")
+ assert(filter5(nil, 1), "filter5 not empty")
+ print("ok")
++
diff --git a/main/lua-socket/lua-cflags.patch b/main/lua-socket/lua-cflags.patch
index eace4258aa..be205f4b04 100644
--- a/main/lua-socket/lua-cflags.patch
+++ b/main/lua-socket/lua-cflags.patch
@@ -1,6 +1,6 @@
---- ./src/makefile.orig 2013-07-09 14:20:08.772827698 +0000
-+++ ./src/makefile 2013-07-09 14:22:46.311231590 +0000
-@@ -142,6 +142,8 @@
+--- src/makefile.orig
++++ ./src/makefile
+@@ -156,6 +156,8 @@
#------
# Compiler and linker settings
# for Linux
@@ -9,12 +9,12 @@
SO_linux=so
O_linux=o
CC_linux=gcc
-@@ -149,7 +151,7 @@
+@@ -163,7 +165,7 @@
-DLUASOCKET_API='__attribute__((visibility("default")))' \
-DUNIX_API='__attribute__((visibility("default")))' \
-DMIME_API='__attribute__((visibility("default")))'
--CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra \
-+CFLAGS_linux= $(LUA_CFLAGS) -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra \
+-CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \
++CFLAGS_linux= $(LUA_CFLAGS) -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \
-Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden
LDFLAGS_linux=-O -shared -fpic -o
LD_linux=gcc