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
|
||||
else
|
||||
ARCH = x86_64
|
||||
HOSTS ?= freebsd openbsd openbsd73 netbsd rhel7 rhel5 xnu win10
|
||||
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10
|
||||
endif
|
||||
|
||||
ifeq ($(PREFIX),)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
│ SUCH DAMAGE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/bsd.h"
|
||||
|
|
|
@ -56,9 +56,7 @@
|
|||
*/
|
||||
int close(int fd) {
|
||||
int rc;
|
||||
if (fd == -1) {
|
||||
rc = 0;
|
||||
} else if (fd < 0) {
|
||||
if (fd < 0) {
|
||||
rc = ebadf();
|
||||
} else {
|
||||
// for performance reasons we want to avoid holding __fds_lock()
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/utsname-linux.internal.h"
|
||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
|
|
@ -84,7 +84,9 @@ static inline void GetProgramExecutableNameImpl(char *p, char *e) {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,9 @@ int timespec_sleep_until(struct timespec);
|
|||
struct timespec timespec_sub(struct timespec, struct timespec) pureconst;
|
||||
struct timespec timespec_subz(struct timespec, struct timespec) pureconst;
|
||||
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) {
|
||||
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_subz(struct timeval, struct timeval) 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) {
|
||||
return !(__tv.tv_sec | __tv.tv_usec);
|
||||
}
|
||||
|
|
|
@ -37,10 +37,8 @@ int utimes(const char *path, const struct timeval tv[2]) {
|
|||
int rc;
|
||||
struct timespec ts[2];
|
||||
if (tv) {
|
||||
ts[0].tv_sec = tv[0].tv_sec;
|
||||
ts[0].tv_nsec = tv[0].tv_usec * 1000;
|
||||
ts[1].tv_sec = tv[1].tv_sec;
|
||||
ts[1].tv_nsec = tv[1].tv_usec * 1000;
|
||||
ts[0] = timeval_totimespec(tv[0]);
|
||||
ts[1] = timeval_totimespec(tv[1]);
|
||||
rc = __utimens(AT_FDCWD, path, ts, 0);
|
||||
} else {
|
||||
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 int64_t fsfilcnt_t; /* uint32_t on xnu */
|
||||
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 uint16_t in_port_t;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_DNS_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_DNS_H_
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/struct/sockaddr.h"
|
||||
|
||||
#define DNS_PORT 53
|
||||
|
@ -67,8 +65,8 @@ struct addrinfo {
|
|||
int getaddrinfo(const char *, const char *, const struct addrinfo *,
|
||||
struct addrinfo **);
|
||||
void freeaddrinfo(struct addrinfo *);
|
||||
int getnameinfo(const struct sockaddr *, socklen_t, char *, socklen_t, char *,
|
||||
socklen_t, int);
|
||||
int getnameinfo(const struct sockaddr *, uint32_t, char *, uint32_t, char *,
|
||||
uint32_t, int);
|
||||
const char *gai_strerror(int);
|
||||
int CompareDnsNames(const char *, 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 *gethostbyname(const char *);
|
||||
struct hostent *gethostbyaddr(const void *, socklen_t, int);
|
||||
struct hostent *gethostbyaddr(const void *, uint32_t, int);
|
||||
void sethostent(int);
|
||||
void endhostent(void);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/dns/servicestxt.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/mem.h"
|
||||
#include "libc/sock/sock.h"
|
||||
|
@ -94,7 +94,7 @@ int getaddrinfo(const char *name, const char *service,
|
|||
return EAI_NONAME;
|
||||
} else if (ResolveHostsTxt(GetHostsTxt(), AF_INET, name, ai->ai_addr,
|
||||
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;
|
||||
return 0;
|
||||
} else {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "libc/mem/mem.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 char h_name[DNS_NAME_MAX + 1];
|
||||
static char *h_aliases[1];
|
||||
|
|
|
@ -53,16 +53,16 @@ struct hostent *gethostbyname(const char *name) {
|
|||
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,
|
||||
* (see newaddrinfo) but the string can still be empty */
|
||||
if (result->ai_canonname[0])
|
||||
memccpy(ptr0->h_name, result->ai_canonname, '\0', DNS_NAME_MAX);
|
||||
else
|
||||
memccpy(ptr0->h_name, name, '\0', DNS_NAME_MAX);
|
||||
strlcpy(ptr0->h_name, *result->ai_canonname ? result->ai_canonname : name,
|
||||
sizeof(h_name));
|
||||
|
||||
*((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 */
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/pushpop.internal.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -39,16 +39,11 @@ static struct HostsTxtInitialStaticMemory {
|
|||
char strings[64];
|
||||
} g_hoststxt_init;
|
||||
|
||||
static textwindows dontinline char *GetNtHostsTxtPath(char *pathbuf,
|
||||
uint32_t size) {
|
||||
const char *const kWinHostsPath = "\\drivers\\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];
|
||||
static const char *GetHostsTxtPath(char *path, size_t size) {
|
||||
if (!IsWindows()) {
|
||||
return "/etc/hosts";
|
||||
} 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) {
|
||||
FILE *f;
|
||||
const char *path;
|
||||
char pathbuf[PATH_MAX];
|
||||
char pathbuf[256];
|
||||
struct HostsTxtInitialStaticMemory *init;
|
||||
init = &g_hoststxt_init;
|
||||
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.p = init->strings;
|
||||
__cxa_atexit(FreeHostsTxt, &g_hoststxt, NULL);
|
||||
path = "/etc/hosts";
|
||||
if (IsWindows()) {
|
||||
path = firstnonnull(GetNtHostsTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
||||
}
|
||||
if (fileexists(path) && (f = fopen(path, "r"))) {
|
||||
if ((f = fopen(GetHostsTxtPath(pathbuf, sizeof(pathbuf)), "r"))) {
|
||||
if (ParseHostsTxt(g_hoststxt, f) == -1) {
|
||||
/* TODO(jart): Elevate robustness. */
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
*
|
||||
* @return 0 on success or EAI_xxx value
|
||||
*/
|
||||
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *name,
|
||||
socklen_t namelen, char *service, socklen_t servicelen,
|
||||
int getnameinfo(const struct sockaddr *addr, uint32_t addrlen, char *name,
|
||||
uint32_t namelen, char *service, uint32_t servicelen,
|
||||
int flags) {
|
||||
char *p, rdomain[1 + sizeof "255.255.255.255.in-addr.arpa"];
|
||||
char info[NI_MAXHOST + 1];
|
||||
|
|
|
@ -24,19 +24,14 @@
|
|||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/dns/prototxt.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
|
||||
textwindows char *GetNtProtocolsTxtPath(char *pathbuf, uint32_t size) {
|
||||
/* protocol, not plural */
|
||||
const char *const kWinHostsPath = "\\drivers\\etc\\protocol";
|
||||
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];
|
||||
const char *GetProtocolsTxtPath(char *buf, size_t size) {
|
||||
if (!IsWindows()) {
|
||||
return "/etc/protocols";
|
||||
} 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 │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.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 *const kWinHostsPath = "\\drivers\\etc\\services";
|
||||
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];
|
||||
const char *GetServicesTxtPath(char *path, size_t size) {
|
||||
if (!IsWindows()) {
|
||||
return "/etc/services";
|
||||
} else {
|
||||
return NULL;
|
||||
return GetSystemDirectoryPath(path, size, "drivers\\etc\\services");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "libc/dns/ent.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
struct servent *getservbyname(const char *name, const char *proto) {
|
||||
|
@ -42,9 +43,10 @@ struct servent *getservbyname(const char *name, const char *proto) {
|
|||
ptr0 = &se0;
|
||||
}
|
||||
if (proto) {
|
||||
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) return NULL;
|
||||
} else
|
||||
strcpy(localproto, "");
|
||||
strlcpy(localproto, proto, sizeof(localproto));
|
||||
} else {
|
||||
*localproto = 0;
|
||||
}
|
||||
p = LookupServicesByName(name, ptr0->s_proto, DNS_NAME_MAX, ptr0->s_name,
|
||||
DNS_NAME_MAX, NULL);
|
||||
if (p == -1) return NULL;
|
||||
|
|
|
@ -41,9 +41,12 @@ struct servent *getservbyport(int port, const char *proto) {
|
|||
ptr1 = &se1;
|
||||
}
|
||||
if (proto) {
|
||||
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) return NULL;
|
||||
} else
|
||||
strcpy(localproto, "");
|
||||
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
*localproto = 0;
|
||||
}
|
||||
if (LookupServicesByPort(ntohs(port), ptr1->s_proto, DNS_NAME_MAX,
|
||||
ptr1->s_name, DNS_NAME_MAX, NULL) == -1) {
|
||||
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) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
const char *path;
|
||||
size_t linesize;
|
||||
const char *path;
|
||||
int found, result;
|
||||
char pathbuf[PATH_MAX];
|
||||
char pathbuf[256];
|
||||
char *name, *number, *alias, *comment, *tok;
|
||||
if (!(path = filepath)) {
|
||||
path = "/etc/protocols";
|
||||
if (IsWindows()) {
|
||||
path =
|
||||
firstnonnull(GetNtProtocolsTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
||||
}
|
||||
!IsWindows()
|
||||
? "/etc/protocols"
|
||||
: firstnonnull(GetProtocolsTxtPath(pathbuf, sizeof(pathbuf)), path);
|
||||
}
|
||||
if (bufsize == 0 || !(f = fopen(path, "r"))) {
|
||||
return -1;
|
||||
|
@ -70,18 +69,20 @@ int LookupProtoByName(const char *protoname, char *buf, size_t bufsize,
|
|||
linesize = 0;
|
||||
found = 0;
|
||||
result = -1;
|
||||
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
|
||||
while (found == 0 && getline(&line, &linesize, f) != -1) {
|
||||
if ((comment = strchr(line, '#'))) *comment = '\0';
|
||||
name = strtok_r(line, " \t\r\n\v", &tok);
|
||||
number = strtok_r(NULL, "/ \t\r\n\v", &tok);
|
||||
if (name && number) {
|
||||
alias = name;
|
||||
while (alias && strcasecmp(alias, protoname) != 0)
|
||||
while (alias && strcasecmp(alias, protoname)) {
|
||||
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)) {
|
||||
strcpy(buf, "");
|
||||
if (bufsize) {
|
||||
*buf = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
result = atoi(number);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "libc/dns/prototxt.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -46,28 +45,22 @@
|
|||
* @param protonum is the protocol number
|
||||
* @param buf is a buffer to store the official name of the protocol
|
||||
* @param bufsize is the size of buf
|
||||
* @param filepath is the location of the protocols file
|
||||
* (if NULL, uses /etc/protocols)
|
||||
* @param path is the location of the protocols file, which may be NULL
|
||||
* to use the system-wide default
|
||||
* @return 0 on success, -1 on error
|
||||
* @note aliases are not read from the file.
|
||||
*/
|
||||
int LookupProtoByNumber(const int protonum, char *buf, size_t bufsize,
|
||||
const char *filepath) {
|
||||
const char *path) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
int found;
|
||||
char *line;
|
||||
size_t linesize;
|
||||
const char *path;
|
||||
char pathbuf[PATH_MAX];
|
||||
char pathbuf[256];
|
||||
char *name, *number, *comment, *tok;
|
||||
if (!(path = filepath)) {
|
||||
path = "/etc/protocols";
|
||||
if (IsWindows()) {
|
||||
path =
|
||||
firstnonnull(GetNtProtocolsTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
||||
}
|
||||
}
|
||||
if (bufsize == 0 || !(f = fopen(path, "r"))) {
|
||||
if (!bufsize ||
|
||||
!(f = fopen(path ? path : GetProtocolsTxtPath(pathbuf, sizeof(pathbuf)),
|
||||
"r"))) {
|
||||
return -1;
|
||||
}
|
||||
line = NULL;
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
* @param buf is a buffer to store the official name of the service
|
||||
* (if NULL, the official name is not stored)
|
||||
* @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)
|
||||
* @return -1 on error, or positive port number
|
||||
* @note aliases are read from file for comparison, but not returned.
|
||||
|
@ -54,29 +54,23 @@
|
|||
*/
|
||||
int LookupServicesByName(const char *servname, char *servproto,
|
||||
size_t servprotolen, char *buf, size_t bufsize,
|
||||
const char *filepath) {
|
||||
const char *path) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
const char *path;
|
||||
size_t linesize;
|
||||
char pathbuf[256];
|
||||
int found, result;
|
||||
char pathbuf[PATH_MAX];
|
||||
char *name, *port, *proto, *alias, *comment, *tok;
|
||||
if (!(path = filepath)) {
|
||||
path = "/etc/services";
|
||||
if (IsWindows()) {
|
||||
path =
|
||||
firstnonnull(GetNtServicesTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
||||
}
|
||||
}
|
||||
if (servprotolen == 0 || !(f = fopen(path, "r"))) {
|
||||
if (servprotolen == 0 ||
|
||||
!(f = fopen(path ? path : GetServicesTxtPath(pathbuf, sizeof(pathbuf)),
|
||||
"r"))) {
|
||||
return -1;
|
||||
}
|
||||
line = NULL;
|
||||
linesize = 0;
|
||||
found = 0;
|
||||
result = -1;
|
||||
if (buf && bufsize != 0) strcpy(buf, "");
|
||||
if (bufsize) strcpy(buf, "");
|
||||
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
|
||||
if ((comment = strchr(line, '#'))) *comment = '\0';
|
||||
name = strtok_r(line, " \t\r\n\v", &tok);
|
||||
|
@ -93,8 +87,8 @@ int LookupServicesByName(const char *servname, char *servproto,
|
|||
strcpy(servproto, "");
|
||||
break;
|
||||
}
|
||||
if (buf && bufsize != 0 && !memccpy(buf, name, '\0', bufsize)) {
|
||||
strcpy(buf, "");
|
||||
if (bufsize && !memccpy(buf, name, '\0', bufsize)) {
|
||||
*buf = 0;
|
||||
break;
|
||||
}
|
||||
result = atoi(port);
|
||||
|
|
|
@ -52,36 +52,30 @@
|
|||
* @param servprotolen the size of servproto
|
||||
* @param buf is a buffer to store the official name of the service
|
||||
* @param bufsize is the size of buf
|
||||
* @param filepath is the location of the services file
|
||||
* (if NULL, uses /etc/services)
|
||||
* @param path is the location of the services file, which may be NULL
|
||||
* to use the system-wide default
|
||||
* @return 0 on success, -1 on error
|
||||
* @note aliases are not read from the file.
|
||||
*/
|
||||
int LookupServicesByPort(const int servport, char *servproto,
|
||||
size_t servprotolen, char *buf, size_t bufsize,
|
||||
const char *filepath) {
|
||||
const char *path) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
char pathbuf[PATH_MAX];
|
||||
const char *path;
|
||||
size_t linesize;
|
||||
int found;
|
||||
char *line;
|
||||
size_t linesize;
|
||||
char pathbuf[256];
|
||||
char *name, *port, *proto, *comment, *tok;
|
||||
if (!(path = filepath)) {
|
||||
path = "/etc/services";
|
||||
if (IsWindows()) {
|
||||
path =
|
||||
firstnonnull(GetNtServicesTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
||||
}
|
||||
}
|
||||
if (servprotolen == 0 || bufsize == 0 || !(f = fopen(path, "r"))) {
|
||||
if (!servprotolen ||
|
||||
!(f = fopen(path ? path : GetServicesTxtPath(pathbuf, sizeof(pathbuf)),
|
||||
"r"))) {
|
||||
return -1;
|
||||
}
|
||||
found = 0;
|
||||
line = NULL;
|
||||
linesize = 0;
|
||||
found = 0;
|
||||
strcpy(buf, "");
|
||||
while (found == 0 && (getline(&line, &linesize, f)) != -1) {
|
||||
if (bufsize) *buf = 0;
|
||||
while (!found && (getline(&line, &linesize, f)) != -1) {
|
||||
if ((comment = strchr(line, '#'))) *comment = '\0';
|
||||
name = strtok_r(line, " \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;
|
||||
}
|
||||
if (!memccpy(buf, name, '\0', bufsize)) {
|
||||
strcpy(buf, "");
|
||||
if (bufsize) {
|
||||
*buf = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
found = 1;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "libc/sock/sock.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)
|
||||
|
||||
struct addrinfo *newaddrinfo(uint16_t port) {
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
const char *GetProtocolsTxtPath(char *, size_t);
|
||||
|
||||
int LookupProtoByNumber(const int, char *, size_t, const char *)
|
||||
paramsnonnull((2));
|
||||
int LookupProtoByName(const char *, char *, size_t, const char *)
|
||||
paramsnonnull((1, 2));
|
||||
char *GetNtProtocolsTxtPath(char *, uint32_t);
|
||||
|
||||
/* 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();
|
||||
for (i = 0; i < ht->entries.i; ++i) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
char *GetSystemDirectoryPath(char *, size_t, const char *);
|
||||
int LookupServicesByPort(const int, char *, size_t, char *, size_t,
|
||||
const char *) paramsnonnull((2, 4));
|
||||
int LookupServicesByName(const char *, char *, size_t, char *, size_t,
|
||||
const char *) paramsnonnull((1, 2));
|
||||
char *GetNtServicesTxtPath(char *, uint32_t);
|
||||
const char *GetServicesTxtPath(char *, size_t);
|
||||
|
||||
/* TODO: implement like struct HostsTxt? */
|
||||
|
||||
|
|
|
@ -1,19 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef COSMOPOLITAN_LIBC_STDCKDINT_H_
|
||||
#define COSMOPOLITAN_LIBC_STDCKDINT_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
/* clang-format off */
|
||||
|
||||
/**
|
||||
* @fileoverview C23 Checked Arithmetic
|
||||
|
@ -54,16 +42,6 @@
|
|||
* @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
|
||||
|
||||
#if ((defined(__llvm__) || \
|
||||
|
@ -81,18 +59,12 @@
|
|||
typedef signed __ckd_intmax __ckd_intmax_t;
|
||||
typedef unsigned __ckd_intmax __ckd_uintmax_t;
|
||||
|
||||
#ifdef __has_builtin
|
||||
#define __ckd_has_builtin(x) __has_builtin(x)
|
||||
#else
|
||||
#define __ckd_has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#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))))
|
||||
(__has_builtin(__builtin_add_overflow) && \
|
||||
__has_builtin(__builtin_sub_overflow) && \
|
||||
__has_builtin(__builtin_mul_overflow))))
|
||||
#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_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)
|
||||
|
||||
#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;
|
||||
if (f->noclose) {
|
||||
f->fd = -1;
|
||||
} else if (close(f->fd) == -1) {
|
||||
} else if (f->fd != -1 && close(f->fd) == -1) {
|
||||
f->state = errno;
|
||||
}
|
||||
if (f->state == EOF) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- 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 │
|
||||
│ 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 │
|
||||
|
@ -16,11 +16,16 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ 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) {
|
||||
return (struct timespec){tv.tv_sec, tv.tv_usec * 1000};
|
||||
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);
|
|
@ -71,8 +71,8 @@ int system(const char *cmdline) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
sigaction(SIGINT, &saveint, 0);
|
||||
sigaction(SIGQUIT, &savequit, 0);
|
||||
sigaction(SIGINT, &saveint, 0);
|
||||
}
|
||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||
ALLOW_CANCELLATIONS;
|
||||
|
|
|
@ -46,11 +46,11 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
void *memccpy(void *dst, const void *src, int c, size_t n) {
|
||||
char *d;
|
||||
size_t i;
|
||||
unsigned char *d;
|
||||
const unsigned char *s;
|
||||
const char *s;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,27 +16,30 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Prepares static search buffer.
|
||||
*
|
||||
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
|
||||
*
|
||||
* 2. If SRC is too short, the remainder is zero-filled.
|
||||
*
|
||||
* Please note this function isn't designed to prevent untrustworthy
|
||||
* data from modifying memory without authorization. Consider trying
|
||||
* memccpy() for that purpose.
|
||||
*
|
||||
* @return dest + stride
|
||||
* @see stncpy(), memccpy()
|
||||
* @param dst is output buffer
|
||||
* @param src is a nul-terminated string
|
||||
* @param dstlen is size of `dst` buffer
|
||||
* @return pointer to first nul-terminator, otherwise dest + stride
|
||||
* @asyncsignalsafe
|
||||
* @see strncpy()
|
||||
* @see memccpy()
|
||||
* @see strlcpy()
|
||||
*/
|
||||
char *stpncpy(char *dest, const char *src, size_t stride) {
|
||||
char *p;
|
||||
if ((p = memccpy(dest, src, '\0', stride))) {
|
||||
bzero(p, dest + stride - p);
|
||||
}
|
||||
return dest + stride;
|
||||
char *stpncpy(char *dst, const char *src, size_t dstlen) {
|
||||
size_t srclen, cpylen, zerlen;
|
||||
srclen = strlen(src);
|
||||
cpylen = MIN(srclen, dstlen);
|
||||
if (cpylen) memcpy(dst, src, cpylen);
|
||||
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
|
||||
* @return 𝑑
|
||||
* @note 𝑑 and 𝑠 can't overlap
|
||||
* @asyncsignaslenafe
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
char *strncat(char *d, const char *s, size_t n) {
|
||||
size_t o;
|
||||
if (!memccpy(d + (o = strlen(d)), s, '\0', n)) {
|
||||
d[o + n] = '\0';
|
||||
size_t dn, sn;
|
||||
if ((sn = strnlen(s, n))) {
|
||||
dn = strlen(d);
|
||||
memcpy(d + dn, s, sn);
|
||||
d[dn + sn] = 0;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
|
@ -24,16 +25,21 @@
|
|||
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
|
||||
* 2. If SRC is too short, the remainder is zero-filled.
|
||||
*
|
||||
* @return dest
|
||||
* @see stpncpy(), memccpy()
|
||||
* @param dst is output buffer
|
||||
* @param src is a nul-terminated string
|
||||
* @param dstlen is size of `dst` buffer
|
||||
* @return dst
|
||||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
* @see stpncpy()
|
||||
* @see strlcpy()
|
||||
* @see memccpy()
|
||||
*/
|
||||
char *strncpy(char *dest, const char *src, size_t stride) {
|
||||
size_t i;
|
||||
for (i = 0; i < stride; ++i) {
|
||||
if (!(dest[i] = src[i])) break;
|
||||
}
|
||||
bzero(dest + i, stride - i);
|
||||
return dest;
|
||||
char *strncpy(char *dst, const char *src, size_t dstlen) {
|
||||
size_t srclen, cpylen, zerlen;
|
||||
srclen = strlen(src);
|
||||
cpylen = MIN(srclen, dstlen);
|
||||
if (cpylen) memcpy(dst, src, cpylen);
|
||||
zerlen = dstlen - cpylen;
|
||||
if (zerlen) bzero(dst + cpylen, zerlen);
|
||||
return dst;
|
||||
}
|
||||
|
|
|
@ -28,64 +28,26 @@
|
|||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/thread/spawn.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SIGTRAP
|
||||
|
||||
TEST(raise, trap_sysv) {
|
||||
if (IsWindows()) return;
|
||||
TEST(raise, trap) {
|
||||
signal(SIGTRAP, SIG_DFL);
|
||||
SPAWN(fork);
|
||||
raise(SIGTRAP);
|
||||
TERMS(SIGTRAP);
|
||||
}
|
||||
|
||||
TEST(raise, trap_windows) {
|
||||
if (!IsWindows()) return;
|
||||
signal(SIGTRAP, SIG_DFL);
|
||||
SPAWN(fork);
|
||||
raise(SIGTRAP);
|
||||
EXITS(128 + SIGTRAP);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SIGFPE
|
||||
|
||||
TEST(raise, fpe_sysv) {
|
||||
if (IsWindows()) return;
|
||||
TEST(raise, fpe) {
|
||||
signal(SIGFPE, SIG_DFL);
|
||||
SPAWN(fork);
|
||||
raise(SIGFPE);
|
||||
TERMS(SIGFPE);
|
||||
}
|
||||
|
||||
TEST(raise, fpe_windows) {
|
||||
if (!IsWindows()) return;
|
||||
signal(SIGFPE, SIG_DFL);
|
||||
SPAWN(fork);
|
||||
raise(SIGFPE);
|
||||
EXITS(128 + SIGFPE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SIGUSR1
|
||||
|
||||
TEST(raise, usr1_sysv) {
|
||||
if (IsWindows()) return;
|
||||
TEST(raise, usr1) {
|
||||
SPAWN(fork);
|
||||
raise(SIGUSR1);
|
||||
TERMS(SIGUSR1);
|
||||
}
|
||||
|
||||
TEST(raise, usr1_windows) {
|
||||
if (!IsWindows()) return;
|
||||
SPAWN(fork);
|
||||
raise(SIGUSR1);
|
||||
EXITS(128 + SIGUSR1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// THREADS
|
||||
|
||||
int threadid;
|
||||
|
||||
void WorkerQuit(int sig, siginfo_t *si, void *ctx) {
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
|
@ -137,8 +137,8 @@ TEST(LookupServicesByName, GetPortWhenNameOrAlias) {
|
|||
|
||||
localproto = proto2;
|
||||
ASSERT_EQ(-1, /* protocol is non-NULL/length must be nonzero */
|
||||
LookupServicesByName("ssh", localproto, 0, name, sizeof(name),
|
||||
"services"));
|
||||
LookupServicesByName("ssh", localproto, sizeof(proto2), name,
|
||||
sizeof(name), "services"));
|
||||
ASSERT_STREQ(proto2, "udp");
|
||||
|
||||
localproto = proto1;
|
||||
|
|
|
@ -19,33 +19,20 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/testlib/subprocess.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(abort, sysv) {
|
||||
if (IsWindows()) return;
|
||||
TEST(abort, test) {
|
||||
SPAWN(fork);
|
||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
||||
abort();
|
||||
TERMS(SIGABRT);
|
||||
}
|
||||
|
||||
TEST(abort, windows) {
|
||||
if (!IsWindows()) return;
|
||||
SPAWN(fork);
|
||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
||||
abort();
|
||||
EXITS(128 + SIGABRT);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(abort, blocked_stillTerminates_sysv) {
|
||||
TEST(abort, blocked_stillTerminates) {
|
||||
sigset_t ss;
|
||||
if (IsWindows()) return;
|
||||
SPAWN(fork);
|
||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_DFL));
|
||||
sigfillset(&ss);
|
||||
|
@ -54,52 +41,19 @@ TEST(abort, blocked_stillTerminates_sysv) {
|
|||
TERMS(SIGABRT);
|
||||
}
|
||||
|
||||
TEST(abort, blocked_stillTerminates_windows) {
|
||||
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;
|
||||
TEST(abort, ign_stillTerminates) {
|
||||
SPAWN(fork);
|
||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, SIG_IGN));
|
||||
abort();
|
||||
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) {
|
||||
}
|
||||
|
||||
TEST(abort, handled_stillTerminates_sysv) {
|
||||
if (IsWindows()) return;
|
||||
TEST(abort, handled_stillTerminates) {
|
||||
SPAWN(fork);
|
||||
ASSERT_NE(SIG_ERR, signal(SIGABRT, Ignore));
|
||||
abort();
|
||||
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 -*-│
|
||||
│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 │
|
||||
│ 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 │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/thread/thread.h"
|
||||
#include "third_party/gdtoa/lock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
static pthread_mutex_t __gdtoa_lock_obj;
|
||||
static pthread_mutex_t __gdtoa_lock1_obj;
|
||||
|
||||
int(__gdtoa_lock)(void) {
|
||||
return pthread_mutex_lock(&__gdtoa_lock_obj);
|
||||
}
|
||||
|
||||
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);
|
||||
TEST(strncat, test) {
|
||||
char buf[32] = "foo";
|
||||
EXPECT_STREQ("foobar", strncat(buf, "bar", 3));
|
||||
EXPECT_STREQ("foobarbar", strncat(buf, "bar", 10));
|
||||
EXPECT_STREQ("foobarbarb", strncat(buf, "bar", 1));
|
||||
EXPECT_STREQ("foobarbarb", strncat(buf, "", 1));
|
||||
}
|
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/macros.internal.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/lock.h"
|
||||
/* clang-format off */
|
||||
|
||||
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
|
||||
__gdtoa_Brelease(Bigint *rv)
|
||||
|
@ -63,7 +110,11 @@ __gdtoa_Bclear(void)
|
|||
__attribute__((__constructor__)) static void
|
||||
__gdtoa_Binit(void)
|
||||
{
|
||||
__gdtoa_initlock();
|
||||
__gdtoa_initlock1();
|
||||
atexit(__gdtoa_Bclear);
|
||||
pthread_atfork(__gdtoa_lock1, __gdtoa_unlock1, __gdtoa_initlock1);
|
||||
pthread_atfork(__gdtoa_lock, __gdtoa_unlock, __gdtoa_initlock);
|
||||
}
|
||||
|
||||
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/winsize.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/dns/dns.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 │
|
||||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/mbedtls/net_sockets.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sock/select.h"
|
||||
|
@ -31,7 +33,6 @@
|
|||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "third_party/mbedtls/error.h"
|
||||
#include "third_party/mbedtls/net_sockets.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
|
||||
#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) {
|
||||
if (rc) fprintf(stderr, "mbedtls test exit() called with %d\n", rc);
|
||||
if (rc) xwrite(1, output, appendz(output).i);
|
||||
free(output);
|
||||
output = 0;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
|
@ -97,7 +98,7 @@
|
|||
* - 1 byte exit status
|
||||
*/
|
||||
|
||||
#define DEATH_CLOCK_SECONDS 128
|
||||
#define DEATH_CLOCK_SECONDS 300
|
||||
|
||||
#define kLogFile "o/runitd.log"
|
||||
#define kLogMaxBytes (2 * 1000 * 1000)
|
||||
|
@ -123,7 +124,6 @@ void OnChildTerminated(int sig) {
|
|||
sigdelset(&ss, SIGTERM);
|
||||
sigprocmask(SIG_BLOCK, &ss, &oldss);
|
||||
for (;;) {
|
||||
INFOF("waitpid");
|
||||
if ((pid = waitpid(-1, &ws, WNOHANG)) != -1) {
|
||||
if (pid) {
|
||||
if (WIFEXITED(ws)) {
|
||||
|
@ -364,13 +364,12 @@ void HandleClient(void) {
|
|||
const size_t kMaxNameSize = 128;
|
||||
const size_t kMaxFileSize = 10 * 1024 * 1024;
|
||||
uint32_t crc;
|
||||
sigset_t sigmask;
|
||||
ssize_t got, wrote;
|
||||
struct sockaddr_in addr;
|
||||
long double now, deadline;
|
||||
sigset_t chldmask, savemask;
|
||||
struct timespec now, deadline;
|
||||
char *addrstr, *exename, *exe;
|
||||
unsigned char msg[4 + 1 + 4 + 4 + 4];
|
||||
struct sigaction ignore, saveint, savequit;
|
||||
uint32_t addrsize, namesize, filesize, remaining;
|
||||
int rc, events, exitcode, wstatus, child, pipefds[2];
|
||||
|
||||
|
@ -411,29 +410,24 @@ void HandleClient(void) {
|
|||
}
|
||||
CHECK_NE(-1, (g_exefd = creat(g_exepath, 0700)));
|
||||
LOGIFNEG1(ftruncate(g_exefd, filesize));
|
||||
INFOF("xwrite");
|
||||
CHECK_NE(-1, xwrite(g_exefd, exe, filesize));
|
||||
LOGIFNEG1(close(g_exefd));
|
||||
|
||||
/* run program, tee'ing stderr to both log and client */
|
||||
DEBUGF("spawning %s", exename);
|
||||
ignore.sa_flags = 0;
|
||||
ignore.sa_handler = SIG_IGN;
|
||||
sigemptyset(&ignore.sa_mask);
|
||||
sigaction(SIGINT, &ignore, &saveint);
|
||||
sigaction(SIGQUIT, &ignore, &savequit);
|
||||
sigemptyset(&chldmask);
|
||||
sigaddset(&chldmask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
||||
sigemptyset(&sigmask);
|
||||
sigaddset(&sigmask, SIGINT);
|
||||
sigaddset(&sigmask, SIGQUIT);
|
||||
sigaddset(&sigmask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &sigmask, 0);
|
||||
CHECK_NE(-1, pipe2(pipefds, O_CLOEXEC));
|
||||
CHECK_NE(-1, (child = fork()));
|
||||
if (!child) {
|
||||
dup2(g_bogusfd, 0);
|
||||
dup2(pipefds[1], 1);
|
||||
dup2(pipefds[1], 2);
|
||||
sigaction(SIGINT, &(struct sigaction){0}, 0);
|
||||
sigaction(SIGQUIT, &(struct sigaction){0}, 0);
|
||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||
sigemptyset(&sigmask);
|
||||
sigprocmask(SIG_SETMASK, &sigmask, 0);
|
||||
int i = 0;
|
||||
const char *exe;
|
||||
char *args[8] = {0};
|
||||
|
@ -451,13 +445,17 @@ void HandleClient(void) {
|
|||
execvp(exe, args);
|
||||
_Exit(127);
|
||||
}
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
close(pipefds[1]);
|
||||
DEBUGF("communicating %s[%d]", exename, child);
|
||||
deadline = nowl() + DEATH_CLOCK_SECONDS;
|
||||
deadline =
|
||||
timespec_add(timespec_real(), timespec_fromseconds(DEATH_CLOCK_SECONDS));
|
||||
for (;;) {
|
||||
now = nowl();
|
||||
if (now >= deadline) {
|
||||
now = timespec_real();
|
||||
if (timespec_cmp(now, deadline) >= 0) {
|
||||
WARNF("%s worker timed out", exename);
|
||||
TerminateJob:
|
||||
LOGIFNEG1(kill(child, 9));
|
||||
LOGIFNEG1(waitpid(child, 0, 0));
|
||||
LOGIFNEG1(close(g_clifd));
|
||||
|
@ -470,22 +468,20 @@ void HandleClient(void) {
|
|||
fds[0].events = POLLIN;
|
||||
fds[1].fd = pipefds[0];
|
||||
fds[1].events = POLLIN;
|
||||
INFOF("poll");
|
||||
events = poll(fds, ARRAYLEN(fds), (deadline - now) * 1000);
|
||||
int waitms = timespec_tomillis(timespec_sub(deadline, now));
|
||||
INFOF("polling for %d ms", waitms);
|
||||
events = poll(fds, ARRAYLEN(fds), waitms);
|
||||
CHECK_NE(-1, events); // EINTR shouldn't be possible
|
||||
if (events) {
|
||||
if (fds[0].revents) {
|
||||
if (!(fds[0].revents & POLLHUP)) {
|
||||
WARNF("%s got unexpected input event from client %#x", exename,
|
||||
fds[0].revents);
|
||||
}
|
||||
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);
|
||||
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
|
||||
|
@ -496,6 +492,8 @@ void HandleClient(void) {
|
|||
fwrite(g_buf, got, 1, stderr);
|
||||
SendOutputFragmentMessage(kRunitStderr, g_buf, got);
|
||||
}
|
||||
}
|
||||
}
|
||||
INFOF("waitpid");
|
||||
CHECK_NE(-1, waitpid(child, &wstatus, 0)); // EINTR shouldn't be possible
|
||||
if (WIFEXITED(wstatus)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue