Make improvements

- This change fixes a bug that allowed unbuffered printf() output (to
  streams like stderr) to be truncated. This regression was introduced
  some time between now and the last release.

- POSIX specifies all functions as thread safe by default. This change
  works towards cleaning up our use of the @threadsafe / @threadunsafe
  documentation annotations to reflect that. The goal is (1) to use
  @threadunsafe to document functions which POSIX say needn't be thread
  safe, and (2) use @threadsafe to document functions that we chose to
  implement as thread safe even though POSIX didn't mandate it.

- Tidy up the clock_gettime() implementation. We're now trying out a
  cleaner approach to system call support that aims to maintain the
  Linux errno convention as long as possible. This also fixes bugs that
  existed previously, where the vDSO errno wasn't being translated
  properly. The gettimeofday() system call is now a wrapper for
  clock_gettime(), which reduces bloat in apps that use both.

- The recently-introduced improvements to the execute bit on Windows has
  had bugs fixed. access(X_OK) on a directory on Windows now succeeds.
  fstat() will now perform the MZ/#! ReadFile() operation correctly.

- Windows.h is no longer included in libc/isystem/, because it confused
  PCRE's build system into thinking Cosmopolitan is a WIN32 platform.
  Cosmo's Windows.h polyfill was never even really that good, since it
  only defines a subset of the subset of WIN32 APIs that Cosmo defines.

- The setlongerjmp() / longerjmp() APIs are removed. While they're nice
  APIs that are superior to the standardized setjmp / longjmp functions,
  they weren't superior enough to not be dead code in the monorepo. If
  you use these APIs, please file an issue and they'll be restored.

- The .com appending magic has now been removed from APE Loader.
This commit is contained in:
Justine Tunney 2023-10-02 19:25:19 -07:00
parent b99512ac58
commit ff77f2a6af
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
226 changed files with 708 additions and 2657 deletions

View file

@ -26,7 +26,6 @@
* portability, since that's guaranteed to work with all libraries
* @return bytes written (excluding NUL) or -1 w/ errno
* @see xasprintf() for a better API
* @threadsafe
*/
int asprintf(char **strp, const char *fmt, ...) {
int res;

View file

@ -23,7 +23,6 @@
*
* @param f is file object stream pointer
* @see clearerr_unlocked()
* @threadsafe
*/
void clearerr(FILE *f) {
flockfile(f);

View file

@ -24,7 +24,6 @@
*
* @param f is file object stream pointer
* @see clearerr()
* @threadsafe
*/
void clearerr_unlocked(FILE *f) {
f->state = 0;

View file

@ -513,6 +513,7 @@ static struct dirent *readdir_impl(DIR *dir) {
* @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
* @threadunsafe
*/
struct dirent *readdir(DIR *dir) {
struct dirent *e;
@ -535,7 +536,6 @@ struct dirent *readdir(DIR *dir) {
* @param result will receive `output` pointer, or null on eof
* @return 0 on success, or errno on error
* @returnserrno
* @threadsafe
*/
errno_t readdir_r(DIR *dir, struct dirent *output, struct dirent **result) {
int err, olderr;
@ -587,7 +587,6 @@ int closedir(DIR *dir) {
/**
* Returns offset into directory data.
* @threadsafe
*/
long telldir(DIR *dir) {
long rc;
@ -599,7 +598,6 @@ long telldir(DIR *dir) {
/**
* Returns file descriptor associated with DIR object.
* @threadsafe
*/
int dirfd(DIR *dir) {
return dir->fd;
@ -607,7 +605,6 @@ int dirfd(DIR *dir) {
/**
* Seeks to beginning of directory stream.
* @threadsafe
*/
void rewinddir(DIR *dir) {
lockdir(dir);
@ -634,7 +631,6 @@ void rewinddir(DIR *dir) {
/**
* Seeks in directory stream.
* @threadsafe
*/
void seekdir(DIR *dir, long tell) {
lockdir(dir);

View file

@ -23,7 +23,6 @@
*
* @param f is file object stream pointer
* @see feof_unlocked()
* @threadsafe
*/
int feof(FILE *f) {
int rc;

View file

@ -25,7 +25,6 @@
* @return non-zero if and only if it's an error state
* @see ferror_unlocked(), feof()
* @note EOF doesn't count
* @threadsafe
*/
errno_t ferror(FILE *f) {
int rc;

View file

@ -23,7 +23,6 @@
*
* @param f is the stream handle, or 0 for all streams
* @return is 0 on success or -1 on error
* @threadsafe
*/
int fflush(FILE *f) {
int rc;

View file

@ -24,7 +24,6 @@
* @param f is non-null file object stream pointer
* @return byte in range 0..255, or -1 w/ errno
* @see fgetc_unlocked()
* @threadsafe
*/
int fgetc(FILE *f) {
int rc;

View file

@ -34,7 +34,6 @@
* @return s on success, NULL on error, or NULL if EOF happens when
* zero characters have been read
* @see fgets_unlocked()
* @threadsafe
*/
char *fgets(char *s, int size, FILE *f) {
char *res;

View file

@ -24,7 +24,6 @@
* @param f is non-null file object stream pointer
* @return wide character or -1 on EOF or error
* @see fgetwc_unlocked()
* @threadsafe
*/
wint_t fgetwc(FILE *f) {
wint_t wc;

View file

@ -29,7 +29,6 @@
* @param size is byte length of `s`
* @param f is file stream object pointer
* @see fgetws()
* @threadsafe
*/
wchar_t *fgetws(wchar_t *s, int size, FILE *f) {
wchar_t *rc;

View file

@ -24,7 +24,6 @@
*
* @param f is file stream object pointer
* @return fd on success or -1 w/ errno;
* @threadsafe
*/
int fileno(FILE *f) {
int rc;

View file

@ -23,7 +23,6 @@
*
* @param c is byte to buffer or write, which is masked
* @return c as unsigned char if written or -1 w/ errno
* @threadsafe
*/
int fputc(int c, FILE *f) {
int rc;

View file

@ -28,7 +28,6 @@
* @param s is a NUL-terminated string that's non-NULL
* @param f is an open stream
* @return bytes written, or -1 w/ errno
* @threadsafe
*/
int fputs(const char *s, FILE *f) {
int rc;

View file

@ -24,7 +24,6 @@
* @param wc has wide character
* @param f is file object stream pointer
* @return wide character if written or -1 w/ errno
* @threadsafe
*/
wint_t fputwc(wchar_t wc, FILE *f) {
wint_t rc;

View file

@ -28,7 +28,6 @@
* @param s is a NUL-terminated string that's non-NULL
* @param f is an open stream
* @return strlen(s), or -1 w/ errno
* @threadsafe
*/
int fputws(const wchar_t *s, FILE *f) {
int rc;

View file

@ -27,7 +27,6 @@
* @param stride specifies the size of individual items
* @param count is the number of strides to fetch
* @return count on success, [0,count) on eof, or 0 on error or count==0
* @threadsafe
*/
size_t fread(void *buf, size_t stride, size_t count, FILE *f) {
size_t rc;

View file

@ -32,7 +32,6 @@
* @param offset is the byte delta
* @param whence can be SEET_SET, SEEK_CUR, or SEEK_END
* @returns 0 on success or -1 on error
* @threadsafe
*/
int fseek(FILE *f, int64_t offset, int whence) {
int rc;

View file

@ -44,7 +44,6 @@ static inline int64_t ftell_unlocked(FILE *f) {
*
* @param stream is a non-null stream handle
* @returns current byte offset from beginning, or -1 w/ errno
* @threadsafe
*/
int64_t ftell(FILE *f) {
int64_t rc;

View file

@ -39,6 +39,7 @@ asm(".include \"libc/disclaimer.inc\"");
* @return 0 on success, -1 on error, or non-zero `fn` result
* @see examples/walk.c for example
* @see nftw()
* @threadsafe
*/
int ftw(const char *dirpath,
int fn(const char *fpath,

View file

@ -26,7 +26,6 @@
* @param stride specifies the size of individual items
* @param count is the number of strides to write
* @return count on success, [0,count) on EOF, 0 on error or count==0
* @threadsafe
*/
size_t fwrite(const void *data, size_t stride, size_t count, FILE *f) {
size_t rc;

View file

@ -21,7 +21,6 @@
/**
* Reads UTF-8 character from stream.
* @return wide character or -1 on EOF or error
* @threadsafe
*/
wint_t getwchar(void) {
return fgetwc(stdin);

View file

@ -160,6 +160,7 @@ static int do_nftw(char *path,
*
* @return 0 on success, -1 on error, or non-zero `fn` result
* @see examples/walk.c for example
* @threadsafe
*/
int nftw(const char *dirpath,
int fn(const char *fpath,

View file

@ -52,7 +52,6 @@
* @raise EAGAIN if `RLIMIT_NPROC` was exceeded
* @raise EINTR if signal was delivered
* @cancellationpoint
* @threadsafe
*/
FILE *popen(const char *cmdline, const char *mode) {
FILE *f, *f2;

View file

@ -22,7 +22,6 @@
* Writes byte to stdout.
*
* @return c (as unsigned char) if written or -1 w/ errno
* @threadsafe
*/
int putchar(int c) {
return fputc(c, stdout);

View file

@ -21,7 +21,6 @@
/**
* Writes wide character to stdout.
* @return wc if written or -1 w/ errno
* @threadsafe
*/
wint_t putwchar(wchar_t wc) {
return fputwc(wc, stdout);

View file

@ -36,6 +36,7 @@
* @note this function does well on bigcrush and practrand
* @note this function is not intended for cryptography
* @see lemur64(), _rand64(), rdrand()
* @threadunsafe
*/
int rand(void) {
return KnuthLinearCongruentialGenerator(&g_rando) >> 33;

42
libc/stdio/sysparam.h Normal file
View file

@ -0,0 +1,42 @@
#ifndef COSMOPOLITAN_LIBC_SYSPARAM_H_
#define COSMOPOLITAN_LIBC_SYSPARAM_H_
#define MAXSYMLINKS 20
#define MAXHOSTNAMELEN 64
#define MAXNAMLEN 255
#define MAXPATHLEN PATH_MAX
#define NBBY 8
#define NGROUPS 32
#define CANBSIZ 255
#define NOFILE 256
#define NCARGS 131072
#define DEV_BSIZE 512
#define NOGROUP (-1)
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define __bitop(x, i, o) ((x)[(i) / 8] o(1 << (i) % 8))
#define setbit(x, i) __bitop(x, i, |=)
#define clrbit(x, i) __bitop(x, i, &= ~)
#define isset(x, i) __bitop(x, i, &)
#define isclr(x, i) !isset(x, i)
#undef roundup
#define roundup(n, d) (howmany(n, d) * (d))
#define powerof2(n) !(((n)-1) & (n))
#define howmany(n, d) (((n) + ((d)-1)) / (d))
#ifdef MIN
#undef MIN
#endif
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#ifdef MAX
#undef MAX
#endif
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SYSPARAM_H_ */

View file

@ -57,7 +57,6 @@
* @raise EINTR if signal was delivered
* @cancellationpoint
* @asyncsignalsafe
* @threadsafe
* @vforksafe
*/
FILE *tmpfile(void) {

View file

@ -20,7 +20,6 @@
/**
* Pushes byte back to stream.
* @threadsafe
*/
int ungetc(int c, FILE *f) {
int rc;

View file

@ -20,7 +20,6 @@
/**
* Pushes wide character back to stream.
* @threadsafe
*/
wint_t ungetwc(wint_t c, FILE *f) {
wint_t rc;

View file

@ -23,7 +23,6 @@
/**
* Formats string w/ dynamic memory allocation.
* @see xasprintf() for a better API
* @threadsafe
*/
int vasprintf(char **strp, const char *fmt, va_list va) {
va_list vb;

View file

@ -59,12 +59,11 @@ static int __vfprintf_nbuf(const char *s, struct state *t, size_t n) {
for (i = 0; i < n; ++i) {
t->b.p[t->b.n++] = s[i];
if (t->b.n == sizeof(t->b.p)) {
if (!fwrite_unlocked(s, 1, t->b.n, t->f)) {
if (!fwrite_unlocked(t->b.p, 1, t->b.n, t->f)) {
return -1;
}
t->b.n = 0;
}
if (ckd_add(&t->n, t->n, 1)) {
} else if (ckd_add(&t->n, t->n, 1)) {
return eoverflow();
}
}