Support non-blocking i/o across platforms

This change introduces new tests for `O_NONBLOCK` and `SOCK_NONBLOCK` to
confirm that non-blocking i/o is now working on all supported platforms,
including Windows. For example, you can now say on Windows, MacOS, etc.:

    socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);

To create a non-blocking IPv4 TCP socket. Or you can enable non-blocking
i/o on an existing socket / pipe / etc. file descriptor by calling fcntl

    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);

This functionality is polyfilled on older Linux kernels too, e.g. RHEL5.
Now that fcntl() support is much better the FIOCLEX / FIONCLEX polyfills
for ioctl() have been removed since they're ugly non-POSIX diameond APIs

This change fixes a weakness in kprintf() that was causing Windows trace
tools to frequently crash.
This commit is contained in:
Justine Tunney 2023-07-23 02:56:47 -07:00
parent 5c9e03e3e0
commit 1d4eb08fa1
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
102 changed files with 678 additions and 331 deletions

View file

@ -26,12 +26,14 @@
#include "libc/errno.h"
#include "libc/fmt/divmod10.internal.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/asancodes.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/nomultics.internal.h"
#include "libc/intrin/safemacros.internal.h"
@ -259,6 +261,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
va_list va) {
int si, y;
wint_t t, u;
char errnum[12];
const char *abet;
signed char type;
const char *s, *f;
@ -539,6 +542,10 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
} else {
type = 0;
s = _strerrno(e);
if (!s) {
FormatInt32(errnum, e);
s = errnum;
}
goto FormatString;
}
}
@ -612,7 +619,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
if (cols) --cols; // end quote
p = kemitquote(p, e, type, hash);
}
if (sign == ' ' && (!pdot || prec) && *s) {
if (sign == ' ' && (!pdot || prec) && s && *s) {
if (p < e) *p = ' ';
++p;
}