cosmopolitan/test/tool/net/lunix_test.lua

174 lines
5.2 KiB
Lua
Raw Permalink Normal View History

-- Copyright 2022 Justine Alexandra Roberts Tunney
--
-- Permission to use, copy, modify, and/or distribute this software for
-- any purpose with or without fee is hereby granted, provided that the
-- above copyright notice and this permission notice appear in all copies.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
-- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
-- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
-- AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-- PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-- TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
gotsigusr1 = false
tmpdir = "%s/o/tmp/lunix_test.%d" % {os.getenv('TMPDIR'), unix.getpid()}
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
function OnSigUsr1(sig)
gotsigusr1 = true
end
function UnixTest()
-- strsignal
assert(unix.strsignal(9) == "SIGKILL")
assert(unix.strsignal(unix.SIGKILL) == "SIGKILL")
-- gmtime
year,mon,mday,hour,min,sec,gmtoffsec,wday,yday,dst,zone = assert(unix.gmtime(1657297063))
assert(year == 2022)
assert(mon == 7)
assert(mday == 8)
assert(hour == 16)
assert(min == 17)
assert(sec == 43)
assert(gmtoffsec == 0)
assert(wday == 5)
assert(yday == 188)
assert(dst == 0)
assert(zone == "GMT")
-- dup
-- 1. duplicate stderr as lowest available fd
-- 1. close the newly assigned file descriptor
fd = assert(unix.dup(2))
assert(unix.close(fd))
-- dup2
-- 1. duplicate stderr as fd 10
-- 1. close the new file descriptor
assert(assert(unix.dup(2, 10)) == 10)
assert(unix.close(10))
-- fork
-- basic subprocess creation
if assert(unix.fork()) == 0 then
assert(unix.pledge(""))
unix.exit(42)
end
pid, ws = assert(unix.wait())
assert(unix.WIFEXITED(ws))
assert(unix.WEXITSTATUS(ws) == 42)
-- pledge
-- 1. fork off a process
-- 2. sandbox the process
-- 3. then violate its security
if GetHostOs() == "LINUX" then
reader, writer = assert(unix.pipe())
if assert(unix.fork()) == 0 then
assert(unix.dup(writer, 2))
assert(unix.pledge("stdio"))
unix.socket()
unix.exit(0)
end
unix.close(writer)
unix.close(reader)
pid, ws = assert(unix.wait())
assert(unix.WIFSIGNALED(ws))
assert(unix.WTERMSIG(ws) == unix.SIGSYS)
elseif GetHostOs() == "OPENBSD" then
if assert(unix.fork()) == 0 then
assert(unix.pledge("stdio"))
unix.socket()
unix.exit(1)
end
pid, ws = assert(unix.wait())
assert(unix.WIFSIGNALED(ws))
assert(unix.WTERMSIG(ws) == unix.SIGABRT)
end
-- sigaction
-- 1. install a signal handler for USR1
-- 2. block USR1
-- 3. trigger USR1 signal [it gets enqueued]
-- 4. pause() w/ atomic unblocking of USR1 [now it gets delivered!]
-- 5. restore old signal mask
-- 6. restore old sig handler
oldhand, oldflags, oldmask = assert(unix.sigaction(unix.SIGUSR1, OnSigUsr1))
oldmask = assert(unix.sigprocmask(unix.SIG_BLOCK, unix.Sigset(unix.SIGUSR1)))
assert(unix.raise(unix.SIGUSR1))
assert(not gotsigusr1)
ok, err = unix.sigsuspend(oldmask)
assert(not ok)
assert(err:errno() == unix.EINTR)
assert(gotsigusr1)
assert(unix.sigprocmask(unix.SIG_SETMASK, oldmask))
assert(unix.sigaction(unix.SIGUSR1, oldhand, oldflags, oldmask))
-- open
-- 1. create file
-- 2. fill it up
-- 3. inspect it
-- 4. mess with it
fd = assert(unix.open("%s/foo" % {tmpdir}, unix.O_RDWR | unix.O_CREAT | unix.O_TRUNC, 0600))
assert(assert(unix.fstat(fd)):size() == 0)
assert(unix.ftruncate(fd, 8192))
assert(assert(unix.fstat(fd)):size() == 8192)
assert(unix.write(fd, "hello"))
assert(unix.lseek(fd, 4096))
assert(unix.write(fd, "poke"))
assert(unix.lseek(fd, 8192-4))
assert(unix.write(fd, "poke"))
st = assert(unix.fstat(fd))
assert(st:size() == 8192)
assert(st:blocks() == 8192/512)
assert((st:mode() & 0777) == 0600)
assert(st:uid() == unix.getuid())
assert(st:gid() == unix.getgid())
assert(unix.write(fd, "bear", 4))
assert(unix.read(fd, 10, 0) == "hellbear\x00\x00")
assert(unix.close(fd))
fd = assert(unix.open("%s/foo" % {tmpdir}))
assert(unix.lseek(fd, 4))
assert(unix.read(fd, 4) == "bear")
assert(unix.close(fd))
fd = assert(unix.open("%s/foo" % {tmpdir}, unix.O_RDWR))
assert(unix.write(fd, "bear"))
assert(unix.close(fd))
fd = assert(unix.open("%s/foo" % {tmpdir}))
assert(unix.read(fd, 8) == "bearbear")
assert(unix.close(fd))
-- getdents
t = {}
for name, kind, ino, off in assert(unix.opendir(tmpdir)) do
table.insert(t, name)
end
2022-07-09 19:00:57 +00:00
table.sort(t)
assert(EncodeLua(t) == '{".", "..", "foo"}');
end
function main()
assert(unix.makedirs(tmpdir))
2022-07-23 12:22:19 +00:00
unix.unveil(tmpdir, "rwc")
unix.unveil(nil, nil)
assert(unix.pledge("stdio rpath wpath cpath proc"))
ok, err = pcall(UnixTest)
if ok then
assert(unix.rmrf(tmpdir))
else
print(err)
error('UnixTest failed (%s)' % {tmpdir})
end
end
main()