mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-01 08:48:29 +00:00
Make improvements
- Emulator can now test the αcτµαlly pδrταblε εxεcµταblε bootloader - Whipped up a webserver named redbean. It services 150k requests per second on a single core. Bundling assets inside zip enables extremely fast serving for two reasons. The first is that zip central directory lookups go faster than stat() system calls. The second is that both zip and gzip content-encoding use DEFLATE, therefore, compressed responses can be served via the sendfile() system call which does an in-kernel copy directly from the zip executable structure. Also note that red bean zip executables can be deployed easily to all platforms, since these native executables work on Linux, Mac, BSD, and Windows. - Address sanitizer now works very well
This commit is contained in:
parent
7327c345f9
commit
416fd86676
230 changed files with 9835 additions and 5682 deletions
|
@ -23,6 +23,8 @@
|
|||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/win32finddata.h"
|
||||
|
@ -31,9 +33,18 @@
|
|||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
struct dirent$freebsd {
|
||||
uint32_t d_fileno;
|
||||
uint16_t d_reclen;
|
||||
uint8_t d_type;
|
||||
uint8_t d_namlen;
|
||||
char d_name[256];
|
||||
};
|
||||
|
||||
struct dirstream {
|
||||
int64_t tell;
|
||||
int64_t fd;
|
||||
struct dirent ent;
|
||||
union {
|
||||
struct {
|
||||
unsigned buf_pos;
|
||||
|
@ -41,8 +52,6 @@ struct dirstream {
|
|||
char buf[BUFSIZ];
|
||||
};
|
||||
struct {
|
||||
struct dirent winent;
|
||||
char __d_name[PATH_MAX];
|
||||
bool isdone;
|
||||
struct NtWin32FindData windata;
|
||||
};
|
||||
|
@ -71,17 +80,60 @@ static textwindows noinline DIR *opendir$nt(const char *name) {
|
|||
}
|
||||
}
|
||||
|
||||
static textwindows noinline struct dirent *readdir$nt(DIR *dir) {
|
||||
if (!dir->isdone) {
|
||||
memset(&dir->ent, 0, sizeof(dir->ent));
|
||||
dir->ent.d_ino = 0;
|
||||
dir->ent.d_off = dir->tell++;
|
||||
dir->ent.d_reclen = sizeof(dir->ent) +
|
||||
tprecode16to8(dir->ent.d_name, sizeof(dir->ent.d_name),
|
||||
dir->windata.cFileName) +
|
||||
1;
|
||||
switch (dir->windata.dwFileType) {
|
||||
case kNtFileTypeDisk:
|
||||
dir->ent.d_type = DT_BLK;
|
||||
break;
|
||||
case kNtFileTypeChar:
|
||||
dir->ent.d_type = DT_CHR;
|
||||
break;
|
||||
case kNtFileTypePipe:
|
||||
dir->ent.d_type = DT_FIFO;
|
||||
break;
|
||||
default:
|
||||
if (dir->windata.dwFileAttributes & kNtFileAttributeDirectory) {
|
||||
dir->ent.d_type = DT_DIR;
|
||||
} else {
|
||||
dir->ent.d_type = DT_REG;
|
||||
}
|
||||
break;
|
||||
}
|
||||
dir->isdone = !FindNextFile(dir->fd, &dir->windata);
|
||||
return &dir->ent;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens directory so readdir() and closedir() may be called.
|
||||
* Opens directory, e.g.
|
||||
*
|
||||
* DIR *d;
|
||||
* struct dirent *e;
|
||||
* CHECK((d = opendir(path)));
|
||||
* while ((e = readdir(d))) {
|
||||
* printf("%s/%s\n", path, e->d_name);
|
||||
* }
|
||||
* LOGIFNEG1(closedir(d));
|
||||
*
|
||||
* @returns newly allocated DIR object, or NULL w/ errno
|
||||
* @errors ENOENT, ENOTDIR, EACCES, EMFILE, ENFILE, ENOMEM
|
||||
* @see glob()
|
||||
*/
|
||||
DIR *opendir(const char *name) {
|
||||
int fd;
|
||||
DIR *res;
|
||||
if (!IsWindows() && !IsXnu()) {
|
||||
int fd;
|
||||
DIR *res = NULL;
|
||||
res = NULL;
|
||||
if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0)) != -1) {
|
||||
if (!(res = fdopendir(fd))) close(fd);
|
||||
}
|
||||
|
@ -103,8 +155,8 @@ DIR *opendir(const char *name) {
|
|||
* @errors ENOMEM and fd is closed
|
||||
*/
|
||||
DIR *fdopendir(int fd) {
|
||||
DIR *dir;
|
||||
if (!IsWindows() && !IsXnu()) {
|
||||
DIR *dir;
|
||||
if ((dir = calloc(1, sizeof(*dir)))) {
|
||||
dir->fd = fd;
|
||||
return dir;
|
||||
|
@ -125,35 +177,36 @@ DIR *fdopendir(int fd) {
|
|||
* differentiated by setting errno to 0 beforehand
|
||||
*/
|
||||
struct dirent *readdir(DIR *dir) {
|
||||
int rc;
|
||||
struct dirent *ent;
|
||||
struct dirent$freebsd *freebsd;
|
||||
if (!IsWindows()) {
|
||||
if (dir->buf_pos >= dir->buf_end) {
|
||||
int rc;
|
||||
if (!(rc = getdents(dir->fd, dir->buf, BUFSIZ)) || rc == -1) {
|
||||
if (!(rc = getdents(dir->fd, dir->buf,
|
||||
sizeof(dir->buf) - sizeof(dir->ent.d_name))) ||
|
||||
rc == -1) {
|
||||
return NULL;
|
||||
}
|
||||
dir->buf_pos = 0;
|
||||
dir->buf_end = rc;
|
||||
}
|
||||
/* TODO(jart): Check FreeBSD and OpenBSD again regarding this */
|
||||
char *record = dir->buf + dir->buf_pos;
|
||||
char *name = record + 8 + 8 + 2;
|
||||
size_t namelen = strlen(name);
|
||||
unsigned char dtype = name[namelen + 1];
|
||||
memmove(name + 1, name, namelen + 1); /* shove forward one byte */
|
||||
*name = dtype; /* is dirent d_type field */
|
||||
struct dirent *ent = (void *)record;
|
||||
dir->buf_pos += ent->d_reclen;
|
||||
dir->tell = ent->d_off;
|
||||
if (IsLinux()) {
|
||||
ent = (struct dirent *)(dir->buf + dir->buf_pos);
|
||||
dir->buf_pos += ent->d_reclen;
|
||||
dir->tell = ent->d_off;
|
||||
} else {
|
||||
freebsd = (struct dirent$freebsd *)(dir->buf + dir->buf_pos);
|
||||
dir->buf_pos += freebsd->d_reclen;
|
||||
ent = &dir->ent;
|
||||
ent->d_ino = freebsd->d_fileno;
|
||||
ent->d_off = dir->tell++;
|
||||
ent->d_reclen = freebsd->d_reclen;
|
||||
ent->d_type = freebsd->d_type;
|
||||
memcpy(ent->d_name, freebsd->d_name, freebsd->d_namlen + 1);
|
||||
}
|
||||
return ent;
|
||||
} else {
|
||||
if (dir->isdone) return NULL;
|
||||
struct dirent *ent = &dir->winent;
|
||||
memset(ent, 0, sizeof(*ent));
|
||||
ent->d_reclen =
|
||||
sizeof(*ent) +
|
||||
tprecode16to8(ent->d_name, PATH_MAX, dir->windata.cFileName) + 1;
|
||||
dir->isdone = FindNextFile(dir->fd, &dir->windata);
|
||||
return ent;
|
||||
return readdir$nt(dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,7 +230,7 @@ int closedir(DIR *dir) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns current byte offset into directory data.
|
||||
* Returns offset into directory data.
|
||||
*/
|
||||
long telldir(DIR *dir) {
|
||||
return dir->tell;
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#define COSMOPOLITAN_LIBC_CALLS_INTERNAL_H_
|
||||
#ifndef __STRICT_ANSI__
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/itimerval.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
|
@ -28,6 +31,8 @@
|
|||
#include "libc/nt/struct/startupinfo.h"
|
||||
#include "libc/nt/struct/systeminfo.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/time/struct/timezone.h"
|
||||
#include "libc/time/struct/utimbuf.h"
|
||||
|
||||
#define kSigactionMinRva 8 /* >SIG_{ERR,DFL,IGN,...} */
|
||||
|
||||
|
@ -41,14 +46,6 @@ struct NtWin32FileAttributeData;
|
|||
struct ZiposHandle;
|
||||
struct __darwin_siginfo;
|
||||
struct __darwin_ucontext;
|
||||
struct itimerval;
|
||||
struct rlimit;
|
||||
struct rusage;
|
||||
struct sigset;
|
||||
struct sysinfo;
|
||||
struct timeval;
|
||||
struct timezone;
|
||||
struct utimbuf;
|
||||
|
||||
struct IoctlPtmGet {
|
||||
int theduxfd;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
/**
|
||||
* Returns information about thing.
|
||||
*
|
||||
* @see S_ISDIR(st.st_mode), S_ISREG(), etc.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int stat(const char *pathname, struct stat *st) {
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_DIRENT_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
struct dirent {
|
||||
struct dirent { /* linux getdents64 abi */
|
||||
uint64_t d_ino; /* inode number */
|
||||
int64_t d_off; /* implementation-dependent location number */
|
||||
uint16_t d_reclen; /* byte length of this whole struct and string */
|
||||
uint8_t d_type; /* DT_UNKNOWN, DT_BLK, DT_DIR, etc. it's flaky */
|
||||
char d_name[1]; /* NUL-terminated basename */
|
||||
uint8_t d_type; /* DT_UNKNOWN, DT_BLK, DT_DIR, etc. */
|
||||
char d_name[256]; /* NUL-terminated basename */
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue