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})

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,7 @@
#include "libc/nexgen32e/rdtscp.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/sysconf.h"
#include "libc/sock/sock.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/rusage.h"
@ -82,6 +83,11 @@ int LuaGetCpuCore(lua_State *L) {
return 1;
}
int LuaGetCpuCount(lua_State *L) {
lua_pushinteger(L, GetCpuCount());
return 1;
}
int LuaGetLogLevel(lua_State *L) {
lua_pushinteger(L, __log_level);
return 1;

View file

@ -35,6 +35,7 @@ int LuaEscapeUser(lua_State *);
int LuaFormatHttpDateTime(lua_State *);
int LuaFormatIp(lua_State *);
int LuaGetCpuCore(lua_State *);
int LuaGetCpuCount(lua_State *);
int LuaGetCpuNode(lua_State *);
int LuaGetCryptoHash(lua_State *);
int LuaGetHostOs(lua_State *);

File diff suppressed because it is too large Load diff

View file

@ -175,6 +175,7 @@ o/$(MODE)/tool/net/demo/sql.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-rawsocket.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-subprocess.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-webserver.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-dir.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-info.lua.zip.o \
o/$(MODE)/tool/net/demo/fetch.lua.zip.o \
o/$(MODE)/tool/net/demo/hello.lua.zip.o \
@ -221,6 +222,7 @@ o/$(MODE)/tool/net/redbean-demo.com.dbg: \
o/$(MODE)/tool/net/demo/unix-rawsocket.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-subprocess.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-webserver.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-dir.lua.zip.o \
o/$(MODE)/tool/net/demo/unix-info.lua.zip.o \
o/$(MODE)/tool/net/demo/fetch.lua.zip.o \
o/$(MODE)/tool/net/demo/hello.lua.zip.o \

View file

@ -63,6 +63,7 @@
#include "libc/runtime/directmap.internal.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/runtime/symbols.internal.h"
@ -196,6 +197,8 @@ STATIC_YOINK("zip_uri_support");
// puncts not used: !"#$%&'()*+,-./;<=>@[\]^_`{|}~
#define GETOPTS "BSVZabdfghijkmsuvzA:C:D:F:G:H:K:L:M:P:R:T:U:c:e:l:p:r:t:"
extern unsigned long long __kbirth;
static const uint8_t kGzipHeader[] = {
0x1F, // MAGNUM
0x8B, // MAGNUM
@ -4956,6 +4959,7 @@ static const luaL_Reg kLuaFuncs[] = {
{"GetComment", LuaGetAssetComment}, //
{"GetCookie", LuaGetCookie}, //
{"GetCpuCore", LuaGetCpuCore}, //
{"GetCpuCount", LuaGetCpuCount}, //
{"GetCpuNode", LuaGetCpuNode}, //
{"GetCryptoHash", LuaGetCryptoHash}, //
{"GetDate", LuaGetDate}, //
@ -5192,6 +5196,7 @@ static void LuaPrint(lua_State *L) {
static void LuaInterpreter(lua_State *L) {
int i, n, sig, status;
const char *script;
if (funtrace) ftrace_install();
if (optind < __argc) {
script = __argv[optind];
if (!strcmp(script, "-")) script = 0;
@ -5201,7 +5206,11 @@ static void LuaInterpreter(lua_State *L) {
luaL_checkstack(L, n + 3, "too many script args");
for (i = 1; i <= n; i++) lua_rawgeti(L, -i, i);
lua_remove(L, -i); // remove arg table from stack
if (funtrace) ++g_ftrace;
if (systrace) ++__strace;
status = lua_runchunk(L, n, LUA_MULTRET);
if (systrace) --__strace;
if (funtrace) --g_ftrace;
}
lua_report(L, status);
} else {
@ -5225,7 +5234,9 @@ static void LuaInterpreter(lua_State *L) {
exit(1);
}
if (status == LUA_OK) {
if (funtrace) ++g_ftrace;
status = lua_runchunk(GL, 0, LUA_MULTRET);
if (funtrace) --g_ftrace;
}
if (status == LUA_OK) {
LuaPrint(GL);
@ -6358,7 +6369,6 @@ static int HandleConnection(size_t i) {
connectionclose = false;
if (!IsTiny()) {
if (systrace) {
extern unsigned long long __kbirth;
__strace = 1;
__kbirth = rdtsc();
}
@ -6474,18 +6484,20 @@ static void RestoreApe(void) {
if (endswith(zpath, ".com.dbg")) return;
if ((a = GetAssetZip("/.ape", 5)) && (p = LoadAsset(a, &n))) {
close(zfd);
if ((zfd = OpenExecutable()) == -1 || WRITE(zfd, p, n) == -1)
if ((zfd = OpenExecutable()) == -1 || WRITE(zfd, p, n) == -1) {
WARNF("(srvr) can't restore .ape");
}
free(p);
} else {
INFOF("(srvr) /.ape not found");
DEBUGF("(srvr) /.ape not found");
}
}
static int HandleReadline(void) {
int status;
lua_State *L = GL;
for (;;) {
status = lua_loadline(GL);
status = lua_loadline(L);
if (status < 0) {
if (status == -1) {
OnTerm(SIGHUP); // eof
@ -6508,12 +6520,12 @@ static int HandleReadline(void) {
linenoiseDisableRawMode();
LUA_REPL_LOCK;
if (status == LUA_OK) {
status = lua_runchunk(GL, 0, LUA_MULTRET);
status = lua_runchunk(L, 0, LUA_MULTRET);
}
if (status == LUA_OK) {
LuaPrint(GL);
LuaPrint(L);
} else {
lua_report(GL, status);
lua_report(L, status);
}
LUA_REPL_UNLOCK;
if (lua_repl_isterminal) {
@ -6683,26 +6695,28 @@ static int EventLoop(int ms) {
}
static void ReplEventLoop(void) {
lua_State *L = GL;
DEBUGF("ReplEventLoop()");
polls[0].fd = 0;
lua_repl_completions_callback = HandleCompletions;
lua_initrepl(GL, "redbean");
lua_initrepl(L, "redbean");
if (lua_repl_isterminal) {
linenoiseEnableRawMode(0);
}
EventLoop(100);
linenoiseDisableRawMode();
lua_freerepl();
lua_settop(GL, 0); // clear stack
lua_settop(L, 0); // clear stack
polls[0].fd = -1;
}
static uint32_t WindowsReplThread(void *arg) {
int sig;
lua_State *L = GL;
DEBUGF("WindowsReplThread()");
lua_repl_blocking = true;
lua_repl_completions_callback = HandleCompletions;
lua_initrepl(GL, "redbean");
lua_initrepl(L, "redbean");
if (lua_repl_isterminal) {
linenoiseEnableRawMode(0);
}
@ -6714,7 +6728,7 @@ static uint32_t WindowsReplThread(void *arg) {
linenoiseDisableRawMode();
lua_freerepl();
LUA_REPL_LOCK;
lua_settop(GL, 0); // clear stack
lua_settop(L, 0); // clear stack
LUA_REPL_UNLOCK;
if ((sig = linenoiseGetInterrupt())) {
raise(sig);
@ -6896,7 +6910,7 @@ void RedBean(int argc, char *argv[]) {
(shared = mmap(NULL, ROUNDUP(sizeof(struct Shared), FRAMESIZE),
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-1, 0)));
zpath = program_executable_name;
zpath = GetProgramExecutableName();
CHECK_NE(-1, (zfd = open(zpath, O_RDONLY)));
CHECK_NE(-1, fstat(zfd, &zst));
OpenZip(true);