Make improvements

- Add GetCpuCount() API to redbean
- Add unix.gmtime() API to redbean
- Add unix.readlink() API to redbean
- Add unix.localtime() API to redbean
- Perfect the new redbean UNIX module APIs
- Integrate with Linux clock_gettime() vDSO
- Run Lua garbage collector when malloc() fails
- Fix another regression quirk with linenoise repl
- Fix GetProgramExecutableName() for systemwide installs
- Fix a build flake with test/libc/mem/test.mk SRCS list
This commit is contained in:
Justine Tunney 2022-04-25 21:16:05 -07:00
parent 860ea18a87
commit d57b81aac7
51 changed files with 3096 additions and 1395 deletions

2
tool/net/demo/script.lua Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/redbean -i
print('hello world')

View file

@ -0,0 +1,93 @@
Write('<!doctype html>\r\n')
Write('<title>redbean</title>\r\n')
Write('<style>\r\n')
Write('td,th { padding: 2px 5px; }\r\n')
Write('td { white-space: nowrap; }\r\n')
Write('.l { text-align: left; }\r\n')
Write('.r { text-align: right; }\r\n')
Write('</style>\r\n')
Write('<h3>UNIX Directory Stream Demo</h3>\r\n')
Write('<table>\r\n')
Write('<thead>\r\n')
Write('<tr>\r\n')
Write('<th class=l>name\r\n')
Write('<th>type\r\n')
Write('<th class=r>ino\r\n')
Write('<th class=r>off\r\n')
Write('<th class=r>size\r\n')
Write('<th class=r>blocks\r\n')
Write('<th class=r>mode\r\n')
Write('<th class=r>uid\r\n')
Write('<th class=r>gid\r\n')
Write('<th class=r>dev\r\n')
Write('<th class=r>rdev\r\n')
Write('<th class=r>nlink\r\n')
Write('<th class=r>blksize\r\n')
Write('<th class=r>gen\r\n')
Write('<th class=r>flags\r\n')
Write('<th class=r>birthtim\r\n')
Write('<th class=r>mtim\r\n')
Write('<th class=r>atim\r\n')
Write('<th class=r>ctim\r\n')
Write('<tbody>\r\n')
dir = '.'
for name, kind, ino, off in assert(unix.opendir(dir)) do
Write('<tr>\r\n')
Write('<td>')
Write(EscapeHtml(name))
if kind == unix.DT_DIR then
Write('/')
end
Write('\r\n')
Write('<td>')
if kind == unix.DT_REG then Write('DT_REG')
elseif kind == unix.DT_DIR then Write('DT_DIR')
elseif kind == unix.DT_FIFO then Write('DT_FIFO')
elseif kind == unix.DT_CHR then Write('DT_CHR')
elseif kind == unix.DT_BLK then Write('DT_BLK')
elseif kind == unix.DT_LNK then Write('DT_LNK')
elseif kind == unix.DT_SOCK then Write('DT_SOCK')
else Write('DT_UNKNOWN')
end
Write('\r\n')
Write('<td class=r>%d\r\n' % {ino})
Write('<td class=r>%d\r\n' % {off})
st,err = unix.stat(dir..'/'..name, unix.AT_SYMLINK_NOFOLLOW)
if st then
Write('<td class=r>%d\r\n' % {st:size()})
Write('<td class=r>%d\r\n' % {st:blocks()})
Write('<td class=r>%.7o\r\n' % {st:mode()})
Write('<td class=r>%d\r\n' % {st:uid()})
Write('<td class=r>%d\r\n' % {st:gid()})
Write('<td class=r>%d\r\n' % {st:dev()})
Write('<td class=r>%d,%d\r\n' % {unix.major(st:rdev()), unix.minor(st:rdev())})
Write('<td class=r>%d\r\n' % {st:nlink()})
Write('<td class=r>%d\r\n' % {st:blksize()})
Write('<td class=r>%d\r\n' % {st:gen()})
Write('<td class=r>%#x\r\n' % {st:flags()})
function WriteTime(unixsec,nanos)
year,mon,mday,hour,min,sec,gmtoffsec = unix.localtime(unixsec)
Write('<td class=r>%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.9d%+.2d%.2d\r\n' % {
year, mon, mday, hour, min, sec, nanos,
gmtoffsec / (60 * 60), math.abs(gmtoffsec) % 60})
end
WriteTime(st:birthtim())
WriteTime(st:mtim())
WriteTime(st:atim())
WriteTime(st:ctim())
else
Write('<td class=l colspan=15>%s\r\n' % {err})
end
end
Write('</table>\r\n')

View file

