mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 08:12:28 +00:00
Perform inconsequential code cleanup
This commit is contained in:
parent
929478c524
commit
decf216655
52 changed files with 326 additions and 442 deletions
|
@ -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);
|
||||
}
|
||||
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))))
|
||||
#if (!defined(__STRICT_ANSI__) && \
|
||||
((defined(__GNUC__) && __GNUC__ >= 5 && \
|
||||
!defined(__chibicc__) && !defined(__ICC)) || \
|
||||
(__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_ */
|
||||
|
|
27
libc/stdio/atof.c
Normal file
27
libc/stdio/atof.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*-*- 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 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
|
||||
/**
|
||||
* Converts string to double.
|
||||
*/
|
||||
double atof(const char *s) {
|
||||
return strtod(s, NULL);
|
||||
}
|
|
@ -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) {
|
||||
|
|
31
libc/stdio/strtold.c
Normal file
31
libc/stdio/strtold.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*-*- 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/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);
|
|
@ -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;
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/locale.h"
|
||||
|
||||
/**
|
||||
* Coerces `tv` from 1e-6 to 1e-9 granularity.
|
||||
*/
|
||||
struct timespec timeval_totimespec(struct timeval tv) {
|
||||
return (struct timespec){tv.tv_sec, tv.tv_usec * 1000};
|
||||
double wcstod(const wchar_t *nptr, wchar_t **endptr) {
|
||||
assert(!"not implemented");
|
||||
abort();
|
||||
}
|
28
libc/stdio/wcstof.c
Normal file
28
libc/stdio/wcstof.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/locale.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
|
||||
float wcstof(const wchar_t *nptr, wchar_t **endptr) {
|
||||
assert(!"not implemented");
|
||||
abort();
|
||||
}
|
30
libc/stdio/wcstold.c
Normal file
30
libc/stdio/wcstold.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/locale.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
|
||||
long double wcstold(const wchar_t *nptr, wchar_t **endptr) {
|
||||
assert(!"not implemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
__weak_reference(strtold, strtold_l);
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue