+end
+
+--- Return a key, value iterator which returns the values sorted according to
+-- the provided callback function.
+-- @param t The table to iterate
+-- @param f A callback function to decide the order of elements
+-- @return Function value containing the corresponding iterator
+function spairs(t,f)
+ return _sortiter( t, f )
+end
+
+--- Return a key, value iterator for the given table.
+-- The table pairs are sorted by key.
+-- @param t The table to iterate
+-- @return Function value containing the corresponding iterator
+function kspairs(t)
+ return _sortiter( t )
+end
+
+--- Return a key, value iterator for the given table.
+-- The table pairs are sorted by value.
+-- @param t The table to iterate
+-- @return Function value containing the corresponding iterator
+function vspairs(t)
+ return _sortiter( t, function (a,b) return t[a] < t[b] end )
+end
+
+
+--
+-- System utility functions
+--
+
+--- Test whether the current system is operating in big endian mode.
+-- @return Boolean value indicating whether system is big endian
+function bigendian()
+ return string.byte(string.dump(function() end), 7) == 0
+end
+
+--- Execute given commandline and gather stdout.
+-- @param command String containing command to execute
+-- @return String containing the command's stdout
+function exec(command)
+ local pp = io.popen(command)
+ local data = pp:read("*a")
+ pp:close()
+
+ return data
+end
+
+--- Return a line-buffered iterator over the output of given command.
+-- @param command String containing the command to execute
+-- @return Iterator
+function execi(command)
+ local pp = io.popen(command)
+
+ return pp and function()
+ local line = pp:read()
+
+ if not line then
+ pp:close()
+ end
+
+ return line
+ end
+end
+
+-- Deprecated
+function execl(command)
+ local pp = io.popen(command)
+ local line = ""
+ local data = {}
+
+ while true do
+ line = pp:read()
+ if (line == nil) then break end
+ data[#data+1] = line
+ end
+ pp:close()
+
+ return data
+end
+
+--- Returns the absolute path to LuCI base directory.
+-- @return String containing the directory path
+function libpath()
+ return require "nixio.fs".dirname(ldebug.__file__)
+end
+
+
+--
+-- Coroutine safe xpcall and pcall versions modified for Luci
+-- original version:
+-- coxpcall 1.13 - Copyright 2005 - Kepler Project (www.keplerproject.org)
+--
+-- Copyright © 2005 Kepler Project.
+-- Permission is hereby granted, free of charge, to any person obtaining a
+-- copy of this software and associated documentation files (the "Software"),
+-- to deal in the Software without restriction, including without limitation
+-- the rights to use, copy, modify, merge, publish, distribute, sublicense,
+-- and/or sell copies of the Software, and to permit persons to whom the
+-- Software is furnished to do so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be
+-- included in all copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+-- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+-- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+local performResume, handleReturnValue
+local oldpcall, oldxpcall = pcall, xpcall
+coxpt = {}
+setmetatable(coxpt, {__mode = "kv"})
+
+-- Identity function for copcall
+local function copcall_id(trace, ...)
+ return ...
+end
+
+--- This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
+-- @param f Lua function to be called protected
+-- @param err Custom error handler
+-- @param ... Parameters passed to the function
+-- @return A boolean whether the function call succeeded and the return
+-- values of either the function or the error handler
+function coxpcall(f, err, ...)
+ local res, co = oldpcall(coroutine.create, f)
+ if not res then
+ local params = {...}
+ local newf = function() return f(unpack(params)) end
+ co = coroutine.create(newf)
+ end
+ local c = coroutine.running()
+ coxpt[co] = coxpt[c] or c or 0
+
+ return performResume(err, co, ...)
+end
+
+--- This is a coroutine-safe drop-in replacement for Lua's "pcall"-function
+-- @param f Lua function to be called protected
+-- @param ... Parameters passed to the function
+-- @return A boolean whether the function call succeeded and the returns
+-- values of the function or the error object
+function copcall(f, ...)
+ return coxpcall(f, copcall_id, ...)
+end
+
+-- Handle return value of protected call
+function handleReturnValue(err, co, status, arg1, arg2, arg3, arg4, arg5)
+ if not status then
+ return false, err(debug.traceback(co, arg1), arg1, arg2, arg3, arg4, arg5)
+ end
+
+ if coroutine.status(co) ~= 'suspended' then
+ return true, arg1, arg2, arg3, arg4, arg5
+ end
+
+ return performResume(err, co, coroutine.yield(arg1, arg2, arg3, arg4, arg5))
+end
+
+-- Resume execution of protected function call
+function performResume(err, co, arg1, arg2, arg3, arg4, arg5)
+ return handleReturnValue(err, co, coroutine.resume(co, arg1, arg2, arg3, arg4, arg5))
+end