Make more libc improvements

- Make memmem() faster
- Make readdir() thread safe
- Remove 64kb limit from mkdeps.com
- Add old crypt() function from Musl
- Improve new fix-third-party.py tool
- Improve libc/isystem/ headers and fix bugs
This commit is contained in:
Justine Tunney 2022-08-06 17:18:40 -07:00
parent a8cf0f7e89
commit 6a5717a48f
50 changed files with 3783 additions and 280 deletions

View file

@ -18,11 +18,14 @@
*/
#include "libc/assert.h"
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/dirent.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/nopl.h"
#include "libc/intrin/pthread.h"
#include "libc/mem/mem.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/filetype.h"
@ -53,6 +56,7 @@ struct dirstream {
bool iszip;
int64_t fd;
int64_t tell;
pthread_mutex_t lock;
struct {
uint64_t offset;
uint64_t records;
@ -109,6 +113,22 @@ struct dirent_netbsd {
char d_name[512];
};
void _lockdir(DIR *dir) {
pthread_mutex_lock(&dir->lock);
}
void _unlockdir(DIR *dir) {
pthread_mutex_unlock(&dir->lock);
}
#ifdef _NOPL1
#define _lockdir(d) _NOPL1("__threadcalls", _lockdir, d)
#define _unlockdir(d) _NOPL1("__threadcalls", _unlockdir, d)
#else
#define _lockdir(d) (__threaded ? _lockdir(d) : 0)
#define _unlockdir(d) (__threaded ? _unlockdir(d) : 0)
#endif
static textwindows DIR *opendir_nt_impl(char16_t *name, size_t len) {
DIR *res;
if (len + 2 + 1 <= PATH_MAX) {
@ -299,16 +319,7 @@ DIR *fdopendir(int fd) {
return dir;
}
/**
* Reads next entry from directory stream.
*
* This API doesn't define any particular ordering.
*
* @param dir is the object opendir() or fdopendir() returned
* @return next entry or NULL on end or error, which can be
* differentiated by setting errno to 0 beforehand
*/
struct dirent *readdir(DIR *dir) {
static struct dirent *readdir_impl(DIR *dir) {
size_t n;
long basep;
int rc, mode;
@ -393,6 +404,23 @@ struct dirent *readdir(DIR *dir) {
}
}
/**
* Reads next entry from directory stream.
*
* This API doesn't define any particular ordering.
*
* @param dir is the object opendir() or fdopendir() returned
* @return next entry or NULL on end or error, which can be
* differentiated by setting errno to 0 beforehand
*/
struct dirent *readdir(DIR *dir) {
struct dirent *e;
_lockdir(dir);
e = readdir_impl(dir);
_unlockdir(dir);
return e;
}
/**
* Closes directory object returned by opendir().
* @return 0 on success or -1 w/ errno
@ -421,8 +449,12 @@ int closedir(DIR *dir) {
* Returns offset into directory data.
*/
long telldir(DIR *dir) {
STRACE("telldir(%p) → %d", dir, dir->tell);
return dir->tell;
long rc;
_lockdir(dir);
rc = dir->tell;
STRACE("telldir(%p) → %ld", dir, rc);
_unlockdir(dir);
return rc;
}
/**
@ -430,6 +462,7 @@ long telldir(DIR *dir) {
*/
int dirfd(DIR *dir) {
int rc;
_lockdir(dir);
if (dir->iszip) {
rc = eopnotsupp();
} else if (IsWindows()) {
@ -438,6 +471,7 @@ int dirfd(DIR *dir) {
rc = dir->fd;
}
STRACE("dirfd(%p) → %d% m", dir, rc);
_unlockdir(dir);
return rc;
}
@ -445,6 +479,7 @@ int dirfd(DIR *dir) {
* Seeks to beginning of directory stream.
*/
void rewinddir(DIR *dir) {
_lockdir(dir);
if (dir->iszip) {
dir->tell = 0;
dir->zip.offset = GetZipCdirOffset(weaken(__zipos_get)()->cdir);
@ -463,4 +498,27 @@ void rewinddir(DIR *dir) {
}
}
STRACE("rewinddir(%p)", dir);
_unlockdir(dir);
}
/**
* Seeks in directory stream.
*/
void seekdir(DIR *dir, long off) {
long i;
struct Zipos *zip;
_lockdir(dir);
zip = weaken(__zipos_get)();
if (dir->iszip) {
dir->zip.offset = GetZipCdirOffset(weaken(__zipos_get)()->cdir);
for (i = 0; i < off && i < dir->zip.records; ++i) {
dir->zip.offset += ZIP_CFILE_HDRSIZE(zip->map + dir->zip.offset);
}
} else {
i = lseek(dir->fd, off, SEEK_SET);
dir->buf_pos = dir->buf_end = 0;
}
dir->tell = i;
STRACE("seekdir(%p, %ld) → %ld", dir, off, i);
_unlockdir(dir);
}

25
libc/stdio/gcvt.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
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.
*/
#include "libc/fmt/fmt.h"
#include "libc/stdio/stdio.h"
char *gcvt(double x, int n, char *b) {
sprintf(b, "%.*g", n, x);
return b;
}

View file

@ -6,6 +6,7 @@
#include "libc/nexgen32e/threaded.h"
#include "libc/runtime/symbolic.h"
#define _STDIO_H
#define L_ctermid 20
#define FILENAME_MAX PATH_MAX
@ -78,12 +79,14 @@ int fseeko(FILE *, int64_t, int) paramsnonnull();
int64_t ftello(FILE *) paramsnonnull();
void rewind(FILE *) paramsnonnull();
int fopenflags(const char *) paramsnonnull();
void setlinebuf(FILE *);
void setbuf(FILE *, char *);
void setbuffer(FILE *, char *, size_t);
int setvbuf(FILE *, char *, int, size_t);
FILE *popen(const char *, const char *);
int pclose(FILE *);
char *ctermid(char *);
void perror(const char *) relegated;
typedef uint64_t fpos_t;
compatfn char *gets(char *) paramsnonnull();