@ -26,7 +26,7 @@ sid, errno = unix.getsid(0)
if sid then
Write('<dd>%d\r\n' % {sid})
else
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {tostring(errno)})
end
Write('<dt>unix.gethostname()\r\n')
@ -54,7 +54,7 @@ function PrintResourceLimit(name, id)
end
Write('\r\n')
else
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
end
end
PrintResourceLimit('RLIMIT_AS', unix.RLIMIT_AS)
@ -77,13 +77,13 @@ if ifs then
Write('%s %s/%d<br>\r\n' % {EscapeHtml(ifs[i].name), FormatIp(ifs[i].ip), cidr})
end
else
Write('%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('%s\r\n' % {EscapeHtml(tostring(errno))})
end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DEBUG)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DEBUG)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -91,7 +91,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_ACCEPTCONN)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_ACCEPTCONN)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -99,7 +99,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEADDR)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEADDR)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -107,7 +107,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEPORT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEPORT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -115,7 +115,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_KEEPALIVE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_KEEPALIVE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -123,7 +123,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NODELAY)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NODELAY)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -131,7 +131,7 @@ end
secs, errno, micros = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVTIMEO)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVTIMEO)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d sec %d µs\r\n' % {secs, micros})
end
@ -139,7 +139,7 @@ end
secs, errno, micros = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDTIMEO)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDTIMEO)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d sec %d µs\r\n' % {secs, micros})
end
@ -147,7 +147,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DONTROUTE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DONTROUTE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -155,7 +155,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDBUF)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDBUF)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -163,7 +163,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVBUF)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVBUF)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -171,7 +171,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -179,7 +179,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_BROADCAST)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_BROADCAST)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -187,7 +187,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_CORK)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_CORK)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -195,7 +195,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_QUICKACK)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_QUICKACK)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -203,7 +203,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_DEFER_ACCEPT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_DEFER_ACCEPT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -211,7 +211,7 @@ end
enabled, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN_CONNECT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN_CONNECT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
@ -219,7 +219,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDLOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDLOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -227,7 +227,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVLOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVLOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -235,7 +235,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPCNT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPCNT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -243,7 +243,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_MAXSEG)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_MAXSEG)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -251,7 +251,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SYNCNT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SYNCNT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -259,7 +259,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NOTSENT_LOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NOTSENT_LOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -267,7 +267,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_WINDOW_CLAMP)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_WINDOW_CLAMP)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -275,7 +275,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPIDLE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPIDLE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
@ -283,7 +283,7 @@ end
bytes, errno = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPINTVL)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPINTVL)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
Write('<dd>%s\r\n' % {EscapeHtml(tostring(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end

11
tool/net/demo/unix-raise.lua Executable file
View file

@ -0,0 +1,11 @@
#!/home/jart/bin/redbean -i
assert(unix.sigaction(unix.SIGUSR1, function(sig)
gotsigusr1 = true
end))
gotsigusr1 = false
assert(unix.raise(unix.SIGUSR1))
if gotsigusr1 then
print('hooray the signal was delivered')
else
print('oh no some other signal was handled')
end

View file

@ -1,4 +1,4 @@
local unix = require "unix"
local unix = require 'unix'
local function main()
if GetMethod() ~= 'GET' and GetMethod() ~= 'HEAD' then
@ -45,7 +45,7 @@ local function main()
Write(EncodeBase64(LoadAsset('/redbean.png')))
Write('">\r\n')
Write('redbean unix demo\r\n')
Write('<span style="color:red">&nbsp;%s</span>\r\n' % {unix.strerrno(errno)})
Write('<span style="color:red">&nbsp;%s</span>\r\n' % {EscapeHtml(tostring(errno))})
Write('</h1>\r\n')
Write([[
<p>
@ -63,7 +63,6 @@ local function main()
unix.close(fd)
return
end
-- if pid is zero then we're the child
-- turn into a daemon
unix.umask(0)
@ -106,34 +105,6 @@ local function main()
unix.write(fd, 'became an autonomous daemon reparented on your init!\r\n')
unix.write(fd, '</p>\r\n')
unix.write(fd, '<h2>listing of current directory</h2>\r\n')
dir, err = unix.opendir('.')
if dir then
unix.write(fd, '<ul>\r\n')
while true do
name, errno, kind, ino, off = dir:read()
if not name then
break
end
unix.write(fd, '<li>')
unix.write(fd, EscapeHtml(VisualizeControlCodes(name)))
if kind == unix.DT_DIR then
unix.write(fd, '/')
else
st, err = unix.stat(name)
if st then
unix.write(fd, ' (%d bytes)' % {st:size()})
end
end
unix.write(fd, '\r\n')
end
unix.write(fd, '</ul>\r\n')
else
unix.write(fd, '<p>\r\n')
unix.write(fd, 'failed: %s\r\n' % {EscapeHtml(VisualizeControlCodes(unix:strerror(err)))})
unix.write(fd, '</p>\r\n')
end
-- terminate
unix.close(fd)
unix.exit(0)

View file

@ -9,55 +9,48 @@ function main()
end
syscall = 'commandv'
ls = assert(unix.commandv(cmd))
if ls then
syscall = 'pipe'
reader, writer, errno = unix.pipe()
if reader then
-- oldint = assert(unix.sigaction(unix.SIGINT, unix.SIG_IGN))
-- oldquit = assert(unix.sigaction(unix.SIGQUIT, unix.SIG_IGN))
-- oldmask = assert(unix.sigprocmask(unix.SIG_BLOCK, (1 << (unix.SIGCHLD - 1))))
syscall = 'fork'
child, errno = unix.fork()
if child then
if child == 0 then
unix.close(1)
unix.dup(writer)
unix.close(writer)
unix.close(reader)
-- unix.sigaction(unix.SIGINT, oldint)
-- unix.sigaction(unix.SIGQUIT, oldquit)
-- unix.sigprocmask(unix.SIG_SETMASK, oldmask)
unix.execve(ls, {ls, '-Shal'})
unix.exit(127)
syscall = 'pipe'
reader, writer = assert(unix.pipe(unix.O_CLOEXEC))
oldint = assert(unix.sigaction(unix.SIGINT, unix.SIG_IGN))
oldquit = assert(unix.sigaction(unix.SIGQUIT, unix.SIG_IGN))
oldmask = assert(unix.sigprocmask(unix.SIG_BLOCK, unix.Sigset(unix.SIGCHLD)))
syscall = 'fork'
child = assert(unix.fork())
if child == 0 then
unix.close(0)
unix.open("/dev/null", unix.O_RDONLY)
unix.close(1)
unix.dup(writer)
unix.close(2)
unix.open("/dev/null", unix.O_RDONLY)
unix.sigaction(unix.SIGINT, oldint)
unix.sigaction(unix.SIGQUIT, oldquit)
unix.sigprocmask(unix.SIG_SETMASK, oldmask)
unix.execve(ls, {ls, '-Shal'})
unix.exit(127)
else
unix.close(writer)
SetStatus(200)
SetHeader('Content-Type', 'text/plain')
while true do
data, err = unix.read(reader)
if data then
if data ~= '' then
Write(data)
else
unix.close(writer)
SetStatus(200)
SetHeader('Content-Type', 'text/plain')
while true do
data, errno = unix.read(reader)
if data then
if data ~= '' then
Write(data)
else
break
end
elseif errno ~= unix.EINTR then
Log(kLogWarn, 'read() failed: %s' % {unix.strerror(errno)})
break
end
end
unix.close(reader)
unix.wait(-1)
-- unix.sigaction(unix.SIGINT, oldint)
-- unix.sigaction(unix.SIGQUIT, oldquit)
-- unix.sigprocmask(unix.SIG_SETMASK, oldmask)
return
break
end
elseif err:errno() ~= unix.EINTR then
Log(kLogWarn, 'read() failed: %s' % {tostring(err)})
break
end
end
unix.close(reader)
unix.wait(-1)
unix.sigaction(unix.SIGINT, oldint)
unix.sigaction(unix.SIGQUIT, oldquit)
unix.sigprocmask(unix.SIG_SETMASK, oldmask)
return
end
SetStatus(200)
SetHeader('Content-Type', 'text/plain')
Write('error %s calling %s()' % {unix.strerrno(errno), syscall})
end
main()

View file

@ -45,7 +45,7 @@ function main()
server = unix.socket()
unix.bind(server, ifs[i].ip)
unix.listen(server)
ip, errno, port = unix.getsockname(server)
ip, port = assert(unix.getsockname(server))
addr = '%s:%d' % {FormatIp(ip), port}
url = 'http://%s' % {addr}
Log(kLogInfo, 'listening on %s' % {addr})
@ -65,7 +65,7 @@ function main()
if fd == mainfd then
data, errno = unix.read(mainfd)
if not data then
Log(kLogInfo, 'got %s from parent client' % {unix.strerrno(errno)})
Log(kLogInfo, 'got %s from parent client' % {tostring(errno)})
-- prevent redbean core from writing a response
unix.exit(1)
end
@ -79,8 +79,7 @@ function main()
unix.write(mainfd, data)
elseif servers[fd] then
unix.write(mainfd, 'preparing to accept from %d<br>\r\n' % {fd})
client, errno, clientip, clientport = unix.accept(fd)
unix.write(mainfd, 'preparing to accept from %d<br>\r\n' % {fd})
client, clientip, clientport = assert(unix.accept(fd))
addr = '%s:%d' % {FormatIp(clientip), clientport}
addrs[client] = addr
unix.write(mainfd, 'got client %s<br>\r\n' % {addr})