Fix some bugs

- addr2line backtrace should continue on eintr
- lua crashes if we try to iterate a non-table
This commit is contained in:
Justine Tunney 2022-04-27 20:18:34 -07:00
parent 92ebef16ee
commit e3a7ab1804
2 changed files with 27 additions and 48 deletions

View file

@ -67,7 +67,8 @@ asm(".include \"libc/disclaimer.inc\"");
* gcc generates is acceptable, since the special cases have already been * gcc generates is acceptable, since the special cases have already been
* handled. * handled.
*/ */
#pragma STDC CX_LIMITED_RANGE ON // TODO(elimisteve): write test proving why we do / don't need it
// #pragma STDC CX_LIMITED_RANGE ON
/* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */ /* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */
#define THRESH 0x1.a827999fcef32p+1022 #define THRESH 0x1.a827999fcef32p+1022

View file

@ -93,11 +93,6 @@
* @support Linux, Mac, Windows, FreeBSD, NetBSD, OpenBSD * @support Linux, Mac, Windows, FreeBSD, NetBSD, OpenBSD
*/ */
struct UnixDir {
int refs;
DIR *dir;
};
struct UnixErrno { struct UnixErrno {
int errno; int errno;
int winerr; int winerr;
@ -1721,7 +1716,7 @@ static int LuaUnixMinor(lua_State *L) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// unix.Stat object // unix.Stat object
static dontinline struct stat *GetUnixStat(lua_State *L) { static struct stat *GetUnixStat(lua_State *L) {
return luaL_checkudata(L, 1, "unix.Stat"); return luaL_checkudata(L, 1, "unix.Stat");
} }
@ -2051,38 +2046,29 @@ static void LuaUnixSigsetObj(lua_State *L) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// unix.Dir object // unix.Dir object
static struct UnixDir **GetUnixDirSelf(lua_State *L) { static DIR **GetUnixDirSelf(lua_State *L) {
return luaL_checkudata(L, 1, "unix.Dir"); return luaL_checkudata(L, 1, "unix.Dir");
} }
static DIR *GetDirOrDie(lua_State *L) { static DIR *GetDirOrDie(lua_State *L) {
struct UnixDir **udir; DIR **dirp;
udir = GetUnixDirSelf(L); dirp = GetUnixDirSelf(L);
assert((*udir)->dir); if (*dirp) return *dirp;
if (*udir) return (*udir)->dir;
luaL_argerror(L, 1, "unix.UnixDir is closed"); luaL_argerror(L, 1, "unix.UnixDir is closed");
unreachable; unreachable;
} }
static int FreeUnixDir(struct UnixDir *dir) {
int rc;
if (--dir->refs) return 0;
rc = closedir(dir->dir);
free(dir);
return rc;
}
// unix.Dir:close() // unix.Dir:close()
// ├─→ true // ├─→ true
// └─→ nil, unix.Errno // └─→ nil, unix.Errno
static int LuaUnixDirClose(lua_State *L) { static int LuaUnixDirClose(lua_State *L) {
DIR **dirp;
int rc, olderr; int rc, olderr;
struct UnixDir **udir; dirp = GetUnixDirSelf(L);
udir = GetUnixDirSelf(L); if (*dirp) {
if (*udir) {
olderr = 0; olderr = 0;
rc = FreeUnixDir(*udir); rc = closedir(*dirp);
*udir = 0; *dirp = 0;
return SysretBool(L, "closedir", olderr, rc); return SysretBool(L, "closedir", olderr, rc);
} else { } else {
lua_pushboolean(L, true); lua_pushboolean(L, true);
@ -2138,12 +2124,11 @@ static int LuaUnixDirRewind(lua_State *L) {
return 0; return 0;
} }
static int ReturnDir(lua_State *L, struct UnixDir *udir) { static int ReturnDir(lua_State *L, DIR *dir) {
struct UnixDir **udirp; DIR **dirp;
udir->refs = 1; dirp = lua_newuserdatauv(L, sizeof(*dirp), 1);
udirp = lua_newuserdatauv(L, sizeof(*udirp), 1);
luaL_setmetatable(L, "unix.Dir"); luaL_setmetatable(L, "unix.Dir");
*udirp = udir; *dirp = dir;
return 1; return 1;
} }
@ -2151,33 +2136,26 @@ static int ReturnDir(lua_State *L, struct UnixDir *udir) {
// ├─→ state:unix.Dir // ├─→ state:unix.Dir
// └─→ nil, unix.Errno // └─→ nil, unix.Errno
static int LuaUnixOpendir(lua_State *L) { static int LuaUnixOpendir(lua_State *L) {
DIR *dir;
int olderr = errno; int olderr = errno;
const char *path; if ((dir = opendir(luaL_checkstring(L, 1)))) {
struct UnixDir *udir; return ReturnDir(L, dir);
path = luaL_checkstring(L, 1); } else {
if ((udir = LuaUnixAlloc(L, sizeof(*udir)))) { return SysretErrno(L, "opendir", olderr);
if ((udir->dir = opendir(path))) {
return ReturnDir(L, udir);
}
free(udir);
} }
return SysretErrno(L, "opendir", olderr);
} }
// unix.fdopendir(fd:int) // unix.fdopendir(fd:int)
// ├─→ next:function, state:unix.Dir // ├─→ next:function, state:unix.Dir
// └─→ nil, unix.Errno // └─→ nil, unix.Errno
static int LuaUnixFdopendir(lua_State *L) { static int LuaUnixFdopendir(lua_State *L) {
int fd, olderr = errno; DIR *dir;
struct UnixDir *udir; int olderr = errno;
fd = luaL_checkinteger(L, 1); if ((dir = fdopendir(luaL_checkinteger(L, 1)))) {
if ((udir = LuaUnixAlloc(L, sizeof(*udir)))) { return ReturnDir(L, dir);
if ((udir->dir = fdopendir(fd))) { } else {
return ReturnDir(L, udir); return SysretErrno(L, "fdopendir", olderr);
}
free(udir);
} }
return SysretErrno(L, "fdopendir", olderr);
} }
static const luaL_Reg kLuaUnixDirMeth[] = { static const luaL_Reg kLuaUnixDirMeth[] = {