1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
-- Additions to the posix module (of luaposix).
local M = require "posix_c"
local posix = M
--- Create a file.
-- @param file name of file to create
-- @param mode permissions with which to create file
-- @return file descriptor, or -1 on error
function M.creat (file, mode)
return posix.open (file, {"creat", "wronly", "trunc"}, mode)
end
--- Run a program like <code>os.execute</code>, but without a shell.
-- @param file filename of program to run
-- @param ... arguments to the program
-- @return status exit code, or nil if fork or wait fails
-- @return error message, or exit type if wait succeeds
function M.system (file, ...)
local pid = posix.fork ()
if pid == 0 then
return posix.execp (file, ...)
else
local pid, reason, status = posix.wait (pid)
return status, reason -- If wait failed, status is nil & reason is error
end
end
--- Check permissions like <code>access</code>, but for euid.
-- Based on the glibc function of the same name. Does not always check
-- for read-only file system, text busy, etc., and does not work with
-- ACLs &c.
-- @param file file to check
-- @param mode checks to perform (as for access)
-- @return 0 if access allowed; <code>nil</code> otherwise (and errno is set)
function M.euidaccess (file, mode)
local pid = posix.getpid ()
if pid.uid == pid.euid and pid.gid == pid.egid then
-- If we are not set-uid or set-gid, access does the same.
return access (file, mode)
end
local stats = posix.stat (file)
if not stats then
return
end
-- The super-user can read and write any file, and execute any file
-- that anyone can execute.
if pid.euid == 0 and ((not string.match (mode, "x")) or
string.match (stats.st_mode, "x")) then
return 0
end
-- Convert to simple list of modes.
mode = string.gsub (mode, "[^rwx]", "")
if mode == "" then
return 0 -- The file exists.
end
-- Get the modes we need.
local granted = stats.st_mode:sub (1, 3)
if pid.euid == stats.st_uid then
granted = stats.st_mode:sub (7, 9)
elseif pid.egid == stats.st_gid or set.new (posix.getgroups ()):member(stats.st_gid) then
granted = stats.st_mode:sub (4, 6)
end
granted = string.gsub (granted, "[^rwx]", "")
if string.gsub ("[^" .. granted .. "]", mode) == "" then
return 0
end
posix.set_errno (EACCESS)
end
return M
|