mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Perform inconsequential code cleanup
This commit is contained in:
parent
929478c524
commit
decf216655
52 changed files with 326 additions and 442 deletions
|
@ -91,7 +91,7 @@ VM = o/third_party/qemu/qemu-aarch64
|
||||||
HOSTS ?= pi silicon
|
HOSTS ?= pi silicon
|
||||||
else
|
else
|
||||||
ARCH = x86_64
|
ARCH = x86_64
|
||||||
HOSTS ?= freebsd openbsd openbsd73 netbsd rhel7 rhel5 xnu win10
|
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(PREFIX),)
|
ifeq ($(PREFIX),)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
│ SUCH DAMAGE. │
|
│ SUCH DAMAGE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/dns/dns.h"
|
#include "libc/dns/dns.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/log/bsd.h"
|
#include "libc/log/bsd.h"
|
||||||
|
|
|
@ -56,9 +56,7 @@
|
||||||
*/
|
*/
|
||||||
int close(int fd) {
|
int close(int fd) {
|
||||||
int rc;
|
int rc;
|
||||||
if (fd == -1) {
|
if (fd < 0) {
|
||||||
rc = 0;
|
|
||||||
} else if (fd < 0) {
|
|
||||||
rc = ebadf();
|
rc = ebadf();
|
||||||
} else {
|
} else {
|
||||||
// for performance reasons we want to avoid holding __fds_lock()
|
// for performance reasons we want to avoid holding __fds_lock()
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/struct/utsname-linux.internal.h"
|
#include "libc/calls/struct/utsname-linux.internal.h"
|
||||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,9 @@ static inline void GetProgramExecutableNameImpl(char *p, char *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsMetal()) {
|
if (IsMetal()) {
|
||||||
if (!memccpy(p, APE_COM_NAME, 0, e - p - 1)) e[-1] = 0;
|
if (!memccpy(p, APE_COM_NAME, 0, e - p - 1)) {
|
||||||
|
e[-1] = 0;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@ int timespec_sleep_until(struct timespec);
|
||||||
struct timespec timespec_sub(struct timespec, struct timespec) pureconst;
|
struct timespec timespec_sub(struct timespec, struct timespec) pureconst;
|
||||||
struct timespec timespec_subz(struct timespec, struct timespec) pureconst;
|
struct timespec timespec_subz(struct timespec, struct timespec) pureconst;
|
||||||
int sys_futex(int *, int, int, const struct timespec *, int *);
|
int sys_futex(int *, int, int, const struct timespec *, int *);
|
||||||
|
static inline struct timespec timespec_fromseconds(int64_t __x) {
|
||||||
|
return (struct timespec){__x};
|
||||||
|
}
|
||||||
static inline bool timespec_iszero(struct timespec __ts) {
|
static inline bool timespec_iszero(struct timespec __ts) {
|
||||||
return !(__ts.tv_sec | __ts.tv_nsec);
|
return !(__ts.tv_sec | __ts.tv_nsec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,9 @@ struct timeval timeval_add(struct timeval, struct timeval) pureconst;
|
||||||
struct timeval timeval_sub(struct timeval, struct timeval) pureconst;
|
struct timeval timeval_sub(struct timeval, struct timeval) pureconst;
|
||||||
struct timeval timeval_subz(struct timeval, struct timeval) pureconst;
|
struct timeval timeval_subz(struct timeval, struct timeval) pureconst;
|
||||||
struct timeval timespec_totimeval(struct timespec) pureconst;
|
struct timeval timespec_totimeval(struct timespec) pureconst;
|
||||||
struct timespec timeval_totimespec(struct timeval) pureconst;
|
static inline struct timespec timeval_totimespec(struct timeval __tv) {
|
||||||
|
return (struct timespec){__tv.tv_sec, __tv.tv_usec * 1000};
|
||||||
|
}
|
||||||
static inline bool timeval_iszero(struct timeval __tv) {
|
static inline bool timeval_iszero(struct timeval __tv) {
|
||||||
return !(__tv.tv_sec | __tv.tv_usec);
|
return !(__tv.tv_sec | __tv.tv_usec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,8 @@ int utimes(const char *path, const struct timeval tv[2]) {
|
||||||
int rc;
|
int rc;
|
||||||
struct timespec ts[2];
|
struct timespec ts[2];
|
||||||
if (tv) {
|
if (tv) {
|
||||||
ts[0].tv_sec = tv[0].tv_sec;
|
ts[0] = timeval_totimespec(tv[0]);
|
||||||
ts[0].tv_nsec = tv[0].tv_usec * 1000;
|
ts[1] = timeval_totimespec(tv[1]);
|
||||||
ts[1].tv_sec = tv[1].tv_sec;
|
|
||||||
ts[1].tv_nsec = tv[1].tv_usec * 1000;
|
|
||||||
rc = __utimens(AT_FDCWD, path, ts, 0);
|
rc = __utimens(AT_FDCWD, path, ts, 0);
|
||||||
} else {
|
} else {
|
||||||
rc = __utimens(AT_FDCWD, path, 0, 0);
|
rc = __utimens(AT_FDCWD, path, 0, 0);
|
||||||
|
|
|
@ -13,7 +13,7 @@ typedef uint64_t dev_t; /* int32_t on xnu */
|
||||||
typedef uint64_t fsblkcnt_t;
|
typedef uint64_t fsblkcnt_t;
|
||||||
typedef int64_t fsfilcnt_t; /* uint32_t on xnu */
|
typedef int64_t fsfilcnt_t; /* uint32_t on xnu */
|
||||||
typedef uint32_t gid_t;
|
typedef uint32_t gid_t;
|
||||||
typedef uint32_t id_t; /* int32_t on linux/freebsd/etc. */
|
typedef int32_t id_t; /* int32_t on linux/freebsd/etc. */
|
||||||
typedef uint32_t in_addr_t;
|
typedef uint32_t in_addr_t;
|
||||||
typedef uint32_t in_addr_t;
|
typedef uint32_t in_addr_t;
|
||||||
typedef uint16_t in_port_t;
|
typedef uint16_t in_port_t;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_DNS_DNS_H_
|
#ifndef COSMOPOLITAN_LIBC_DNS_DNS_H_
|
||||||
#define COSMOPOLITAN_LIBC_DNS_DNS_H_
|
#define COSMOPOLITAN_LIBC_DNS_DNS_H_
|
||||||
#include "libc/calls/weirdtypes.h"
|
|
||||||
#include "libc/dns/resolvconf.h"
|
#include "libc/dns/resolvconf.h"
|
||||||
#include "libc/sock/sock.h"
|
|
||||||
#include "libc/sock/struct/sockaddr.h"
|
#include "libc/sock/struct/sockaddr.h"
|
||||||
|
|
||||||
#define DNS_PORT 53
|
#define DNS_PORT 53
|
||||||
|
@ -67,8 +65,8 @@ struct addrinfo {
|
||||||
int getaddrinfo(const char *, const char *, const struct addrinfo *,
|
int getaddrinfo(const char *, const char *, const struct addrinfo *,
|
||||||
struct addrinfo **);
|
struct addrinfo **);
|
||||||
void freeaddrinfo(struct addrinfo *);
|
void freeaddrinfo(struct addrinfo *);
|
||||||
int getnameinfo(const struct sockaddr *, socklen_t, char *, socklen_t, char *,
|
int getnameinfo(const struct sockaddr *, uint32_t, char *, uint32_t, char *,
|
||||||
socklen_t, int);
|
uint32_t, int);
|
||||||
const char *gai_strerror(int);
|
const char *gai_strerror(int);
|
||||||
int CompareDnsNames(const char *, const char *) paramsnonnull();
|
int CompareDnsNames(const char *, const char *) paramsnonnull();
|
||||||
int PascalifyDnsName(uint8_t *, size_t, const char *) paramsnonnull();
|
int PascalifyDnsName(uint8_t *, size_t, const char *) paramsnonnull();
|
||||||
|
|
|
@ -57,7 +57,7 @@ void endprotoent(void);
|
||||||
|
|
||||||
struct hostent *gethostent(void);
|
struct hostent *gethostent(void);
|
||||||
struct hostent *gethostbyname(const char *);
|
struct hostent *gethostbyname(const char *);
|
||||||
struct hostent *gethostbyaddr(const void *, socklen_t, int);
|
struct hostent *gethostbyaddr(const void *, uint32_t, int);
|
||||||
void sethostent(int);
|
void sethostent(int);
|
||||||
void endhostent(void);
|
void endhostent(void);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "libc/dns/resolvconf.h"
|
#include "libc/dns/resolvconf.h"
|
||||||
#include "libc/dns/servicestxt.h"
|
#include "libc/dns/servicestxt.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
#include "libc/intrin/safemacros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/gc.h"
|
#include "libc/mem/gc.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
|
@ -94,7 +94,7 @@ int getaddrinfo(const char *name, const char *service,
|
||||||
return EAI_NONAME;
|
return EAI_NONAME;
|
||||||
} else if (ResolveHostsTxt(GetHostsTxt(), AF_INET, name, ai->ai_addr,
|
} else if (ResolveHostsTxt(GetHostsTxt(), AF_INET, name, ai->ai_addr,
|
||||||
sizeof(ai->ai_addr4), &canon) > 0) {
|
sizeof(ai->ai_addr4), &canon) > 0) {
|
||||||
memcpy(ai->ai_canonname, canon, min(strlen(canon), DNS_NAME_MAX) + 1);
|
strlcpy(ai->ai_canonname, canon, DNS_NAME_MAX + 1);
|
||||||
*res = ai;
|
*res = ai;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
|
|
||||||
struct hostent *gethostbyaddr(const void *s_addr, socklen_t len, int type) {
|
struct hostent *gethostbyaddr(const void *s_addr, uint32_t len, int type) {
|
||||||
static struct hostent *ptr1, he1;
|
static struct hostent *ptr1, he1;
|
||||||
static char h_name[DNS_NAME_MAX + 1];
|
static char h_name[DNS_NAME_MAX + 1];
|
||||||
static char *h_aliases[1];
|
static char *h_aliases[1];
|
||||||
|
|
|
@ -53,16 +53,16 @@ struct hostent *gethostbyname(const char *name) {
|
||||||
ptr0 = &he0;
|
ptr0 = &he0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getaddrinfo(name, NULL, NULL, &result) || result == NULL) return NULL;
|
if (getaddrinfo(name, NULL, NULL, &result) || result == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* if getaddrinfo is successful, result->ai_canonname is non-NULL,
|
/* if getaddrinfo is successful, result->ai_canonname is non-NULL,
|
||||||
* (see newaddrinfo) but the string can still be empty */
|
* (see newaddrinfo) but the string can still be empty */
|
||||||
if (result->ai_canonname[0])
|
strlcpy(ptr0->h_name, *result->ai_canonname ? result->ai_canonname : name,
|
||||||
memccpy(ptr0->h_name, result->ai_canonname, '\0', DNS_NAME_MAX);
|
sizeof(h_name));
|
||||||
else
|
|
||||||
memccpy(ptr0->h_name, name, '\0', DNS_NAME_MAX);
|
|
||||||
|
|
||||||
*((uint32_t *)ptr0->h_addr_list[0]) = (result->ai_addr4->sin_addr.s_addr);
|
*((uint32_t *)ptr0->h_addr_list[0]) = result->ai_addr4->sin_addr.s_addr;
|
||||||
/* TODO: if result has ai_next, fit multiple entries for h_addr_list */
|
/* TODO: if result has ai_next, fit multiple entries for h_addr_list */
|
||||||
|
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/dns/hoststxt.h"
|
#include "libc/dns/hoststxt.h"
|
||||||
|
#include "libc/dns/servicestxt.h"
|
||||||
#include "libc/fmt/fmt.h"
|
#include "libc/fmt/fmt.h"
|
||||||
#include "libc/intrin/bits.h"
|
#include "libc/intrin/bits.h"
|
||||||
#include "libc/intrin/pushpop.internal.h"
|
#include "libc/intrin/pushpop.internal.h"
|
||||||
#include "libc/intrin/safemacros.internal.h"
|
#include "libc/intrin/safemacros.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nt/systeminfo.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -39,16 +39,11 @@ static struct HostsTxtInitialStaticMemory {
|
||||||
char strings[64];
|
char strings[64];
|
||||||
} g_hoststxt_init;
|
} g_hoststxt_init;
|
||||||
|
|
||||||
static textwindows dontinline char *GetNtHostsTxtPath(char *pathbuf,
|
static const char *GetHostsTxtPath(char *path, size_t size) {
|
||||||
uint32_t size) {
|
if (!IsWindows()) {
|
||||||
const char *const kWinHostsPath = "\\drivers\\etc\\hosts";
|
return "/etc/hosts";
|
||||||
uint32_t len = GetSystemDirectoryA(&pathbuf[0], size);
|
|
||||||
if (len && len + strlen(kWinHostsPath) + 1 < size) {
|
|
||||||
if (pathbuf[len] == '\\') pathbuf[len--] = '\0';
|
|
||||||
memcpy(&pathbuf[len], kWinHostsPath, strlen(kWinHostsPath) + 1);
|
|
||||||
return &pathbuf[0];
|
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return GetSystemDirectoryPath(path, size, "drivers\\etc\\hosts");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +55,7 @@ static textwindows dontinline char *GetNtHostsTxtPath(char *pathbuf,
|
||||||
*/
|
*/
|
||||||
const struct HostsTxt *GetHostsTxt(void) {
|
const struct HostsTxt *GetHostsTxt(void) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
const char *path;
|
char pathbuf[256];
|
||||||
char pathbuf[PATH_MAX];
|
|
||||||
struct HostsTxtInitialStaticMemory *init;
|
struct HostsTxtInitialStaticMemory *init;
|
||||||
init = &g_hoststxt_init;
|
init = &g_hoststxt_init;
|
||||||
pthread_mutex_lock(&init->lock);
|
pthread_mutex_lock(&init->lock);
|
||||||
|
@ -72,11 +66,7 @@ const struct HostsTxt *GetHostsTxt(void) {
|
||||||
init->ht.strings.n = pushpop(ARRAYLEN(init->strings));
|
init->ht.strings.n = pushpop(ARRAYLEN(init->strings));
|
||||||
init->ht.strings.p = init->strings;
|
init->ht.strings.p = init->strings;
|
||||||
__cxa_atexit(FreeHostsTxt, &g_hoststxt, NULL);
|
__cxa_atexit(FreeHostsTxt, &g_hoststxt, NULL);
|
||||||
path = "/etc/hosts";
|
if ((f = fopen(GetHostsTxtPath(pathbuf, sizeof(pathbuf)), "r"))) {
|
||||||
if (IsWindows()) {
|
|
||||||
path = firstnonnull(GetNtHostsTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
|
||||||
}
|
|
||||||
if (fileexists(path) && (f = fopen(path, "r"))) {
|
|
||||||
if (ParseHostsTxt(g_hoststxt, f) == -1) {
|
if (ParseHostsTxt(g_hoststxt, f) == -1) {
|
||||||
/* TODO(jart): Elevate robustness. */
|
/* TODO(jart): Elevate robustness. */
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,8 @@
|
||||||
*
|
*
|
||||||
* @return 0 on success or EAI_xxx value
|
* @return 0 on success or EAI_xxx value
|
||||||
*/
|
*/
|
||||||
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *name,
|
int getnameinfo(const struct sockaddr *addr, uint32_t addrlen, char *name,
|
||||||
socklen_t namelen, char *service, socklen_t servicelen,
|
uint32_t namelen, char *service, uint32_t servicelen,
|
||||||
int flags) {
|
int flags) {
|
||||||
char *p, rdomain[1 + sizeof "255.255.255.255.in-addr.arpa"];
|
char *p, rdomain[1 + sizeof "255.255.255.255.in-addr.arpa"];
|
||||||
char info[NI_MAXHOST + 1];
|
char info[NI_MAXHOST + 1];
|
||||||
|
|
|
@ -24,19 +24,14 @@
|
||||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/dns/prototxt.h"
|
#include "libc/dns/prototxt.h"
|
||||||
#include "libc/nt/systeminfo.h"
|
#include "libc/dns/servicestxt.h"
|
||||||
#include "libc/str/str.h"
|
|
||||||
|
|
||||||
textwindows char *GetNtProtocolsTxtPath(char *pathbuf, uint32_t size) {
|
const char *GetProtocolsTxtPath(char *buf, size_t size) {
|
||||||
/* protocol, not plural */
|
if (!IsWindows()) {
|
||||||
const char *const kWinHostsPath = "\\drivers\\etc\\protocol";
|
return "/etc/protocols";
|
||||||
uint32_t len = GetSystemDirectoryA(&pathbuf[0], size);
|
|
||||||
if (len && len + strlen(kWinHostsPath) + 1 < size) {
|
|
||||||
if (pathbuf[len] == '\\') pathbuf[len--] = '\0';
|
|
||||||
memcpy(&pathbuf[len], kWinHostsPath, strlen(kWinHostsPath) + 1);
|
|
||||||
return &pathbuf[0];
|
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return GetSystemDirectoryPath(buf, size, "drivers\\etc\\protocol");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,18 +24,13 @@
|
||||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/dns/servicestxt.h"
|
#include "libc/dns/servicestxt.h"
|
||||||
#include "libc/nt/systeminfo.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
|
|
||||||
textwindows char *GetNtServicesTxtPath(char *pathbuf, uint32_t size) {
|
const char *GetServicesTxtPath(char *path, size_t size) {
|
||||||
const char *const kWinHostsPath = "\\drivers\\etc\\services";
|
if (!IsWindows()) {
|
||||||
uint32_t len = GetSystemDirectoryA(&pathbuf[0], size);
|
return "/etc/services";
|
||||||
if (len && len + strlen(kWinHostsPath) + 1 < size) {
|
|
||||||
if (pathbuf[len] == '\\') pathbuf[len--] = '\0';
|
|
||||||
memcpy(&pathbuf[len], kWinHostsPath, strlen(kWinHostsPath) + 1);
|
|
||||||
return &pathbuf[0];
|
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return GetSystemDirectoryPath(path, size, "drivers\\etc\\services");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "libc/dns/ent.h"
|
#include "libc/dns/ent.h"
|
||||||
#include "libc/dns/servicestxt.h"
|
#include "libc/dns/servicestxt.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
struct servent *getservbyname(const char *name, const char *proto) {
|
struct servent *getservbyname(const char *name, const char *proto) {
|
||||||
|
@ -42,9 +43,10 @@ struct servent *getservbyname(const char *name, const char *proto) {
|
||||||
ptr0 = &se0;
|
ptr0 = &se0;
|
||||||
}
|
}
|
||||||
if (proto) {
|
if (proto) {
|
||||||
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) return NULL;
|
strlcpy(localproto, proto, sizeof(localproto));
|
||||||
} else
|
} else {
|
||||||
strcpy(localproto, "");
|
*localproto = 0;
|
||||||
|
}
|
||||||
p = LookupServicesByName(name, ptr0->s_proto, DNS_NAME_MAX, ptr0->s_name,
|
p = LookupServicesByName(name, ptr0->s_proto, DNS_NAME_MAX, ptr0->s_name,
|
||||||
DNS_NAME_MAX, NULL);
|
DNS_NAME_MAX, NULL);
|
||||||
if (p == -1) return NULL;
|
if (p == -1) return NULL;
|
||||||
|
|
|
@ -41,9 +41,12 @@ struct servent *getservbyport(int port, const char *proto) {
|
||||||
ptr1 = &se1;
|
ptr1 = &se1;
|
||||||
}
|
}
|
||||||
if (proto) {
|
if (proto) {
|
||||||
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) return NULL;
|
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) {
|
||||||
} else
|
return NULL;
|
||||||
strcpy(localproto, "");
|
}
|
||||||
|
} else {
|
||||||
|
*localproto = 0;
|
||||||
|
}
|
||||||
if (LookupServicesByPort(ntohs(port), ptr1->s_proto, DNS_NAME_MAX,
|
if (LookupServicesByPort(ntohs(port), ptr1->s_proto, DNS_NAME_MAX,
|
||||||
ptr1->s_name, DNS_NAME_MAX, NULL) == -1) {
|
ptr1->s_name, DNS_NAME_MAX, NULL) == -1) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
37
libc/dns/getsystemdirectorypath.c
Normal file
37
libc/dns/getsystemdirectorypath.c
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*-*- 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 2023 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/dns/dns.h"
|
||||||
|
#include "libc/nt/systeminfo.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
|
// e.g. GetSystemDirectoryPath(buf, size, "FOO") → "C:\WINDOWS\SYSTEM32\FOO"
|
||||||
|
textwindows char *GetSystemDirectoryPath(char *buf, size_t size,
|
||||||
|
const char *path) {
|
||||||
|
uint32_t syslen = GetSystemDirectoryA(buf, size);
|
||||||
|
size_t pathlen = strlen(path);
|
||||||
|
if (syslen && syslen + pathlen + 1 < size) {
|
||||||
|
if (buf[syslen] == '\\') {
|
||||||
|
--syslen;
|
||||||
|
}
|
||||||
|
memcpy(buf + syslen, path, pathlen + 1);
|
||||||
|
return buf;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,17 +51,16 @@ int LookupProtoByName(const char *protoname, char *buf, size_t bufsize,
|
||||||
const char *filepath) {
|
const char *filepath) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *line;
|
char *line;
|
||||||
const char *path;
|
|
||||||
size_t linesize;
|
size_t linesize;
|
||||||
|
const char *path;
|
||||||
int found, result;
|
int found, result;
|
||||||
char pathbuf[PATH_MAX];
|
char pathbuf[256];
|
||||||
char *name, *number, *alias, *comment, *tok;
|
char *name, *number, *alias, *comment, *tok;
|
||||||
if (!(path = filepath)) {
|
if (!(path = filepath)) {
|
||||||
path = "/etc/protocols";
|
path =
|
||||||
if (IsWindows()) {
|
!IsWindows()
|
||||||
path =
|
? "/etc/protocols"
|
||||||
firstnonnull(GetNtProtocolsTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
: firstnonnull(GetProtocolsTxtPath(pathbuf, sizeof(pathbuf)), path);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (bufsize == 0 || !(f = fopen(path, "r"))) {
|
if (bufsize == 0 || !(f = fopen(path, "r"))) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -70,18 +69,20 @@ int LookupProtoByName(const char *protoname, char *buf, size_t bufsize,
|
||||||
linesize = 0;
|
linesize = 0;
|
||||||
found = 0;
|
found = 0;
|
||||||
result = -1;
|
result = -1;
|
||||||
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
|
while (found == 0 && getline(&line, &linesize, f) != -1) {
|
||||||
if ((comment = strchr(line, '#'))) *comment = '\0';
|
if ((comment = strchr(line, '#'))) *comment = '\0';
|
||||||
name = strtok_r(line, " \t\r\n\v", &tok);
|
name = strtok_r(line, " \t\r\n\v", &tok);
|
||||||
number = strtok_r(NULL, "/ \t\r\n\v", &tok);
|
number = strtok_r(NULL, "/ \t\r\n\v", &tok);
|
||||||
if (name && number) {
|
if (name && number) {
|
||||||
alias = name;
|
alias = name;
|
||||||
while (alias && strcasecmp(alias, protoname) != 0)
|
while (alias && strcasecmp(alias, protoname)) {
|
||||||
alias = strtok_r(NULL, " \t\r\n\v", &tok);
|
alias = strtok_r(NULL, " \t\r\n\v", &tok);
|
||||||
if (alias) /* alias matched with protoname */
|
}
|
||||||
{
|
if (alias) { /* alias matched with protoname */
|
||||||
if (!memccpy(buf, name, '\0', bufsize)) {
|
if (!memccpy(buf, name, '\0', bufsize)) {
|
||||||
strcpy(buf, "");
|
if (bufsize) {
|
||||||
|
*buf = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result = atoi(number);
|
result = atoi(number);
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include "libc/dns/prototxt.h"
|
#include "libc/dns/prototxt.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
#include "libc/intrin/safemacros.internal.h"
|
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -46,28 +45,22 @@
|
||||||
* @param protonum is the protocol number
|
* @param protonum is the protocol number
|
||||||
* @param buf is a buffer to store the official name of the protocol
|
* @param buf is a buffer to store the official name of the protocol
|
||||||
* @param bufsize is the size of buf
|
* @param bufsize is the size of buf
|
||||||
* @param filepath is the location of the protocols file
|
* @param path is the location of the protocols file, which may be NULL
|
||||||
* (if NULL, uses /etc/protocols)
|
* to use the system-wide default
|
||||||
* @return 0 on success, -1 on error
|
* @return 0 on success, -1 on error
|
||||||
* @note aliases are not read from the file.
|
* @note aliases are not read from the file.
|
||||||
*/
|
*/
|
||||||
int LookupProtoByNumber(const int protonum, char *buf, size_t bufsize,
|
int LookupProtoByNumber(const int protonum, char *buf, size_t bufsize,
|
||||||
const char *filepath) {
|
const char *path) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *line;
|
|
||||||
int found;
|
int found;
|
||||||
|
char *line;
|
||||||
size_t linesize;
|
size_t linesize;
|
||||||
const char *path;
|
char pathbuf[256];
|
||||||
char pathbuf[PATH_MAX];
|
|
||||||
char *name, *number, *comment, *tok;
|
char *name, *number, *comment, *tok;
|
||||||
if (!(path = filepath)) {
|
if (!bufsize ||
|
||||||
path = "/etc/protocols";
|
!(f = fopen(path ? path : GetProtocolsTxtPath(pathbuf, sizeof(pathbuf)),
|
||||||
if (IsWindows()) {
|
"r"))) {
|
||||||
path =
|
|
||||||
firstnonnull(GetNtProtocolsTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bufsize == 0 || !(f = fopen(path, "r"))) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
line = NULL;
|
line = NULL;
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
* @param buf is a buffer to store the official name of the service
|
* @param buf is a buffer to store the official name of the service
|
||||||
* (if NULL, the official name is not stored)
|
* (if NULL, the official name is not stored)
|
||||||
* @param bufsize is the size of buf
|
* @param bufsize is the size of buf
|
||||||
* @param filepath is the location of services file
|
* @param path is the location of services file
|
||||||
* (if NULL, uses /etc/services)
|
* (if NULL, uses /etc/services)
|
||||||
* @return -1 on error, or positive port number
|
* @return -1 on error, or positive port number
|
||||||
* @note aliases are read from file for comparison, but not returned.
|
* @note aliases are read from file for comparison, but not returned.
|
||||||
|
@ -54,29 +54,23 @@
|
||||||
*/
|
*/
|
||||||
int LookupServicesByName(const char *servname, char *servproto,
|
int LookupServicesByName(const char *servname, char *servproto,
|
||||||
size_t servprotolen, char *buf, size_t bufsize,
|
size_t servprotolen, char *buf, size_t bufsize,
|
||||||
const char *filepath) {
|
const char *path) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *line;
|
char *line;
|
||||||
const char *path;
|
|
||||||
size_t linesize;
|
size_t linesize;
|
||||||
|
char pathbuf[256];
|
||||||
int found, result;
|
int found, result;
|
||||||
char pathbuf[PATH_MAX];
|
|
||||||
char *name, *port, *proto, *alias, *comment, *tok;
|
char *name, *port, *proto, *alias, *comment, *tok;
|
||||||
if (!(path = filepath)) {
|
if (servprotolen == 0 ||
|
||||||
path = "/etc/services";
|
!(f = fopen(path ? path : GetServicesTxtPath(pathbuf, sizeof(pathbuf)),
|
||||||
if (IsWindows()) {
|
"r"))) {
|
||||||
path =
|
|
||||||
firstnonnull(GetNtServicesTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (servprotolen == 0 || !(f = fopen(path, "r"))) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
line = NULL;
|
line = NULL;
|
||||||
linesize = 0;
|
linesize = 0;
|
||||||
found = 0;
|
found = 0;
|
||||||
result = -1;
|
result = -1;
|
||||||
if (buf && bufsize != 0) strcpy(buf, "");
|
if (bufsize) strcpy(buf, "");
|
||||||
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
|
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
|
||||||
if ((comment = strchr(line, '#'))) *comment = '\0';
|
if ((comment = strchr(line, '#'))) *comment = '\0';
|
||||||
name = strtok_r(line, " \t\r\n\v", &tok);
|
name = strtok_r(line, " \t\r\n\v", &tok);
|
||||||
|
@ -93,8 +87,8 @@ int LookupServicesByName(const char *servname, char *servproto,
|
||||||
strcpy(servproto, "");
|
strcpy(servproto, "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (buf && bufsize != 0 && !memccpy(buf, name, '\0', bufsize)) {
|
if (bufsize && !memccpy(buf, name, '\0', bufsize)) {
|
||||||
strcpy(buf, "");
|
*buf = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result = atoi(port);
|
result = atoi(port);
|
||||||
|
|
|
@ -52,36 +52,30 @@
|
||||||
* @param servprotolen the size of servproto
|
* @param servprotolen the size of servproto
|
||||||
* @param buf is a buffer to store the official name of the service
|
* @param buf is a buffer to store the official name of the service
|
||||||
* @param bufsize is the size of buf
|
* @param bufsize is the size of buf
|
||||||
* @param filepath is the location of the services file
|
* @param path is the location of the services file, which may be NULL
|
||||||
* (if NULL, uses /etc/services)
|
* to use the system-wide default
|
||||||
* @return 0 on success, -1 on error
|
* @return 0 on success, -1 on error
|
||||||
* @note aliases are not read from the file.
|
* @note aliases are not read from the file.
|
||||||
*/
|
*/
|
||||||
int LookupServicesByPort(const int servport, char *servproto,
|
int LookupServicesByPort(const int servport, char *servproto,
|
||||||
size_t servprotolen, char *buf, size_t bufsize,
|
size_t servprotolen, char *buf, size_t bufsize,
|
||||||
const char *filepath) {
|
const char *path) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *line;
|
|
||||||
char pathbuf[PATH_MAX];
|
|
||||||
const char *path;
|
|
||||||
size_t linesize;
|
|
||||||
int found;
|
int found;
|
||||||
|
char *line;
|
||||||
|
size_t linesize;
|
||||||
|
char pathbuf[256];
|
||||||
char *name, *port, *proto, *comment, *tok;
|
char *name, *port, *proto, *comment, *tok;
|
||||||
if (!(path = filepath)) {
|
if (!servprotolen ||
|
||||||
path = "/etc/services";
|
!(f = fopen(path ? path : GetServicesTxtPath(pathbuf, sizeof(pathbuf)),
|
||||||
if (IsWindows()) {
|
"r"))) {
|
||||||
path =
|
|
||||||
firstnonnull(GetNtServicesTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (servprotolen == 0 || bufsize == 0 || !(f = fopen(path, "r"))) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
found = 0;
|
||||||
line = NULL;
|
line = NULL;
|
||||||
linesize = 0;
|
linesize = 0;
|
||||||
found = 0;
|
if (bufsize) *buf = 0;
|
||||||
strcpy(buf, "");
|
while (!found && (getline(&line, &linesize, f)) != -1) {
|
||||||
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
|
|
||||||
if ((comment = strchr(line, '#'))) *comment = '\0';
|
if ((comment = strchr(line, '#'))) *comment = '\0';
|
||||||
name = strtok_r(line, " \t\r\n\v", &tok);
|
name = strtok_r(line, " \t\r\n\v", &tok);
|
||||||
port = strtok_r(NULL, "/ \t\r\n\v", &tok);
|
port = strtok_r(NULL, "/ \t\r\n\v", &tok);
|
||||||
|
@ -93,7 +87,9 @@ int LookupServicesByPort(const int servport, char *servproto,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!memccpy(buf, name, '\0', bufsize)) {
|
if (!memccpy(buf, name, '\0', bufsize)) {
|
||||||
strcpy(buf, "");
|
if (bufsize) {
|
||||||
|
*buf = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
found = 1;
|
found = 1;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
|
|
||||||
#define SIZE ROUNDUP(sizeof(struct addrinfo), sizeof(void *))
|
#define SIZE sizeof(struct addrinfo)
|
||||||
#define ADDRLEN sizeof(struct sockaddr_in)
|
#define ADDRLEN sizeof(struct sockaddr_in)
|
||||||
|
|
||||||
struct addrinfo *newaddrinfo(uint16_t port) {
|
struct addrinfo *newaddrinfo(uint16_t port) {
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
const char *GetProtocolsTxtPath(char *, size_t);
|
||||||
|
|
||||||
int LookupProtoByNumber(const int, char *, size_t, const char *)
|
int LookupProtoByNumber(const int, char *, size_t, const char *)
|
||||||
paramsnonnull((2));
|
paramsnonnull((2));
|
||||||
int LookupProtoByName(const char *, char *, size_t, const char *)
|
int LookupProtoByName(const char *, char *, size_t, const char *)
|
||||||
paramsnonnull((1, 2));
|
paramsnonnull((1, 2));
|
||||||
char *GetNtProtocolsTxtPath(char *, uint32_t);
|
|
||||||
|
|
||||||
/* TODO: implement like struct HostsTxt? */
|
/* TODO: implement like struct HostsTxt? */
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ int ResolveHostsReverse(const struct HostsTxt *ht, int af, const uint8_t *ip,
|
||||||
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
||||||
for (i = 0; i < ht->entries.i; ++i) {
|
for (i = 0; i < ht->entries.i; ++i) {
|
||||||
if (READ32LE(ip) == READ32LE(ht->entries.p[i].ip)) {
|
if (READ32LE(ip) == READ32LE(ht->entries.p[i].ip)) {
|
||||||
if (memccpy(buf, ht->strings.p + ht->entries.p[i].name, '\0', bufsize)) {
|
if (memccpy(buf, ht->strings.p + ht->entries.p[i].name, 0, bufsize)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
char *GetSystemDirectoryPath(char *, size_t, const char *);
|
||||||
int LookupServicesByPort(const int, char *, size_t, char *, size_t,
|
int LookupServicesByPort(const int, char *, size_t, char *, size_t,
|
||||||
const char *) paramsnonnull((2, 4));
|
const char *) paramsnonnull((2, 4));
|
||||||
int LookupServicesByName(const char *, char *, size_t, char *, size_t,
|
int LookupServicesByName(const char *, char *, size_t, char *, size_t,
|
||||||
const char *) paramsnonnull((1, 2));
|
const char *) paramsnonnull((1, 2));
|
||||||
char *GetNtServicesTxtPath(char *, uint32_t);
|
const char *GetServicesTxtPath(char *, size_t);
|
||||||
|
|
||||||
/* TODO: implement like struct HostsTxt? */
|
/* TODO: implement like struct HostsTxt? */
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,7 @@
|
||||||
/*
|
#ifndef COSMOPOLITAN_LIBC_STDCKDINT_H_
|
||||||
* Copyright 2023 Justine Alexandra Roberts Tunney
|
#define COSMOPOLITAN_LIBC_STDCKDINT_H_
|
||||||
*
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
/* clang-format off */
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview C23 Checked Arithmetic
|
* @fileoverview C23 Checked Arithmetic
|
||||||
|
@ -54,16 +42,6 @@
|
||||||
* @version 0.1 (2023-07-22)
|
* @version 0.1 (2023-07-22)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef JTCKDINT_H_
|
|
||||||
#define JTCKDINT_H_
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
#ifdef __has_include
|
|
||||||
#define __ckd_has_include(x) __has_include(x)
|
|
||||||
#else
|
|
||||||
#define __ckd_has_include(x) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define __STDC_VERSION_STDCKDINT_H__ 202311L
|
#define __STDC_VERSION_STDCKDINT_H__ 202311L
|
||||||
|
|
||||||
#if ((defined(__llvm__) || \
|
#if ((defined(__llvm__) || \
|
||||||
|
@ -81,18 +59,12 @@
|
||||||
typedef signed __ckd_intmax __ckd_intmax_t;
|
typedef signed __ckd_intmax __ckd_intmax_t;
|
||||||
typedef unsigned __ckd_intmax __ckd_uintmax_t;
|
typedef unsigned __ckd_intmax __ckd_uintmax_t;
|
||||||
|
|
||||||
#ifdef __has_builtin
|
#if (!defined(__STRICT_ANSI__) && \
|
||||||
#define __ckd_has_builtin(x) __has_builtin(x)
|
((defined(__GNUC__) && __GNUC__ >= 5 && \
|
||||||
#else
|
!defined(__chibicc__) && !defined(__ICC)) || \
|
||||||
#define __ckd_has_builtin(x) 0
|
(__has_builtin(__builtin_add_overflow) && \
|
||||||
#endif
|
__has_builtin(__builtin_sub_overflow) && \
|
||||||
|
__has_builtin(__builtin_mul_overflow))))
|
||||||
#if (!defined(__STRICT_ANSI__) && \
|
|
||||||
((defined(__GNUC__) && __GNUC__ >= 5 && \
|
|
||||||
!defined(__chibicc__) && !defined(__ICC)) || \
|
|
||||||
(__ckd_has_builtin(__builtin_add_overflow) && \
|
|
||||||
__ckd_has_builtin(__builtin_sub_overflow) && \
|
|
||||||
__ckd_has_builtin(__builtin_mul_overflow))))
|
|
||||||
#define ckd_add(res, x, y) __builtin_add_overflow((x), (y), (res))
|
#define ckd_add(res, x, y) __builtin_add_overflow((x), (y), (res))
|
||||||
#define ckd_sub(res, x, y) __builtin_sub_overflow((x), (y), (res))
|
#define ckd_sub(res, x, y) __builtin_sub_overflow((x), (y), (res))
|
||||||
#define ckd_mul(res, x, y) __builtin_mul_overflow((x), (y), (res))
|
#define ckd_mul(res, x, y) __builtin_mul_overflow((x), (y), (res))
|
||||||
|
@ -653,4 +625,5 @@ __ckd_declare_mul(__ckd_mul_uint128, unsigned __int128)
|
||||||
#define ckd_mul(res, x, y) (*(res) = (x) * (y), 0)
|
#define ckd_mul(res, x, y) (*(res) = (x) * (y), 0)
|
||||||
|
|
||||||
#endif /* GNU */
|
#endif /* GNU */
|
||||||
#endif /* JTCKDINT_H_ */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_STDCKDINT_H_ */
|
||||||
|
|
|
@ -47,7 +47,7 @@ int fclose(FILE *f) {
|
||||||
f->state = EOF;
|
f->state = EOF;
|
||||||
if (f->noclose) {
|
if (f->noclose) {
|
||||||
f->fd = -1;
|
f->fd = -1;
|
||||||
} else if (close(f->fd) == -1) {
|
} else if (f->fd != -1 && close(f->fd) == -1) {
|
||||||
f->state = errno;
|
f->state = errno;
|
||||||
}
|
}
|
||||||
if (f->state == EOF) {
|
if (f->state == EOF) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
/*-*- 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│
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
@ -16,11 +16,16 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/struct/timeval.h"
|
#include "libc/fmt/conv.h"
|
||||||
|
#include "third_party/gdtoa/gdtoa.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Coerces `tv` from 1e-6 to 1e-9 granularity.
|
* Converts string to long double.
|
||||||
*/
|
*/
|
||||||
struct timespec timeval_totimespec(struct timeval tv) {
|
long double strtold(const char *s, char **endptr) {
|
||||||
return (struct timespec){tv.tv_sec, tv.tv_usec * 1000};
|
long double x;
|
||||||
|
strtorx(s, endptr, FPI_Round_near, &x);
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__weak_reference(strtold, strtold_l);
|
|
@ -71,8 +71,8 @@ int system(const char *cmdline) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sigaction(SIGINT, &saveint, 0);
|
|
||||||
sigaction(SIGQUIT, &savequit, 0);
|
sigaction(SIGQUIT, &savequit, 0);
|
||||||
|
sigaction(SIGINT, &saveint, 0);
|
||||||
}
|
}
|
||||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||||
ALLOW_CANCELLATIONS;
|
ALLOW_CANCELLATIONS;
|
||||||
|
|
|
@ -46,11 +46,11 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
void *memccpy(void *dst, const void *src, int c, size_t n) {
|
void *memccpy(void *dst, const void *src, int c, size_t n) {
|
||||||
|
char *d;
|
||||||
size_t i;
|
size_t i;
|
||||||
unsigned char *d;
|
const char *s;
|
||||||
const unsigned char *s;
|
|
||||||
for (d = dst, s = src, i = 0; i < n; ++i) {
|
for (d = dst, s = src, i = 0; i < n; ++i) {
|
||||||
if ((d[i] = s[i]) == (c & 255)) {
|
if (((d[i] = s[i]) & 255) == (c & 255)) {
|
||||||
return d + i + 1;
|
return d + i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,27 +16,30 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares static search buffer.
|
* Prepares static search buffer.
|
||||||
*
|
*
|
||||||
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
|
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
|
||||||
*
|
|
||||||
* 2. If SRC is too short, the remainder is zero-filled.
|
* 2. If SRC is too short, the remainder is zero-filled.
|
||||||
*
|
*
|
||||||
* Please note this function isn't designed to prevent untrustworthy
|
* @param dst is output buffer
|
||||||
* data from modifying memory without authorization. Consider trying
|
* @param src is a nul-terminated string
|
||||||
* memccpy() for that purpose.
|
* @param dstlen is size of `dst` buffer
|
||||||
*
|
* @return pointer to first nul-terminator, otherwise dest + stride
|
||||||
* @return dest + stride
|
|
||||||
* @see stncpy(), memccpy()
|
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
|
* @see strncpy()
|
||||||
|
* @see memccpy()
|
||||||
|
* @see strlcpy()
|
||||||
*/
|
*/
|
||||||
char *stpncpy(char *dest, const char *src, size_t stride) {
|
char *stpncpy(char *dst, const char *src, size_t dstlen) {
|
||||||
char *p;
|
size_t srclen, cpylen, zerlen;
|
||||||
if ((p = memccpy(dest, src, '\0', stride))) {
|
srclen = strlen(src);
|
||||||
bzero(p, dest + stride - p);
|
cpylen = MIN(srclen, dstlen);
|
||||||
}
|
if (cpylen) memcpy(dst, src, cpylen);
|
||||||
return dest + stride;
|
zerlen = dstlen - cpylen;
|
||||||
|
if (zerlen) bzero(dst + cpylen, zerlen);
|
||||||
|
return dst + cpylen;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,14 @@
|
||||||
* @param 𝑛 is maximum number of characters from s to copy
|
* @param 𝑛 is maximum number of characters from s to copy
|
||||||
* @return 𝑑
|
* @return 𝑑
|
||||||
* @note 𝑑 and 𝑠 can't overlap
|
* @note 𝑑 and 𝑠 can't overlap
|
||||||
* @asyncsignaslenafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
char *strncat(char *d, const char *s, size_t n) {
|
char *strncat(char *d, const char *s, size_t n) {
|
||||||
size_t o;
|
size_t dn, sn;
|
||||||
if (!memccpy(d + (o = strlen(d)), s, '\0', n)) {
|
if ((sn = strnlen(s, n))) {
|
||||||
d[o + n] = '\0';
|
dn = strlen(d);
|
||||||
|
memcpy(d + dn, s, sn);
|
||||||
|
d[dn + sn] = 0;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,16 +25,21 @@
|
||||||
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
|
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
|
||||||
* 2. If SRC is too short, the remainder is zero-filled.
|
* 2. If SRC is too short, the remainder is zero-filled.
|
||||||
*
|
*
|
||||||
* @return dest
|
* @param dst is output buffer
|
||||||
* @see stpncpy(), memccpy()
|
* @param src is a nul-terminated string
|
||||||
|
* @param dstlen is size of `dst` buffer
|
||||||
|
* @return dst
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
* @vforksafe
|
* @see stpncpy()
|
||||||
|
* @see strlcpy()
|
||||||
|
* @see memccpy()
|
||||||
*/
|
*/
|
||||||
char *strncpy(char *dest, const char *src, size_t stride) {
|
char *strncpy(char *dst, const char *src, size_t dstlen) {
|
||||||
size_t i;
|
size_t srclen, cpylen, zerlen;
|
||||||
for (i = 0; i < stride; ++i) {
|
srclen = strlen(src);
|
||||||
if (!(dest[i] = src[i])) break;
|
cpylen = MIN(srclen, dstlen);
|
||||||
}
|
if (cpylen) memcpy(dst, src, cpylen);
|
||||||
bzero(dest + i, stride - i);
|
zerlen = dstlen - cpylen;
|
||||||
return dest;
|
if (zerlen) bzero(dst + cpylen, zerlen);
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,64 +28,26 @@
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/thread/spawn.h"
|
#include "libc/thread/spawn.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
TEST(raise, trap) {
|
||||||
// SIGTRAP
|
|
||||||
|
|
||||||
TEST(raise, trap_sysv) {
|
|
||||||
if (IsWindows()) return;
|
|
||||||
signal(SIGTRAP, SIG_DFL);
|
signal(SIGTRAP, SIG_DFL);
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
raise(SIGTRAP);
|
raise(SIGTRAP);
|
||||||
TERMS(SIGTRAP);
|
TERMS(SIGTRAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(raise, trap_windows) {
|
TEST(raise, fpe) {
|
||||||
if (!IsWindows()) return;
|
|
||||||
signal(SIGTRAP, SIG_DFL);
|
|
||||||
SPAWN(fork);
|
|
||||||
raise(SIGTRAP);
|
|
||||||
EXITS(128 + SIGTRAP);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// SIGFPE
|
|
||||||
|
|
||||||
TEST(raise, fpe_sysv) {
|
|
||||||
if (IsWindows()) return;
|
|
||||||
signal(SIGFPE, SIG_DFL);
|
signal(SIGFPE, SIG_DFL);
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
raise(SIGFPE);
|
raise(SIGFPE);
|
||||||
TERMS(SIGFPE);
|
TERMS(SIGFPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(raise, fpe_windows) {
|
TEST(raise, usr1) {
|
||||||
if (!IsWindows()) return;
|
|
||||||
signal(SIGFPE, SIG_DFL);
|
|
||||||
SPAWN(fork);
|
|
||||||
raise(SIGFPE);
|
|
||||||
EXITS(128 + SIGFPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// SIGUSR1
|
|
||||||
|
|
||||||
TEST(raise, usr1_sysv) {
|
|
||||||
if (IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
raise(SIGUSR1);
|
raise(SIGUSR1);
|
||||||
TERMS(SIGUSR1);
|
TERMS(SIGUSR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(raise, usr1_windows) {
|
|
||||||
if (!IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
|
||||||
raise(SIGUSR1);
|
|
||||||
EXITS(128 + SIGUSR1);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// THREADS
|
|
||||||
|
|
||||||
int threadid;
|
int threadid;
|
||||||
|
|
||||||
void WorkerQuit(int sig, siginfo_t *si, void *ctx) {
|
void WorkerQuit(int sig, siginfo_t *si, void *ctx) {
|
||||||
|
|
|
@ -25,10 +25,10 @@
|
||||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
│ │
|
│ │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/dns/servicestxt.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dns/dns.h"
|
#include "libc/dns/dns.h"
|
||||||
#include "libc/dns/ent.h"
|
#include "libc/dns/ent.h"
|
||||||
#include "libc/dns/servicestxt.h"
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
@ -137,8 +137,8 @@ TEST(LookupServicesByName, GetPortWhenNameOrAlias) {
|
||||||
|
|
||||||
localproto = proto2;
|
localproto = proto2;
|
||||||
ASSERT_EQ(-1, /* protocol is non-NULL/length must be nonzero */
|
ASSERT_EQ(-1, /* protocol is non-NULL/length must be nonzero */
|
||||||
LookupServicesByName("ssh", localproto, 0, name, sizeof(name),
|
LookupServicesByName("ssh", localproto, sizeof(proto2), name,
|
||||||
"services"));
|
sizeof(name), "services"));
|
||||||
ASSERT_STREQ(proto2, "udp");
|
ASSERT_STREQ(proto2, "udp");
|
||||||
|
|
||||||
localproto = proto1;
|
localproto = proto1;
|
||||||
|
|
|
@ -19,33 +19,20 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/calls/struct/sigset.h"
|
#include "libc/calls/struct/sigset.h"
|
||||||
#include "libc/dce.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/testlib/subprocess.h"
|
#include "libc/testlib/subprocess.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
TEST(abort, sysv) {
|
TEST(abort, test) {
|
||||||
if (IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
||||||
abort();
|
abort();
|
||||||
TERMS(SIGABRT);
|
TERMS(SIGABRT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(abort, windows) {
|
TEST(abort, blocked_stillTerminates) {
|
||||||
if (!IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
|
||||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
|
||||||
abort();
|
|
||||||
EXITS(128 + SIGABRT);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TEST(abort, blocked_stillTerminates_sysv) {
|
|
||||||
sigset_t ss;
|
sigset_t ss;
|
||||||
if (IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
||||||
sigfillset(&ss);
|
sigfillset(&ss);
|
||||||
|
@ -54,52 +41,19 @@ TEST(abort, blocked_stillTerminates_sysv) {
|
||||||
TERMS(SIGABRT);
|
TERMS(SIGABRT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(abort, blocked_stillTerminates_windows) {
|
TEST(abort, ign_stillTerminates) {
|
||||||
sigset_t ss;
|
|
||||||
if (!IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
|
||||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
|
||||||
sigfillset(&ss);
|
|
||||||
sigprocmask(SIG_SETMASK, &ss, 0);
|
|
||||||
abort();
|
|
||||||
EXITS(128 + SIGABRT);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TEST(abort, ign_stillTerminates_sysv) {
|
|
||||||
if (IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_IGN));
|
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_IGN));
|
||||||
abort();
|
abort();
|
||||||
TERMS(SIGABRT);
|
TERMS(SIGABRT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(abort, ign_stillTerminates_windows) {
|
|
||||||
if (!IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
|
||||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_IGN));
|
|
||||||
abort();
|
|
||||||
EXITS(128 + SIGABRT);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void Ignore(int sig) {
|
void Ignore(int sig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(abort, handled_stillTerminates_sysv) {
|
TEST(abort, handled_stillTerminates) {
|
||||||
if (IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, Ignore));
|
ASSERT_NE(SIG_ERR, signal(SIGABRT, Ignore));
|
||||||
abort();
|
abort();
|
||||||
TERMS(SIGABRT);
|
TERMS(SIGABRT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(abort, handled_stillTerminates_windows) {
|
|
||||||
if (!IsWindows()) return;
|
|
||||||
SPAWN(fork);
|
|
||||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, Ignore));
|
|
||||||
abort();
|
|
||||||
EXITS(128 + SIGABRT);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
/*-*- 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│
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
@ -16,24 +16,13 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/thread/thread.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/gdtoa/lock.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
static pthread_mutex_t __gdtoa_lock_obj;
|
TEST(strncat, test) {
|
||||||
static pthread_mutex_t __gdtoa_lock1_obj;
|
char buf[32] = "foo";
|
||||||
|
EXPECT_STREQ("foobar", strncat(buf, "bar", 3));
|
||||||
int(__gdtoa_lock)(void) {
|
EXPECT_STREQ("foobarbar", strncat(buf, "bar", 10));
|
||||||
return pthread_mutex_lock(&__gdtoa_lock_obj);
|
EXPECT_STREQ("foobarbarb", strncat(buf, "bar", 1));
|
||||||
}
|
EXPECT_STREQ("foobarbarb", strncat(buf, "", 1));
|
||||||
|
|
||||||
int(__gdtoa_unlock)(void) {
|
|
||||||
return pthread_mutex_unlock(&__gdtoa_lock_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
int(__gdtoa_lock1)(void) {
|
|
||||||
return pthread_mutex_lock(&__gdtoa_lock1_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
int(__gdtoa_unlock1)(void) {
|
|
||||||
return pthread_mutex_unlock(&__gdtoa_lock1_obj);
|
|
||||||
}
|
}
|
27
third_party/gdtoa/lock.h
vendored
27
third_party/gdtoa/lock.h
vendored
|
@ -1,27 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_THIRD_PARTY_GDTOA_LOCK_H_
|
|
||||||
#define COSMOPOLITAN_THIRD_PARTY_GDTOA_LOCK_H_
|
|
||||||
#include "libc/intrin/nopl.internal.h"
|
|
||||||
#include "libc/thread/tls.h"
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
||||||
COSMOPOLITAN_C_START_
|
|
||||||
|
|
||||||
int __gdtoa_lock(void);
|
|
||||||
int __gdtoa_unlock(void);
|
|
||||||
int __gdtoa_lock1(void);
|
|
||||||
int __gdtoa_unlock1(void);
|
|
||||||
|
|
||||||
#ifdef _NOPL0
|
|
||||||
#define __gdtoa_lock() _NOPL0("__threadcalls", __gdtoa_lock)
|
|
||||||
#define __gdtoa_unlock() _NOPL0("__threadcalls", __gdtoa_unlock)
|
|
||||||
#define __gdtoa_lock1() _NOPL0("__threadcalls", __gdtoa_lock1)
|
|
||||||
#define __gdtoa_unlock1() _NOPL0("__threadcalls", __gdtoa_unlock1)
|
|
||||||
#else
|
|
||||||
#define __gdtoa_lock() (__threaded ? __gdtoa_lock() : 0)
|
|
||||||
#define __gdtoa_unlock() (__threaded ? __gdtoa_unlock() : 0)
|
|
||||||
#define __gdtoa_lock1() (__threaded ? __gdtoa_lock1() : 0)
|
|
||||||
#define __gdtoa_unlock1() (__threaded ? __gdtoa_unlock1() : 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
||||||
#endif /* COSMOPOLITAN_THIRD_PARTY_GDTOA_LOCK_H_ */
|
|
53
third_party/gdtoa/misc.c
vendored
53
third_party/gdtoa/misc.c
vendored
|
@ -32,11 +32,58 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/thread/thread.h"
|
||||||
|
#include "libc/thread/tls.h"
|
||||||
#include "third_party/gdtoa/gdtoa.internal.h"
|
#include "third_party/gdtoa/gdtoa.internal.h"
|
||||||
#include "third_party/gdtoa/lock.h"
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static ThInfo TI0;
|
static ThInfo TI0;
|
||||||
|
static pthread_mutex_t __gdtoa_lock_obj;
|
||||||
|
static pthread_mutex_t __gdtoa_lock1_obj;
|
||||||
|
|
||||||
|
static void
|
||||||
|
__gdtoa_lock(void)
|
||||||
|
{
|
||||||
|
if (!__threaded)
|
||||||
|
return;
|
||||||
|
pthread_mutex_lock(&__gdtoa_lock_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__gdtoa_unlock(void)
|
||||||
|
{
|
||||||
|
if (!__threaded)
|
||||||
|
return;
|
||||||
|
pthread_mutex_unlock(&__gdtoa_lock_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__gdtoa_initlock(void)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(&__gdtoa_lock_obj, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__gdtoa_lock1(void)
|
||||||
|
{
|
||||||
|
if (!__threaded)
|
||||||
|
return;
|
||||||
|
pthread_mutex_lock(&__gdtoa_lock1_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__gdtoa_unlock1(void)
|
||||||
|
{
|
||||||
|
if (!__threaded)
|
||||||
|
return;
|
||||||
|
pthread_mutex_unlock(&__gdtoa_lock1_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__gdtoa_initlock1(void)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(&__gdtoa_lock1_obj, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__gdtoa_Brelease(Bigint *rv)
|
__gdtoa_Brelease(Bigint *rv)
|
||||||
|
@ -63,7 +110,11 @@ __gdtoa_Bclear(void)
|
||||||
__attribute__((__constructor__)) static void
|
__attribute__((__constructor__)) static void
|
||||||
__gdtoa_Binit(void)
|
__gdtoa_Binit(void)
|
||||||
{
|
{
|
||||||
|
__gdtoa_initlock();
|
||||||
|
__gdtoa_initlock1();
|
||||||
atexit(__gdtoa_Bclear);
|
atexit(__gdtoa_Bclear);
|
||||||
|
pthread_atfork(__gdtoa_lock1, __gdtoa_unlock1, __gdtoa_initlock1);
|
||||||
|
pthread_atfork(__gdtoa_lock, __gdtoa_unlock, __gdtoa_initlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ThInfo *
|
static ThInfo *
|
||||||
|
|
44
third_party/gdtoa/strtold.c
vendored
44
third_party/gdtoa/strtold.c
vendored
|
@ -1,44 +0,0 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
|
||||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
|
||||||
│ │
|
|
||||||
│ The author of this software is David M. Gay. │
|
|
||||||
│ Please send bug reports to David M. Gay <dmg@acm.org> │
|
|
||||||
│ or Justine Tunney <jtunney@gmail.com> │
|
|
||||||
│ │
|
|
||||||
│ Copyright (C) 1998, 1999 by Lucent Technologies │
|
|
||||||
│ All Rights Reserved │
|
|
||||||
│ │
|
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
|
||||||
│ copies and that both that the copyright notice and this │
|
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
|
||||||
│ documentation, and that the name of Lucent or any of its entities │
|
|
||||||
│ not be used in advertising or publicity pertaining to │
|
|
||||||
│ distribution of the software without specific, written prior │
|
|
||||||
│ permission. │
|
|
||||||
│ │
|
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
|
||||||
│ SPECIAL, 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/conv.h"
|
|
||||||
#include "third_party/gdtoa/gdtoa.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts string to long double.
|
|
||||||
*/
|
|
||||||
long double strtold(const char *s, char **endptr) {
|
|
||||||
long double x;
|
|
||||||
strtorx(s, endptr, FPI_Round_near, &x);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
__weak_reference(strtold, strtold_l);
|
|
1
third_party/lua/lunix.c
vendored
1
third_party/lua/lunix.c
vendored
|
@ -38,6 +38,7 @@
|
||||||
#include "libc/calls/struct/timeval.h"
|
#include "libc/calls/struct/timeval.h"
|
||||||
#include "libc/calls/struct/winsize.h"
|
#include "libc/calls/struct/winsize.h"
|
||||||
#include "libc/calls/ucontext.h"
|
#include "libc/calls/ucontext.h"
|
||||||
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/dns/dns.h"
|
#include "libc/dns/dns.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
|
3
third_party/mbedtls/net_sockets.c
vendored
3
third_party/mbedtls/net_sockets.c
vendored
|
@ -15,8 +15,10 @@
|
||||||
│ See the License for the specific language governing permissions and │
|
│ See the License for the specific language governing permissions and │
|
||||||
│ limitations under the License. │
|
│ limitations under the License. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "third_party/mbedtls/net_sockets.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/dns/dns.h"
|
#include "libc/dns/dns.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/sock/select.h"
|
#include "libc/sock/select.h"
|
||||||
|
@ -31,7 +33,6 @@
|
||||||
#include "libc/sysv/consts/sock.h"
|
#include "libc/sysv/consts/sock.h"
|
||||||
#include "libc/sysv/consts/sol.h"
|
#include "libc/sysv/consts/sol.h"
|
||||||
#include "third_party/mbedtls/error.h"
|
#include "third_party/mbedtls/error.h"
|
||||||
#include "third_party/mbedtls/net_sockets.h"
|
|
||||||
#include "third_party/mbedtls/ssl.h"
|
#include "third_party/mbedtls/ssl.h"
|
||||||
|
|
||||||
#define IS_EINTR(ret) ((ret) == EINTR)
|
#define IS_EINTR(ret) ((ret) == EINTR)
|
||||||
|
|
1
third_party/mbedtls/test/lib.c
vendored
1
third_party/mbedtls/test/lib.c
vendored
|
@ -97,6 +97,7 @@ void mbedtls_test_platform_teardown(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wontreturn void exit(int rc) {
|
wontreturn void exit(int rc) {
|
||||||
|
if (rc) fprintf(stderr, "mbedtls test exit() called with %d\n", rc);
|
||||||
if (rc) xwrite(1, output, appendz(output).i);
|
if (rc) xwrite(1, output, appendz(output).i);
|
||||||
free(output);
|
free(output);
|
||||||
output = 0;
|
output = 0;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
|
#include "libc/calls/struct/timespec.h"
|
||||||
#include "libc/calls/struct/timeval.h"
|
#include "libc/calls/struct/timeval.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
@ -97,7 +98,7 @@
|
||||||
* - 1 byte exit status
|
* - 1 byte exit status
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DEATH_CLOCK_SECONDS 128
|
#define DEATH_CLOCK_SECONDS 300
|
||||||
|
|
||||||
#define kLogFile "o/runitd.log"
|
#define kLogFile "o/runitd.log"
|
||||||
#define kLogMaxBytes (2 * 1000 * 1000)
|
#define kLogMaxBytes (2 * 1000 * 1000)
|
||||||
|
@ -123,7 +124,6 @@ void OnChildTerminated(int sig) {
|
||||||
sigdelset(&ss, SIGTERM);
|
sigdelset(&ss, SIGTERM);
|
||||||
sigprocmask(SIG_BLOCK, &ss, &oldss);
|
sigprocmask(SIG_BLOCK, &ss, &oldss);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
INFOF("waitpid");
|
|
||||||
if ((pid = waitpid(-1, &ws, WNOHANG)) != -1) {
|
if ((pid = waitpid(-1, &ws, WNOHANG)) != -1) {
|
||||||
if (pid) {
|
if (pid) {
|
||||||
if (WIFEXITED(ws)) {
|
if (WIFEXITED(ws)) {
|
||||||
|
@ -364,13 +364,12 @@ void HandleClient(void) {
|
||||||
const size_t kMaxNameSize = 128;
|
const size_t kMaxNameSize = 128;
|
||||||
const size_t kMaxFileSize = 10 * 1024 * 1024;
|
const size_t kMaxFileSize = 10 * 1024 * 1024;
|
||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
|
sigset_t sigmask;
|
||||||
ssize_t got, wrote;
|
ssize_t got, wrote;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
long double now, deadline;
|
struct timespec now, deadline;
|
||||||
sigset_t chldmask, savemask;
|
|
||||||
char *addrstr, *exename, *exe;
|
char *addrstr, *exename, *exe;
|
||||||
unsigned char msg[4 + 1 + 4 + 4 + 4];
|
unsigned char msg[4 + 1 + 4 + 4 + 4];
|
||||||
struct sigaction ignore, saveint, savequit;
|
|
||||||
uint32_t addrsize, namesize, filesize, remaining;
|
uint32_t addrsize, namesize, filesize, remaining;
|
||||||
int rc, events, exitcode, wstatus, child, pipefds[2];
|
int rc, events, exitcode, wstatus, child, pipefds[2];
|
||||||
|
|
||||||
|
@ -411,29 +410,24 @@ void HandleClient(void) {
|
||||||
}
|
}
|
||||||
CHECK_NE(-1, (g_exefd = creat(g_exepath, 0700)));
|
CHECK_NE(-1, (g_exefd = creat(g_exepath, 0700)));
|
||||||
LOGIFNEG1(ftruncate(g_exefd, filesize));
|
LOGIFNEG1(ftruncate(g_exefd, filesize));
|
||||||
INFOF("xwrite");
|
|
||||||
CHECK_NE(-1, xwrite(g_exefd, exe, filesize));
|
CHECK_NE(-1, xwrite(g_exefd, exe, filesize));
|
||||||
LOGIFNEG1(close(g_exefd));
|
LOGIFNEG1(close(g_exefd));
|
||||||
|
|
||||||
/* run program, tee'ing stderr to both log and client */
|
/* run program, tee'ing stderr to both log and client */
|
||||||
DEBUGF("spawning %s", exename);
|
DEBUGF("spawning %s", exename);
|
||||||
ignore.sa_flags = 0;
|
sigemptyset(&sigmask);
|
||||||
ignore.sa_handler = SIG_IGN;
|
sigaddset(&sigmask, SIGINT);
|
||||||
sigemptyset(&ignore.sa_mask);
|
sigaddset(&sigmask, SIGQUIT);
|
||||||
sigaction(SIGINT, &ignore, &saveint);
|
sigaddset(&sigmask, SIGCHLD);
|
||||||
sigaction(SIGQUIT, &ignore, &savequit);
|
sigprocmask(SIG_BLOCK, &sigmask, 0);
|
||||||
sigemptyset(&chldmask);
|
|
||||||
sigaddset(&chldmask, SIGCHLD);
|
|
||||||
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
|
||||||
CHECK_NE(-1, pipe2(pipefds, O_CLOEXEC));
|
CHECK_NE(-1, pipe2(pipefds, O_CLOEXEC));
|
||||||
CHECK_NE(-1, (child = fork()));
|
CHECK_NE(-1, (child = fork()));
|
||||||
if (!child) {
|
if (!child) {
|
||||||
dup2(g_bogusfd, 0);
|
dup2(g_bogusfd, 0);
|
||||||
dup2(pipefds[1], 1);
|
dup2(pipefds[1], 1);
|
||||||
dup2(pipefds[1], 2);
|
dup2(pipefds[1], 2);
|
||||||
sigaction(SIGINT, &(struct sigaction){0}, 0);
|
sigemptyset(&sigmask);
|
||||||
sigaction(SIGQUIT, &(struct sigaction){0}, 0);
|
sigprocmask(SIG_SETMASK, &sigmask, 0);
|
||||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
const char *exe;
|
const char *exe;
|
||||||
char *args[8] = {0};
|
char *args[8] = {0};
|
||||||
|
@ -451,13 +445,17 @@ void HandleClient(void) {
|
||||||
execvp(exe, args);
|
execvp(exe, args);
|
||||||
_Exit(127);
|
_Exit(127);
|
||||||
}
|
}
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
signal(SIGQUIT, SIG_IGN);
|
||||||
close(pipefds[1]);
|
close(pipefds[1]);
|
||||||
DEBUGF("communicating %s[%d]", exename, child);
|
DEBUGF("communicating %s[%d]", exename, child);
|
||||||
deadline = nowl() + DEATH_CLOCK_SECONDS;
|
deadline =
|
||||||
|
timespec_add(timespec_real(), timespec_fromseconds(DEATH_CLOCK_SECONDS));
|
||||||
for (;;) {
|
for (;;) {
|
||||||
now = nowl();
|
now = timespec_real();
|
||||||
if (now >= deadline) {
|
if (timespec_cmp(now, deadline) >= 0) {
|
||||||
WARNF("%s worker timed out", exename);
|
WARNF("%s worker timed out", exename);
|
||||||
|
TerminateJob:
|
||||||
LOGIFNEG1(kill(child, 9));
|
LOGIFNEG1(kill(child, 9));
|
||||||
LOGIFNEG1(waitpid(child, 0, 0));
|
LOGIFNEG1(waitpid(child, 0, 0));
|
||||||
LOGIFNEG1(close(g_clifd));
|
LOGIFNEG1(close(g_clifd));
|
||||||
|
@ -470,31 +468,31 @@ void HandleClient(void) {
|
||||||
fds[0].events = POLLIN;
|
fds[0].events = POLLIN;
|
||||||
fds[1].fd = pipefds[0];
|
fds[1].fd = pipefds[0];
|
||||||
fds[1].events = POLLIN;
|
fds[1].events = POLLIN;
|
||||||
INFOF("poll");
|
int waitms = timespec_tomillis(timespec_sub(deadline, now));
|
||||||
events = poll(fds, ARRAYLEN(fds), (deadline - now) * 1000);
|
INFOF("polling for %d ms", waitms);
|
||||||
|
events = poll(fds, ARRAYLEN(fds), waitms);
|
||||||
CHECK_NE(-1, events); // EINTR shouldn't be possible
|
CHECK_NE(-1, events); // EINTR shouldn't be possible
|
||||||
if (fds[0].revents) {
|
if (events) {
|
||||||
if (!(fds[0].revents & POLLHUP)) {
|
if (fds[0].revents) {
|
||||||
WARNF("%s got unexpected input event from client %#x", exename,
|
if (!(fds[0].revents & POLLHUP)) {
|
||||||
fds[0].revents);
|
WARNF("%s got unexpected input event from client %#x", exename,
|
||||||
|
fds[0].revents);
|
||||||
|
}
|
||||||
|
WARNF("%s client disconnected so killing worker %d", exename, child);
|
||||||
|
goto TerminateJob;
|
||||||
|
}
|
||||||
|
if (fds[1].revents) {
|
||||||
|
INFOF("read");
|
||||||
|
got = read(pipefds[0], g_buf, sizeof(g_buf));
|
||||||
|
CHECK_NE(-1, got); // EINTR shouldn't be possible
|
||||||
|
if (!got) {
|
||||||
|
LOGIFNEG1(close(pipefds[0]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fwrite(g_buf, got, 1, stderr);
|
||||||
|
SendOutputFragmentMessage(kRunitStderr, g_buf, got);
|
||||||
}
|
}
|
||||||
WARNF("%s client disconnected so killing worker %d", exename, child);
|
|
||||||
LOGIFNEG1(kill(child, 9));
|
|
||||||
LOGIFNEG1(waitpid(child, 0, 0));
|
|
||||||
LOGIFNEG1(close(g_clifd));
|
|
||||||
LOGIFNEG1(close(pipefds[0]));
|
|
||||||
LOGIFNEG1(unlink(g_exepath));
|
|
||||||
_exit(1);
|
|
||||||
}
|
}
|
||||||
INFOF("read");
|
|
||||||
got = read(pipefds[0], g_buf, sizeof(g_buf));
|
|
||||||
CHECK_NE(-1, got); // EINTR shouldn't be possible
|
|
||||||
if (!got) {
|
|
||||||
LOGIFNEG1(close(pipefds[0]));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fwrite(g_buf, got, 1, stderr);
|
|
||||||
SendOutputFragmentMessage(kRunitStderr, g_buf, got);
|
|
||||||
}
|
}
|
||||||
INFOF("waitpid");
|
INFOF("waitpid");
|
||||||
CHECK_NE(-1, waitpid(child, &wstatus, 0)); // EINTR shouldn't be possible
|
CHECK_NE(-1, waitpid(child, &wstatus, 0)); // EINTR shouldn't be possible
|
||||||
|
|
Loading…
Add table
Reference in a new issue