+end
+
+function meta.blocksource(self, bs, limit)
+ bs = bs or BUFFERSIZE
+ return function()
+ local toread = bs
+ if limit then
+ if limit < 1 then
+ return nil
+ elseif limit < toread then
+ toread = limit
+ end
+ end
+
+ local block, code, msg = self:read(toread)
+
+ if not block then
+ return nil, code, msg
+ elseif #block == 0 then
+ return nil
+ else
+ if limit then
+ limit = limit - #block
+ end
+
+ return block
+ end
+ end
+end
+
+function meta.sink(self, close)
+ return function(chunk, src_err)
+ if not chunk and not src_err and close then
+ if self.shutdown then
+ self:shutdown()
+ end
+ self:close()
+ elseif chunk and #chunk > 0 then
+ return self:writeall(chunk)
+ end
+ return true
+ end
+end
+
+function meta.copy(self, fdout, size)
+ local source = self:blocksource(nil, size)
+ local sink = fdout:sink()
+ local sent, chunk, code, msg = 0
+
+ repeat
+ chunk, code, msg = source()
+ sink(chunk, code, msg)
+ sent = chunk and (sent + #chunk) or sent
+ until not chunk
+ return not code and sent or nil, code, msg, sent
+end
+
+function meta.copyz(self, fd, size)
+ local sent, lsent, code, msg = 0
+ if self:is_file() then
+ if nixio.sendfile and fd:is_socket() and self:stat("type") == "reg" then
+ repeat
+ lsent, code, msg = nixio.sendfile(fd, self, size or ZIOBLKSIZE)
+ if lsent then
+ sent = sent + lsent
+ size = size and (size - lsent)
+ end
+ until (not lsent or lsent == 0 or (size and size == 0))
+ if lsent or (not lsent and sent == 0 and
+ code ~= nixio.const.ENOSYS and code ~= nixio.const.EINVAL) then
+ return lsent and sent, code, msg, sent
+ end
+ end
+ end
+
+ return self:copy(fd, size)
+end
+
+function tls_socket.close(self)
+ return self.socket:close()
+end
+
+for k, v in pairs(meta) do
+ file[k] = v
+ socket[k] = v
+ tls_socket[k] = v