mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 23:08:31 +00:00
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:
parent
a8cf0f7e89
commit
6a5717a48f
50 changed files with 3783 additions and 280 deletions
|
@ -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
25
libc/stdio/gcvt.c
Normal 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;
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue