--
-- This file is part of LEM, a Lua Event Machine.
-- Copyright 2011-2013 Emil Renner Berthing
--
-- LEM is free software: you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as
-- published by the Free Software Foundation, either version 3 of
-- the License, or (at your option) any later version.
--
-- LEM is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with LEM. If not, see <http://www.gnu.org/licenses/>.
--
local utils = require 'lem.utils'
local io = require 'lem.io.core'
local type = type
local assert = assert
local error = error
do
local parsers = require 'lem.parsers'
io.Stream.read = parsers.newreader(io.Stream.readp)
io.File.read = parsers.newreader(io.File.readp)
end
do
local stdin = io.stdin
function io.input(file)
if not file then return stdin end
if type(file) == 'string' then
stdin = assert(io.open(file))
else
stdin = file
end
end
function io.read(...)
return stdin:read(...)
end
local streamfile, error = io.streamfile, error
function io.lines(filename, fmt)
if not filename then return stdin:lines(fmt) end
if not fmt then fmt = '*l' end
local file, err = streamfile(filename)
if not file then error(err, 2) end
return function(s)
local line = s:read(fmt)
if not line then s:close() end
return line
end, file
end
end
do
local stdout = io.stdout
function io.output(file)
if not file then return stdout end
if type(file) == 'string' then
stdout = assert(io.open(file))
else
stdout = file
end
end
function io.write(...)
return stdout:write(...)
end
function io.print(...)
return stdout:print(...)
end
function io.close(file)
if not file then file = stdout end
return file:close()
end
end
function io.File:lines(fmt)
if not fmt then fmt = '*l' end
return function(s)
return s:read(fmt)
end, self
end
io.Stream.lines = io.File.lines
if not io.Stream.cork then
function io.Stream:cork()
return nil, 'Operation not supported'
end
io.Stream.uncork = io.Stream.cork
end
do
local MultiServer = {}
MultiServer.__index = MultiServer
io.MultiServer = MultiServer
function MultiServer:interrupt()
return self[1]:interrupt()
end
function MultiServer:close()
local rok, rerr = true
for i = 1, #self do
local ok, err = self[i]:close()
if not ok then
rok, rerr = ok, err
end
end
return rok, rerr
end
local function autospawn(self, i, handler)
local ok, err = self[i]:autospawn(handler)
if self.running then
self.running, self.ok, self.err = false, ok, err
end
for i = 1, #self do
self[i]:interrupt()
end
end
local spawn = utils.spawn
function MultiServer:autospawn(handler)
local n = #self
self.running = true
for i = 1, n-1 do
spawn(autospawn, self, i, handler)
end
autospawn(self, n, handler)
return self.ok, self.err
end
local setmetatable = setmetatable
local listen4, listen6 = io.tcp.listen4, io.tcp.listen6
function io.tcp.listen(host, port)
if host:match(':') then
return listen6(host, port)
end
local s6, err = listen6(host, port)
if s6 then
local s4 = listen4(host, port)
if s4 then
return setmetatable({ s6, s4 }, MultiServer)
end
return s6
else
return listen4(host, port)
end
end
end
return io
-- vim: ts=2 sw=2 noet: