mirror of
https://github.com/jart/cosmopolitan.git
synced 2026-11-08 17:19:47 -10:00
Compare commits
92
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ace523c79b | ||
|
|
c70422586a | ||
|
|
cabb0a7ede | ||
|
|
38aece42ba | ||
|
|
f66ef5d58e | ||
|
|
0c6581f912 | ||
|
|
d522a88def | ||
|
|
795d6fd6cd | ||
|
|
d3a735702b | ||
|
|
214e3a68a9 | ||
|
|
3d0347e26e | ||
|
|
bc464a8898 | ||
|
|
59e1c245d1 | ||
|
|
916f19eea1 | ||
|
|
5029e20bef | ||
|
|
968474d291 | ||
|
|
228fb7428b | ||
|
|
1e5bd4d23e | ||
|
|
fe29710e4e | ||
|
|
579b597ded | ||
|
|
e963d9c8e3 | ||
|
|
9b29358511 | ||
|
|
71273bc5c9 | ||
|
|
1aa0df696c | ||
|
|
a22f0736d8 | ||
|
|
b420ed8248 | ||
|
|
20bb8db9f8 | ||
|
|
a2e443edd7 | ||
|
|
9454788223 | ||
|
|
31a37aeb1a | ||
|
|
79ba5233db | ||
|
|
d26d7ae0e4 | ||
|
|
ee7e296339 | ||
|
|
3bfb7580c5 | ||
|
|
b703eee96e | ||
|
|
5a441ea57f | ||
|
|
10aade69e3 | ||
|
|
53b9f83e1c | ||
|
|
d86027fe90 | ||
|
|
798d542f15 | ||
|
|
295b3d6ca5 | ||
|
|
f9eae9794a | ||
|
|
98f330b764 | ||
|
|
5ef64dbcdb | ||
|
|
0c4c56ff39 | ||
|
|
75fc601ff5 | ||
|
|
28a592f2d4 | ||
|
|
d8faadf44e | ||
|
|
4daafef63a | ||
|
|
2bc0901ce3 | ||
|
|
6bbb44c165 | ||
|
|
0cdba6878b | ||
|
|
1f766a332f | ||
|
|
aeeb851422 | ||
|
|
55a15c204e | ||
|
|
b142ea7176 | ||
|
|
fd76fa0016 | ||
|
|
533f3d1ef1 | ||
|
|
df8ab0aa0c | ||
|
|
344d2dc356 | ||
|
|
f7b4804251 | ||
|
|
64d87d4e5a | ||
|
|
0b317523a0 | ||
|
|
a73e808b25 | ||
|
|
3ac6576fe5 | ||
|
|
312ccc919b | ||
|
|
ea83cc0ad0 | ||
|
|
398f0c16fb | ||
|
|
f3e28aa192 | ||
|
|
8c4cce043c | ||
|
|
98c674d915 | ||
|
|
e99a4dcc8c | ||
|
|
c002e4ba76 | ||
|
|
fe881982b5 | ||
|
|
4178896aa0 | ||
|
|
3641e99042 | ||
|
|
45d72920ba | ||
|
|
feb0f9fb3a | ||
|
|
cc9366b200 | ||
|
|
c89bc56f6a | ||
|
|
36b2710e1a | ||
|
|
e51034bab3 | ||
|
|
f8b9bd2b47 | ||
|
|
0ecd71f697 | ||
|
|
c0bec24fa2 | ||
|
|
58fb2fb3d3 | ||
|
|
8d5f60a9cd | ||
|
|
0ea2907730 | ||
|
|
cfbd2afc19 | ||
|
|
a7bd4ed9ea | ||
|
|
300876ee50 | ||
|
|
e6b22f1f65 |
No files matched your search
@@ -0,0 +1,3 @@
|
||||
# -*- conf -*-
|
||||
/build/bootstrap/*.com binary
|
||||
/usr/share/zoneinfo/* binary
|
||||
@@ -1,5 +1,10 @@
|
||||
# -*- conf -*-
|
||||
|
||||
/o
|
||||
|
||||
# TODO: Find some way to have Python write to o/
|
||||
__pycache__
|
||||
|
||||
*.tmp
|
||||
/.bochs.log
|
||||
/HTAGS
|
||||
|
||||
@@ -130,17 +130,20 @@ include libc/sock/sock.mk #─┐
|
||||
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
|
||||
include libc/dns/dns.mk # │ You can communicate with the network
|
||||
include net/http/http.mk # │
|
||||
include third_party/mbedtls/mbedtls.mk # │
|
||||
include net/https/https.mk # │
|
||||
include third_party/regex/regex.mk #─┘
|
||||
include third_party/third_party.mk
|
||||
include libc/testlib/testlib.mk
|
||||
include tool/viz/lib/vizlib.mk
|
||||
include third_party/linenoise/linenoise.mk
|
||||
include third_party/lua/lua.mk
|
||||
include third_party/sqlite3/sqlite3.mk
|
||||
include third_party/mbedtls/mbedtls.mk
|
||||
include third_party/mbedtls/test/test.mk
|
||||
include third_party/quickjs/quickjs.mk
|
||||
include third_party/lz4cli/lz4cli.mk
|
||||
include third_party/infozip/infozip.mk
|
||||
include third_party/python/python.mk
|
||||
include tool/build/lib/buildlib.mk
|
||||
include third_party/chibicc/chibicc.mk
|
||||
include third_party/chibicc/test/test.mk
|
||||
@@ -175,6 +178,7 @@ include test/libc/stdio/test.mk
|
||||
include test/libc/release/test.mk
|
||||
include test/libc/test.mk
|
||||
include test/net/http/test.mk
|
||||
include test/net/https/test.mk
|
||||
include test/net/test.mk
|
||||
include test/tool/build/lib/test.mk
|
||||
include test/tool/build/test.mk
|
||||
@@ -213,15 +217,19 @@ o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(
|
||||
$(file >$@) $(foreach x,$(SRCS),$(file >>$@,$(x)))
|
||||
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
|
||||
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
|
||||
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x))))
|
||||
$(file >$@) $(foreach x,$(INCS) $(INCS),$(file >>$@,$(x)))
|
||||
else
|
||||
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
|
||||
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^SRCS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
|
||||
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
|
||||
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^HDRS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
|
||||
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x))))
|
||||
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^INCS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
|
||||
endif
|
||||
|
||||
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt $(SRCS) $(HDRS) $(INCS)
|
||||
@$(COMPILE) -AMKDEPS $(MKDEPS) -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt
|
||||
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt $(SRCS) $(HDRS) $(INCS)
|
||||
@$(COMPILE) -AMKDEPS $(MKDEPS) -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt
|
||||
|
||||
TAGS: o/$(MODE)/srcs.txt $(SRCS)
|
||||
@rm -f $@
|
||||
|
||||
@@ -545,6 +545,22 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
||||
// We prefer this because it's a tiny constant one time cost.
|
||||
// We simply printf a 64-byte header and call execve() again.
|
||||
.ascii "o=\"$(command -v \"$0\")\"\n"
|
||||
#ifdef APE_BUILDSAFE
|
||||
// This code is intended for binaries in build/bootstrap/. It
|
||||
// causes them to not self-modify since they're checked-in to
|
||||
// version control. It assumes cosmopolitan's build prefix is
|
||||
// being used by convention and that the program has the noop
|
||||
// flag -n which is used to prime the binary.
|
||||
.ascii "if [ ${o##o/} = $o ]; then\n"
|
||||
.ascii " if ! [ o/$o -nt $o ]; then\n"
|
||||
.ascii " mkdir -p o/${o%/*} || exit\n"
|
||||
.ascii " cp -f $o o/$o.$$ || exit\n"
|
||||
.ascii " o/$o.$$ -n || exit\n"
|
||||
.ascii " mv -f o/$o.$$ o/$o || exit\n"
|
||||
.ascii " fi\n"
|
||||
.ascii " exec o/$o \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
#endif
|
||||
#else
|
||||
// The alternative behavior is to copy to $TMPDIR and edit.
|
||||
// This imposes a variety of caveats of its own that should
|
||||
|
||||
+3
-1
@@ -201,6 +201,8 @@ SECTIONS {
|
||||
|
||||
/* Real Mode */
|
||||
KEEP(*(.head))
|
||||
KEEP(*(.apesh))
|
||||
KEEP(*(.head2))
|
||||
KEEP(*(.text.head))
|
||||
|
||||
/* Executable & Linkable Format */
|
||||
@@ -375,7 +377,7 @@ SECTIONS {
|
||||
/*END: file content */
|
||||
/*BEGIN: bss memory that's addressable */
|
||||
|
||||
.bss ALIGN(__SIZEOF_POINTER__) : {
|
||||
.bss ALIGN(64) : {
|
||||
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
|
||||
*(.piro.bss)
|
||||
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
||||
|
||||
@@ -19,6 +19,11 @@ APE = $(APE_DEPS) \
|
||||
$(APE_OBJS) \
|
||||
o/$(MODE)/ape/ape.lds
|
||||
|
||||
APE_BUILDSAFE = \
|
||||
$(APE_DEPS) \
|
||||
o/$(MODE)/ape/ape-buildsafe.o \
|
||||
o/$(MODE)/ape/ape.lds
|
||||
|
||||
APELINK = \
|
||||
$(COMPILE) \
|
||||
-ALINK.ape \
|
||||
@@ -49,6 +54,9 @@ $(APE_OBJS): $(BUILD_FILES) \
|
||||
o/$(MODE)/ape/ape-no-modify-self.o: ape/ape.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_NO_MODIFY_SELF $<
|
||||
|
||||
o/$(MODE)/ape/ape-buildsafe.o: ape/ape.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_BUILDSAFE $<
|
||||
|
||||
.PHONY: o/$(MODE)/ape
|
||||
o/$(MODE)/ape: $(APE) \
|
||||
$(APE_CHECKS) \
|
||||
|
||||
-1279
File diff suppressed because it is too large.
Load diff
-1294
File diff suppressed because it is too large.
Load diff
Binary file not shown.
Binary file not shown.
+39
-7
@@ -50,6 +50,8 @@ endif
|
||||
|
||||
# Release Mode
|
||||
#
|
||||
# Follows traditional closed source release binary norms.
|
||||
#
|
||||
# - `make MODE=rel`
|
||||
# - More optimized
|
||||
# - Reasonably small
|
||||
@@ -74,14 +76,40 @@ TARGET_ARCH ?= \
|
||||
|
||||
endif
|
||||
|
||||
# Asan Mode
|
||||
#
|
||||
# Safer binaries good for backend production serving.
|
||||
#
|
||||
# - `make MODE=asan`
|
||||
# - Memory safety
|
||||
# - Production worthy
|
||||
# - Backtraces
|
||||
# - Debuggability
|
||||
# - Larger binaries
|
||||
|
||||
ifeq ($(MODE), asan)
|
||||
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
-O2
|
||||
|
||||
CONFIG_COPTS += \
|
||||
-fsanitize=address
|
||||
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
|
||||
endif
|
||||
|
||||
# Debug Mode
|
||||
#
|
||||
# - `make MODE=dbg`
|
||||
# - Backtraces
|
||||
# - Zero optimization
|
||||
# - Enables sanitization
|
||||
# - Enables stack canaries
|
||||
# - Enormous binaries (b/c ubsan suboptimalities)
|
||||
# - Enables asan
|
||||
# - Enables ubsan (TODO)
|
||||
# - Stack canaries
|
||||
# - No optimization (TODO)
|
||||
# - Enormous binaries
|
||||
|
||||
ifeq ($(MODE), dbg)
|
||||
|
||||
@@ -91,11 +119,10 @@ CONFIG_CPPFLAGS += \
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
$(FTRACE) \
|
||||
-Og
|
||||
-O2
|
||||
|
||||
CONFIG_COPTS += \
|
||||
$(SECURITY_BLANKETS) \
|
||||
$(SANITIZER)
|
||||
-fsanitize=address
|
||||
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
@@ -116,6 +143,7 @@ endif
|
||||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
|
||||
ifeq ($(MODE), tiny)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
@@ -143,6 +171,7 @@ endif
|
||||
# - No portability
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
|
||||
ifeq ($(MODE), tinylinux)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
@@ -172,6 +201,7 @@ endif
|
||||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
|
||||
ifeq ($(MODE), tinylinuxbsd)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
@@ -200,6 +230,7 @@ endif
|
||||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
|
||||
ifeq ($(MODE), tinysysv)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
@@ -228,6 +259,7 @@ endif
|
||||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
|
||||
ifeq ($(MODE), tinynowin)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
|
||||
@@ -77,7 +77,8 @@ PWD := $(shell pwd)
|
||||
IMAGE_BASE_VIRTUAL ?= 0x400000
|
||||
HELLO := $(shell build/hello)
|
||||
TMPDIR := $(shell build/findtmp)
|
||||
COMPILE := $(shell build/getcompile) -V$(shell build/getccversion $(CC))
|
||||
SPAWNER := $(shell build/getcompile) -V$(shell build/getccversion $(CC))
|
||||
COMPILE = $(SPAWNER) $(QUOTA)
|
||||
|
||||
export ADDR2LINE
|
||||
export LC_ALL
|
||||
@@ -181,7 +182,6 @@ DEFAULT_LDLIBS =
|
||||
|
||||
MCA = llvm-mca-10 \
|
||||
-mtriple=x86_64-pc-linux-gnu \
|
||||
-iterations=3 \
|
||||
-instruction-info \
|
||||
-iterations=3 \
|
||||
-all-stats \
|
||||
|
||||
@@ -79,4 +79,7 @@ o/$(MODE)/%.zip.o: % ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLA
|
||||
o/$(MODE)/%-gcc.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
|
||||
o/$(MODE)/%-clang.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@
|
||||
|
||||
o/$(MODE)/%.lua: %.lua o/$(MODE)/third_party/lua/luac.com
|
||||
@$(COMPILE) -ALUAC -T$@ o/$(MODE)/third_party/lua/luac.com -s -o $@ $<
|
||||
|
||||
o/$(MODE)/%-clang.asm: CC = $(CLANG)
|
||||
@@ -0,0 +1,403 @@
|
||||
/*-*- 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 The Mbed TLS Contributors │
|
||||
│ │
|
||||
│ Licensed under the Apache License, Version 2.0 (the "License"); │
|
||||
│ you may not use this file except in compliance with the License. │
|
||||
│ You may obtain a copy of the License at │
|
||||
│ │
|
||||
│ http://www.apache.org/licenses/LICENSE-2.0 │
|
||||
│ │
|
||||
│ Unless required by applicable law or agreed to in writing, software │
|
||||
│ distributed under the License is distributed on an "AS IS" BASIS, │
|
||||
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
|
||||
│ See the License for the specific language governing permissions and │
|
||||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
#include "third_party/mbedtls/debug.h"
|
||||
#include "third_party/mbedtls/entropy.h"
|
||||
#include "third_party/mbedtls/net_sockets.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
#include "third_party/mbedtls/x509_crt.h"
|
||||
|
||||
STATIC_YOINK("ssl_root_support");
|
||||
|
||||
#define MODE_NONE 0
|
||||
#define MODE_FILE 1
|
||||
#define MODE_SSL 2
|
||||
|
||||
#define DFL_MODE MODE_NONE
|
||||
#define DFL_FILENAME "cert.crt"
|
||||
#define DFL_CA_FILE ""
|
||||
#define DFL_CRL_FILE ""
|
||||
#define DFL_CA_PATH "zip:usr/share/ssl/root"
|
||||
#define DFL_SERVER_NAME "localhost"
|
||||
#define DFL_SERVER_PORT "4433"
|
||||
#define DFL_DEBUG_LEVEL 0
|
||||
#define DFL_PERMISSIVE 0
|
||||
|
||||
#define USAGE_IO \
|
||||
" ca_file=%%s file containing top-level CAs\n" \
|
||||
" ca_path=%%s dir containing top-level CAs\n" \
|
||||
" crl_file=%%s The single CRL file you want to use\n"
|
||||
|
||||
#define USAGE \
|
||||
"\n usage: %s param=<>...\n" \
|
||||
"\n acceptable parameters:\n" \
|
||||
" mode=file|ssl default: none\n" \
|
||||
" filename=%%s default: cert.crt\n" USAGE_IO \
|
||||
" server_name=%%s default: localhost\n" \
|
||||
" server_port=%%d default: 4433\n" \
|
||||
" debug_level=%%d default: 0 (disabled)\n" \
|
||||
" permissive=%%d default: 0 (disabled)\n" \
|
||||
"\n"
|
||||
|
||||
/*
|
||||
* global options
|
||||
*/
|
||||
struct options {
|
||||
int mode; /* the mode to run the application in */
|
||||
const char *filename; /* filename of the certificate file */
|
||||
const char *ca_file; /* the file with the CA certificate(s) */
|
||||
const char *crl_file; /* the file with the CRL to use */
|
||||
const char *ca_path; /* the path with the CA certificate(s) reside */
|
||||
const char *server_name; /* hostname of the server (client only) */
|
||||
const char *server_port; /* port on which the ssl service runs */
|
||||
int debug_level; /* level of debugging */
|
||||
int permissive; /* permissive parsing */
|
||||
} opt;
|
||||
|
||||
static void my_debug(void *ctx, int level, const char *file, int line,
|
||||
const char *str) {
|
||||
fprintf((FILE *)ctx, "%s:%04d: %s", file, line, str);
|
||||
fflush((FILE *)ctx);
|
||||
}
|
||||
|
||||
static int my_verify(void *data, mbedtls_x509_crt *crt, int depth,
|
||||
uint32_t *flags) {
|
||||
char buf[1024];
|
||||
printf("\nVerify requested for (Depth %d):\n", depth);
|
||||
mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
|
||||
printf("%s", buf);
|
||||
if (*flags) {
|
||||
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", *flags);
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbedtls_net_context server_fd;
|
||||
unsigned char buf[1024];
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_ssl_context ssl;
|
||||
mbedtls_ssl_config conf;
|
||||
mbedtls_x509_crt cacert;
|
||||
mbedtls_x509_crl cacrl;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int ret = 1;
|
||||
int exit_code = EXIT_FAILURE;
|
||||
int i, j;
|
||||
uint32_t flags;
|
||||
int verify = 0;
|
||||
char *p, *q;
|
||||
const char *pers = "cert_app";
|
||||
|
||||
/*
|
||||
* Set to sane values
|
||||
*/
|
||||
mbedtls_net_init(&server_fd);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
mbedtls_ssl_init(&ssl);
|
||||
mbedtls_ssl_config_init(&conf);
|
||||
mbedtls_x509_crt_init(&cacert);
|
||||
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
||||
mbedtls_x509_crl_init(&cacrl);
|
||||
#else
|
||||
/* Zeroize structure as CRL parsing is not supported and we have to pass
|
||||
it to the verify function */
|
||||
memset(&cacrl, 0, sizeof(mbedtls_x509_crl));
|
||||
#endif
|
||||
|
||||
if (argc == 0) {
|
||||
usage:
|
||||
printf(USAGE, program_invocation_name);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
opt.mode = DFL_MODE;
|
||||
opt.filename = DFL_FILENAME;
|
||||
opt.ca_file = DFL_CA_FILE;
|
||||
opt.crl_file = DFL_CRL_FILE;
|
||||
opt.ca_path = DFL_CA_PATH;
|
||||
opt.server_name = DFL_SERVER_NAME;
|
||||
opt.server_port = DFL_SERVER_PORT;
|
||||
opt.debug_level = DFL_DEBUG_LEVEL;
|
||||
opt.permissive = DFL_PERMISSIVE;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
p = argv[i];
|
||||
if ((q = strchr(p, '=')) == NULL) goto usage;
|
||||
*q++ = '\0';
|
||||
|
||||
for (j = 0; p + j < q; j++) {
|
||||
if (argv[i][j] >= 'A' && argv[i][j] <= 'Z') argv[i][j] |= 0x20;
|
||||
}
|
||||
|
||||
if (strcmp(p, "mode") == 0) {
|
||||
if (strcmp(q, "file") == 0)
|
||||
opt.mode = MODE_FILE;
|
||||
else if (strcmp(q, "ssl") == 0)
|
||||
opt.mode = MODE_SSL;
|
||||
else
|
||||
goto usage;
|
||||
} else if (strcmp(p, "filename") == 0)
|
||||
opt.filename = q;
|
||||
else if (strcmp(p, "ca_file") == 0)
|
||||
opt.ca_file = q;
|
||||
else if (strcmp(p, "crl_file") == 0)
|
||||
opt.crl_file = q;
|
||||
else if (strcmp(p, "ca_path") == 0)
|
||||
opt.ca_path = q;
|
||||
else if (strcmp(p, "server_name") == 0)
|
||||
opt.server_name = q;
|
||||
else if (strcmp(p, "server_port") == 0)
|
||||
opt.server_port = q;
|
||||
else if (strcmp(p, "debug_level") == 0) {
|
||||
opt.debug_level = atoi(q);
|
||||
if (opt.debug_level < 0 || opt.debug_level > 65535) goto usage;
|
||||
} else if (strcmp(p, "permissive") == 0) {
|
||||
opt.permissive = atoi(q);
|
||||
if (opt.permissive < 0 || opt.permissive > 1) goto usage;
|
||||
} else
|
||||
goto usage;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1.1. Load the trusted CA
|
||||
*/
|
||||
printf(" . Loading the CA root certificate ...");
|
||||
fflush(stdout);
|
||||
|
||||
if (strlen(opt.ca_path)) {
|
||||
if ((ret = mbedtls_x509_crt_parse_path(&cacert, opt.ca_path)) < 0) {
|
||||
printf(" failed\n ! mbedtls_x509_crt_parse_path returned -0x%x\n\n",
|
||||
(unsigned int)-ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
verify = 1;
|
||||
} else if (strlen(opt.ca_file)) {
|
||||
if ((ret = mbedtls_x509_crt_parse_file(&cacert, opt.ca_file)) < 0) {
|
||||
printf(" failed\n ! mbedtls_x509_crt_parse_file returned -0x%x\n\n",
|
||||
(unsigned int)-ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
verify = 1;
|
||||
}
|
||||
|
||||
printf(" ok (%d skipped)\n", ret);
|
||||
|
||||
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
||||
if (strlen(opt.crl_file)) {
|
||||
if ((ret = mbedtls_x509_crl_parse_file(&cacrl, opt.crl_file)) != 0) {
|
||||
printf(" failed\n ! mbedtls_x509_crl_parse returned -0x%x\n\n",
|
||||
(unsigned int)-ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
verify = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (opt.mode == MODE_FILE) {
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_x509_crt *cur = &crt;
|
||||
mbedtls_x509_crt_init(&crt);
|
||||
|
||||
/*
|
||||
* 1.1. Load the certificate(s)
|
||||
*/
|
||||
printf("\n . Loading the certificate(s) ...");
|
||||
fflush(stdout);
|
||||
|
||||
ret = mbedtls_x509_crt_parse_file(&crt, opt.filename);
|
||||
|
||||
if (ret < 0) {
|
||||
printf(" failed\n ! mbedtls_x509_crt_parse_file returned -0x%04x\n\n",
|
||||
-ret);
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (opt.permissive == 0 && ret > 0) {
|
||||
printf(" failed\n ! mbedtls_x509_crt_parse failed to parse %d "
|
||||
"certificates\n\n",
|
||||
ret);
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
printf(" ok\n");
|
||||
|
||||
/*
|
||||
* 1.2 Print the certificate(s)
|
||||
*/
|
||||
while (cur != NULL) {
|
||||
printf(" . Peer certificate information ...\n");
|
||||
ret = mbedtls_x509_crt_info((char *)buf, sizeof(buf) - 1, " ", cur);
|
||||
if (ret == -1) {
|
||||
printf(" failed\n ! mbedtls_x509_crt_info returned -0x%04x\n\n",
|
||||
-ret);
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
printf("%s\n", buf);
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1.3 Verify the certificate
|
||||
*/
|
||||
if (verify) {
|
||||
printf(" . Verifying X.509 certificate...");
|
||||
|
||||
if ((ret = mbedtls_x509_crt_verify(&crt, &cacert, &cacrl, NULL, &flags,
|
||||
my_verify, NULL)) != 0) {
|
||||
char vrfy_buf[512];
|
||||
|
||||
printf(" failed\n");
|
||||
|
||||
mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
|
||||
|
||||
printf("%s\n", vrfy_buf);
|
||||
} else
|
||||
printf(" ok\n");
|
||||
}
|
||||
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
} else if (opt.mode == MODE_SSL) {
|
||||
/*
|
||||
* 1. Initialize the RNG and the session data
|
||||
*/
|
||||
printf("\n . Seeding the random number generator...");
|
||||
fflush(stdout);
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
|
||||
(const unsigned char *)pers,
|
||||
strlen(pers))) != 0) {
|
||||
printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret);
|
||||
goto ssl_exit;
|
||||
}
|
||||
|
||||
printf(" ok\n");
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
mbedtls_debug_set_threshold(opt.debug_level);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 2. Start the connection
|
||||
*/
|
||||
printf(" . Connecting to tcp/%s/%s...\n", opt.server_name,
|
||||
opt.server_port);
|
||||
|
||||
if ((ret = mbedtls_net_connect(&server_fd, opt.server_name, opt.server_port,
|
||||
MBEDTLS_NET_PROTO_TCP)) != 0) {
|
||||
printf(" ! mbedtls_net_connect returned -0x%04x\n\n", -ret);
|
||||
goto ssl_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* 3. Setup stuff
|
||||
*/
|
||||
if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
|
||||
printf(" ! mbedtls_ssl_config_defaults returned -0x%04x\n\n", -ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
|
||||
mbedtls_ssl_conf_verify(&conf, my_verify, NULL);
|
||||
} else
|
||||
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
|
||||
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||
mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
|
||||
|
||||
if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
|
||||
printf(" ! mbedtls_ssl_setup returned -0x%04x\n\n", -ret);
|
||||
goto ssl_exit;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_ssl_set_hostname(&ssl, opt.server_name)) != 0) {
|
||||
printf(" ! mbedtls_ssl_set_hostname returned -0x%04x\n\n", -ret);
|
||||
goto ssl_exit;
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv,
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* 4. Handshake
|
||||
*/
|
||||
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
printf(" ! mbedtls_ssl_handshake returned -0x%04x\n\n", -ret);
|
||||
goto ssl_exit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 5. Print the certificate
|
||||
*/
|
||||
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
printf(" . Peer certificate information ... skipped\n");
|
||||
#else
|
||||
printf(" . Peer certificate information ...\n");
|
||||
ret = mbedtls_x509_crt_info((char *)buf, sizeof(buf) - 1, " ",
|
||||
mbedtls_ssl_get_peer_cert(&ssl));
|
||||
if (ret == -1) {
|
||||
printf(" failed\n ! mbedtls_x509_crt_info returned -0x%04x\n\n", -ret);
|
||||
goto ssl_exit;
|
||||
}
|
||||
|
||||
printf("%s\n", buf);
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
|
||||
mbedtls_ssl_close_notify(&ssl);
|
||||
|
||||
ssl_exit:
|
||||
mbedtls_ssl_free(&ssl);
|
||||
mbedtls_ssl_config_free(&conf);
|
||||
} else
|
||||
goto usage;
|
||||
|
||||
exit_code = MBEDTLS_EXIT_SUCCESS;
|
||||
|
||||
exit:
|
||||
|
||||
mbedtls_net_free(&server_fd);
|
||||
mbedtls_x509_crt_free(&cacert);
|
||||
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
||||
mbedtls_x509_crl_free(&cacrl);
|
||||
#endif
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
|
||||
mbedtls_exit(exit_code);
|
||||
}
|
||||
+322
-65
@@ -8,24 +8,49 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/goodsocket.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/slice.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/shut.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/so.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "libc/sysv/consts/tcp.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "net/http/http.h"
|
||||
#include "net/http/url.h"
|
||||
#include "net/https/https.h"
|
||||
#include "net/https/sslcache.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
#include "third_party/mbedtls/debug.h"
|
||||
#include "third_party/mbedtls/error.h"
|
||||
#include "third_party/mbedtls/pk.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
#include "third_party/mbedtls/ssl_ticket.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Downloads HTTP URL to stdout.
|
||||
@@ -34,35 +59,138 @@
|
||||
* o//examples/curl.com http://justine.lol/ape.html
|
||||
*/
|
||||
|
||||
#define HasHeader(H) (!!msg.headers[H].a)
|
||||
#define HeaderData(H) (p + msg.headers[H].a)
|
||||
#define HeaderLength(H) (msg.headers[H].b - msg.headers[H].a)
|
||||
#define HeaderEqualCase(H, S) \
|
||||
SlicesEqualCase(S, strlen(S), HeaderData(H), HeaderLength(H))
|
||||
|
||||
static bool TuneSocket(int fd, int a, int b, int x) {
|
||||
if (!b) return false;
|
||||
return setsockopt(fd, a, b, &x, sizeof(x)) != -1;
|
||||
}
|
||||
|
||||
static int TlsSend(void *c, const unsigned char *p, size_t n) {
|
||||
int rc;
|
||||
NOISEF("begin send %zu", n);
|
||||
CHECK_NE(-1, (rc = write(*(int *)c, p, n)));
|
||||
NOISEF("end send %zu", n);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
|
||||
int r;
|
||||
struct iovec v[2];
|
||||
static unsigned a, b;
|
||||
static unsigned char t[4096];
|
||||
if (a < b) {
|
||||
r = MIN(n, b - a);
|
||||
memcpy(p, t + a, r);
|
||||
if ((a += r) == b) a = b = 0;
|
||||
return r;
|
||||
}
|
||||
v[0].iov_base = p;
|
||||
v[0].iov_len = n;
|
||||
v[1].iov_base = t;
|
||||
v[1].iov_len = sizeof(t);
|
||||
NOISEF("begin recv %zu", n + sizeof(t) - b);
|
||||
CHECK_NE(-1, (r = readv(*(int *)c, v, 2)));
|
||||
NOISEF("end recv %zu", r);
|
||||
if (r > n) b = r - n;
|
||||
return MIN(n, r);
|
||||
}
|
||||
|
||||
static wontreturn void PrintUsage(FILE *f, int rc) {
|
||||
fprintf(f, "usage: %s [-ksvV] URL\n", program_invocation_name);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!NoDebug()) showcrashreports();
|
||||
xsigaction(SIGPIPE, SIG_IGN, 0, 0, 0);
|
||||
|
||||
/*
|
||||
* Read flags.
|
||||
*/
|
||||
int opt;
|
||||
struct Headers {
|
||||
size_t n;
|
||||
char **p;
|
||||
} headers = {0};
|
||||
int method = kHttpGet;
|
||||
bool authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
|
||||
__log_level = kLogWarn;
|
||||
while ((opt = getopt(argc, argv, "qksvVIX:H:A:")) != -1) {
|
||||
switch (opt) {
|
||||
case 's':
|
||||
case 'q':
|
||||
break;
|
||||
case 'v':
|
||||
++__log_level;
|
||||
break;
|
||||
case 'I':
|
||||
method = kHttpHead;
|
||||
break;
|
||||
case 'A':
|
||||
agent = optarg;
|
||||
break;
|
||||
case 'H':
|
||||
headers.p = realloc(headers.p, ++headers.n * sizeof(*headers.p));
|
||||
headers.p[headers.n - 1] = optarg;
|
||||
break;
|
||||
case 'X':
|
||||
CHECK((method = GetHttpMethod(optarg, strlen(optarg))));
|
||||
break;
|
||||
case 'V':
|
||||
++mbedtls_debug_threshold;
|
||||
break;
|
||||
case 'k':
|
||||
authmode = MBEDTLS_SSL_VERIFY_NONE;
|
||||
break;
|
||||
case 'h':
|
||||
PrintUsage(stdout, EXIT_SUCCESS);
|
||||
default:
|
||||
PrintUsage(stderr, EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get argument.
|
||||
*/
|
||||
const char *urlarg;
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "USAGE: %s URL\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
urlarg = argv[1];
|
||||
if (optind == argc) PrintUsage(stderr, EX_USAGE);
|
||||
urlarg = argv[optind];
|
||||
|
||||
/*
|
||||
* Parse URL.
|
||||
*/
|
||||
struct Url url;
|
||||
char *host, *port;
|
||||
bool usessl = false;
|
||||
_gc(ParseUrl(urlarg, -1, &url));
|
||||
_gc(url.params.p);
|
||||
if (url.scheme.n &&
|
||||
!(url.scheme.n == 4 && !memcasecmp(url.scheme.p, "http", 4))) {
|
||||
fprintf(stderr, "ERROR: NOT AN HTTP URL: %s\n", urlarg);
|
||||
exit(1);
|
||||
if (url.scheme.n) {
|
||||
if (url.scheme.n == 5 && !memcasecmp(url.scheme.p, "https", 5)) {
|
||||
usessl = true;
|
||||
} else if (!(url.scheme.n == 4 && !memcasecmp(url.scheme.p, "http", 4))) {
|
||||
fprintf(stderr, "error: not an http/https url: %s\n", urlarg);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (url.host.n) {
|
||||
host = _gc(strndup(url.host.p, url.host.n));
|
||||
if (url.port.n) {
|
||||
port = _gc(strndup(url.port.p, url.port.n));
|
||||
} else {
|
||||
port = usessl ? "443" : "80";
|
||||
}
|
||||
} else {
|
||||
host = "127.0.0.1";
|
||||
port = usessl ? "443" : "80";
|
||||
}
|
||||
host = firstnonnull(_gc(strndup(url.host.p, url.host.n)), "127.0.0.1");
|
||||
port = url.port.n ? _gc(strndup(url.port.p, url.port.n)) : "80";
|
||||
port = _gc(xasprintf("%hu", atoi(port)));
|
||||
if (!IsAcceptableHost(host, -1)) {
|
||||
fprintf(stderr, "ERROR: INVALID HOST: %s\n", urlarg);
|
||||
fprintf(stderr, "error: invalid host: %s\n", urlarg);
|
||||
exit(1);
|
||||
}
|
||||
url.fragment.p = 0, url.fragment.n = 0;
|
||||
@@ -81,68 +209,197 @@ int main(int argc, char *argv[]) {
|
||||
/*
|
||||
* Create HTTP message.
|
||||
*/
|
||||
const char *msg;
|
||||
msg = _gc(xasprintf("GET %s HTTP/1.1\r\n"
|
||||
"Host: %s:%s\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-Length: 0\r\n"
|
||||
"Accept: text/plain; */*\r\n"
|
||||
"Accept-Encoding: identity\r\n"
|
||||
"User-Agent: github.com/jart/cosmopolitan\r\n"
|
||||
"\r\n",
|
||||
_gc(EncodeUrl(&url, 0)), host, port));
|
||||
char *request = 0;
|
||||
appendf(&request,
|
||||
"%s %s HTTP/1.1\r\n"
|
||||
"Host: %s:%s\r\n"
|
||||
"Connection: close\r\n"
|
||||
"User-Agent: %s\r\n",
|
||||
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), host, port, agent);
|
||||
for (int i = 0; i < headers.n; ++i) {
|
||||
appendf(&request, "%s\r\n", headers.p[i]);
|
||||
}
|
||||
appendf(&request, "\r\n");
|
||||
|
||||
/*
|
||||
* Setup crypto.
|
||||
*/
|
||||
mbedtls_ssl_config conf;
|
||||
mbedtls_ssl_context ssl;
|
||||
mbedtls_x509_crt *cachain = 0;
|
||||
mbedtls_ctr_drbg_context drbg;
|
||||
if (usessl) {
|
||||
mbedtls_ssl_init(&ssl);
|
||||
mbedtls_ctr_drbg_init(&drbg);
|
||||
mbedtls_ssl_config_init(&conf);
|
||||
cachain = GetSslRoots();
|
||||
CHECK_EQ(0, mbedtls_ctr_drbg_seed(&drbg, GetEntropy, 0, "justine", 7));
|
||||
CHECK_EQ(0, mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT));
|
||||
mbedtls_ssl_conf_authmode(&conf, authmode);
|
||||
mbedtls_ssl_conf_ca_chain(&conf, cachain, 0);
|
||||
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &drbg);
|
||||
if (!IsTiny()) mbedtls_ssl_conf_dbg(&conf, TlsDebug, 0);
|
||||
CHECK_EQ(0, mbedtls_ssl_setup(&ssl, &conf));
|
||||
CHECK_EQ(0, mbedtls_ssl_set_hostname(&ssl, host));
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform DNS lookup.
|
||||
*/
|
||||
struct addrinfo *addr, *addrs;
|
||||
struct addrinfo *addr;
|
||||
struct addrinfo hints = {.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
.ai_protocol = IPPROTO_TCP,
|
||||
.ai_flags = AI_NUMERICSERV};
|
||||
CHECK_EQ(EAI_SUCCESS, getaddrinfo(host, port, &hints, &addrs));
|
||||
for (addr = addrs; addr; addr = addr->ai_next) {
|
||||
CHECK_EQ(EAI_SUCCESS, getaddrinfo(host, port, &hints, &addr));
|
||||
|
||||
/*
|
||||
* Send HTTP Message.
|
||||
*/
|
||||
int sock;
|
||||
CHECK_NE(-1, (sock = socket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol)));
|
||||
CHECK_NE(-1, connect(sock, addr->ai_addr, addr->ai_addrlen));
|
||||
CHECK_EQ(strlen(msg), write(sock, msg, strlen(msg)));
|
||||
shutdown(sock, SHUT_WR);
|
||||
|
||||
/*
|
||||
* Handle response.
|
||||
*/
|
||||
ssize_t rc;
|
||||
char buf[1500];
|
||||
size_t got, toto;
|
||||
unsigned long need;
|
||||
const char *msg, *crlfcrlf;
|
||||
buf[0] = '\0';
|
||||
CHECK_NE(-1, (rc = read(sock, buf, sizeof(buf))));
|
||||
got = rc;
|
||||
CHECK(startswith(buf, "HTTP/1.1 200"), "%`'.*s", got, buf);
|
||||
CHECK_NOTNULL((crlfcrlf = memmem(buf, got, "\r\n\r\n", 4)));
|
||||
need = strtol((char *)firstnonnull(
|
||||
memmem(buf, crlfcrlf - buf, "\r\nContent-Length: ", 18),
|
||||
firstnonnull(memmem(buf, crlfcrlf - buf,
|
||||
"\r\ncontent-length: ", 18),
|
||||
"\r\nContent-Length: -1")) +
|
||||
18,
|
||||
NULL, 10);
|
||||
got = MIN(got - (crlfcrlf + 4 - buf), need);
|
||||
CHECK_EQ(got, write(1, crlfcrlf + 4, got));
|
||||
for (toto = got; toto < need; toto += got) {
|
||||
CHECK_NE(-1, (rc = read(sock, buf, sizeof(buf))));
|
||||
if (!(got = rc)) exit(18);
|
||||
got = MIN(got, need - toto);
|
||||
CHECK_EQ(got, write(1, buf, got));
|
||||
/*
|
||||
* Connect to server.
|
||||
*/
|
||||
int ret, sock;
|
||||
CHECK_NE(-1, (sock = GoodSocket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol, false,
|
||||
&(struct timeval){-60})));
|
||||
CHECK_NE(-1, connect(sock, addr->ai_addr, addr->ai_addrlen));
|
||||
freeaddrinfo(addr);
|
||||
if (usessl) {
|
||||
mbedtls_ssl_set_bio(&ssl, &sock, TlsSend, 0, TlsRecv);
|
||||
if ((ret = mbedtls_ssl_handshake(&ssl))) {
|
||||
TlsDie("ssl handshake", ret);
|
||||
}
|
||||
close(sock);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send HTTP Message.
|
||||
*/
|
||||
size_t n;
|
||||
n = appendz(request).i;
|
||||
if (usessl) {
|
||||
ret = mbedtls_ssl_write(&ssl, request, n);
|
||||
if (ret != n) TlsDie("ssl write", ret);
|
||||
} else {
|
||||
CHECK_EQ(n, write(sock, request, n));
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle response.
|
||||
*/
|
||||
int t;
|
||||
char *p;
|
||||
ssize_t rc;
|
||||
struct HttpMessage msg;
|
||||
struct HttpUnchunker u;
|
||||
size_t g, i, hdrlen, paylen;
|
||||
InitHttpMessage(&msg, kHttpResponse);
|
||||
for (p = 0, hdrlen = paylen = t = i = n = 0;;) {
|
||||
if (i == n) {
|
||||
n += 1000;
|
||||
n += n >> 1;
|
||||
p = realloc(p, n);
|
||||
}
|
||||
if (usessl) {
|
||||
if ((rc = mbedtls_ssl_read(&ssl, p + i, n - i)) < 0) {
|
||||
if (rc == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
|
||||
rc = 0;
|
||||
} else {
|
||||
TlsDie("ssl read", rc);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CHECK_NE(-1, (rc = read(sock, p + i, n - i)));
|
||||
}
|
||||
g = rc;
|
||||
i += g;
|
||||
switch (t) {
|
||||
case kHttpClientStateHeaders:
|
||||
CHECK(g);
|
||||
CHECK_NE(-1, (rc = ParseHttpMessage(&msg, p, i)));
|
||||
if (rc) {
|
||||
hdrlen = rc;
|
||||
if (100 <= msg.status && msg.status <= 199) {
|
||||
CHECK(!HasHeader(kHttpContentLength) ||
|
||||
HeaderEqualCase(kHttpContentLength, "0"));
|
||||
CHECK(!HasHeader(kHttpTransferEncoding) ||
|
||||
HeaderEqualCase(kHttpTransferEncoding, "identity"));
|
||||
DestroyHttpMessage(&msg);
|
||||
InitHttpMessage(&msg, kHttpResponse);
|
||||
memmove(p, p + hdrlen, i - hdrlen);
|
||||
i -= hdrlen;
|
||||
break;
|
||||
}
|
||||
if (method == kHttpHead) {
|
||||
CHECK_EQ(hdrlen, write(1, p, hdrlen));
|
||||
goto Finished;
|
||||
} else if (msg.status == 204 || msg.status == 304) {
|
||||
goto Finished;
|
||||
}
|
||||
if (HasHeader(kHttpTransferEncoding) &&
|
||||
!HeaderEqualCase(kHttpTransferEncoding, "identity")) {
|
||||
CHECK(HeaderEqualCase(kHttpTransferEncoding, "chunked"));
|
||||
t = kHttpClientStateBodyChunked;
|
||||
memset(&u, 0, sizeof(u));
|
||||
goto Chunked;
|
||||
} else if (HasHeader(kHttpContentLength)) {
|
||||
CHECK_NE(-1, (rc = ParseContentLength(
|
||||
HeaderData(kHttpContentLength),
|
||||
HeaderLength(kHttpContentLength))));
|
||||
t = kHttpClientStateBodyLengthed;
|
||||
paylen = rc;
|
||||
if (paylen > i - hdrlen) {
|
||||
CHECK_EQ(i - hdrlen, write(1, p + hdrlen, i - hdrlen));
|
||||
} else {
|
||||
CHECK_EQ(paylen, write(1, p + hdrlen, paylen));
|
||||
goto Finished;
|
||||
}
|
||||
} else {
|
||||
t = kHttpClientStateBody;
|
||||
CHECK_EQ(i - hdrlen, write(1, p + hdrlen, i - hdrlen));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kHttpClientStateBody:
|
||||
if (!g) goto Finished;
|
||||
CHECK_EQ(g, write(1, p + i - g, g));
|
||||
break;
|
||||
case kHttpClientStateBodyLengthed:
|
||||
CHECK(g);
|
||||
if (i - hdrlen > paylen) g = hdrlen + paylen - (i - g);
|
||||
CHECK_EQ(g, write(1, p + i - g, g));
|
||||
if (i - hdrlen >= paylen) goto Finished;
|
||||
break;
|
||||
case kHttpClientStateBodyChunked:
|
||||
Chunked:
|
||||
CHECK_NE(-1, (rc = Unchunk(&u, p + hdrlen, i - hdrlen, &paylen)));
|
||||
if (rc) {
|
||||
CHECK_EQ(paylen, write(1, p + hdrlen, paylen));
|
||||
goto Finished;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Close connection.
|
||||
*/
|
||||
Finished:
|
||||
CHECK_NE(-1, close(sock));
|
||||
|
||||
/*
|
||||
* Free memory.
|
||||
*/
|
||||
free(p);
|
||||
free(headers.p);
|
||||
if (usessl) {
|
||||
mbedtls_ssl_free(&ssl);
|
||||
mbedtls_ctr_drbg_free(&drbg);
|
||||
mbedtls_ssl_config_free(&conf);
|
||||
mbedtls_x509_crt_free(cachain);
|
||||
mbedtls_ctr_drbg_free(&drbg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -66,8 +66,10 @@ EXAMPLES_DIRECTDEPS = \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
NET_HTTP \
|
||||
NET_HTTPS \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_QUICKJS \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_LUA \
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Fast Division Using Multiplication Tutorial
|
||||
*
|
||||
* Expected program output:
|
||||
*
|
||||
* 23 / 3 = 7
|
||||
* 0x5555555555555556 1 1
|
||||
* division l: 16𝑐 5𝑛𝑠
|
||||
* fast div l: 5𝑐 2𝑛𝑠
|
||||
* precomps l: 70𝑐 23𝑛𝑠
|
||||
*/
|
||||
|
||||
struct Divisor {
|
||||
uint64_t m;
|
||||
uint8_t s;
|
||||
uint8_t t;
|
||||
};
|
||||
|
||||
struct Divisor GetDivisor(uint64_t d) {
|
||||
int b;
|
||||
uint128_t x;
|
||||
if (!d) raise(SIGFPE);
|
||||
b = __builtin_clzll(d) ^ 63;
|
||||
x = -d & (((1ull << b) - 1) | (1ull << b));
|
||||
return (struct Divisor){(x << 64) / d + 1, MIN(1, b + 1), MAX(0, b)};
|
||||
}
|
||||
|
||||
uint64_t Divide(uint64_t x, struct Divisor d) {
|
||||
uint128_t t;
|
||||
uint64_t l, h;
|
||||
t = d.m;
|
||||
t *= x;
|
||||
l = t;
|
||||
h = t >> 64;
|
||||
l = (x - h) >> d.s;
|
||||
return (h + l) >> d.t;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("23 / 3 = %ld\n", Divide(23, GetDivisor(3)));
|
||||
volatile struct Divisor v = GetDivisor(3);
|
||||
volatile uint64_t x = 23, y = 3, z;
|
||||
EZBENCH2("division", donothing, z = x / y);
|
||||
EZBENCH2("fast div", donothing, z = Divide(x, v));
|
||||
EZBENCH2("precomp ", donothing, v = GetDivisor(y));
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Fast Modulus Using Multiplication Tutorial
|
||||
*
|
||||
* Expected program output:
|
||||
*
|
||||
* 23 / 3 = 7
|
||||
* 0x5555555555555556 1 1
|
||||
* modulus l: 15𝑐 5𝑛𝑠
|
||||
* fastmod l: 4𝑐 1𝑛𝑠
|
||||
* precomp l: 18𝑐 6𝑛𝑠
|
||||
*/
|
||||
|
||||
struct Modulus {
|
||||
uint64_t c;
|
||||
uint64_t d;
|
||||
};
|
||||
|
||||
struct Modulus GetModulus(uint64_t d) {
|
||||
return (struct Modulus){0xFFFFFFFFFFFFFFFFull / d + 1, d};
|
||||
}
|
||||
|
||||
uint64_t Modulus(uint64_t x, struct Modulus m) {
|
||||
return ((uint128_t)(m.c * x) * m.d) >> 64;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("%#lx %% %d = %d\n", 0x23, 3, Modulus(23, GetModulus(3)));
|
||||
printf("%#lx %% %d = %d\n", 0x123, 17, Modulus(0x123, GetModulus(17)));
|
||||
volatile struct Modulus v = GetModulus(3);
|
||||
volatile uint64_t x = 23, y = 3, z;
|
||||
EZBENCH2("modulus", donothing, z = x % y);
|
||||
EZBENCH2("fastmod", donothing, z = Modulus(x, v));
|
||||
EZBENCH2("precomp", donothing, v = GetModulus(y));
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/runtime/sysconf.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int c, n;
|
||||
char a[22];
|
||||
if ((c = GetCpuCount())) {
|
||||
n = int64toarray_radix10(c, a);
|
||||
a[n++] = '\n';
|
||||
return write(1, a, n) == n ? 0 : 1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/rand/xorshift.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
|
||||
#define B 4096
|
||||
|
||||
bool isdone;
|
||||
bool isbinary;
|
||||
unsigned long count = -1;
|
||||
|
||||
uint64_t bcast(uint64_t f(void)) {
|
||||
unsigned i;
|
||||
uint64_t x;
|
||||
for (x = i = 0; i < 8; ++i) {
|
||||
x <<= 8;
|
||||
x |= f() & 255;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t randv6(void) {
|
||||
static int16_t gorp;
|
||||
gorp = (gorp + 625) & 077777;
|
||||
return gorp;
|
||||
}
|
||||
|
||||
uint64_t randv7(void) {
|
||||
static uint32_t randx = 1;
|
||||
return ((randx = randx * 1103515245 + 12345) >> 16) & 077777;
|
||||
}
|
||||
|
||||
uint64_t zero(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t inc(void) {
|
||||
static uint64_t x;
|
||||
return x++;
|
||||
}
|
||||
|
||||
uint64_t unixv6(void) {
|
||||
return bcast(randv6);
|
||||
}
|
||||
|
||||
uint64_t unixv7(void) {
|
||||
return bcast(randv7);
|
||||
}
|
||||
|
||||
uint64_t ape(void) {
|
||||
static int i;
|
||||
if ((i += 8) > _end - _base) i = 8;
|
||||
return READ64LE(_base + i);
|
||||
}
|
||||
|
||||
uint64_t moby(void) {
|
||||
static int i;
|
||||
if ((i += 8) > kMobySize) i = 8;
|
||||
return READ64LE(kMoby + i);
|
||||
}
|
||||
|
||||
uint64_t knuth(void) {
|
||||
uint64_t a, b;
|
||||
static uint64_t x = 1;
|
||||
x *= 6364136223846793005;
|
||||
x += 1442695040888963407;
|
||||
a = x >> 32;
|
||||
x *= 6364136223846793005;
|
||||
x += 1442695040888963407;
|
||||
b = x >> 32;
|
||||
return a | b << 32;
|
||||
}
|
||||
|
||||
uint64_t vigna(void) {
|
||||
static uint64_t x;
|
||||
uint64_t z = (x += 0x9e3779b97f4a7c15);
|
||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
uint64_t rngset64(void) {
|
||||
static unsigned i;
|
||||
static uint64_t s;
|
||||
if (!i) {
|
||||
s = rand64();
|
||||
i = (s + 1) & (511);
|
||||
}
|
||||
return MarsagliaXorshift64(&s);
|
||||
}
|
||||
|
||||
uint64_t xorshift64(void) {
|
||||
static uint64_t s = kMarsagliaXorshift64Seed;
|
||||
return MarsagliaXorshift64(&s);
|
||||
}
|
||||
|
||||
uint64_t xorshift32(void) {
|
||||
static uint32_t s = kMarsagliaXorshift32Seed;
|
||||
uint64_t a = MarsagliaXorshift32(&s);
|
||||
uint64_t b = MarsagliaXorshift32(&s);
|
||||
return (uint64_t)a << 32 | b;
|
||||
}
|
||||
|
||||
uint64_t libc(void) {
|
||||
uint64_t x;
|
||||
CHECK_EQ(8, getrandom(&x, 8, 0));
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t kernel(void) {
|
||||
uint64_t x;
|
||||
CHECK_EQ(8, getrandom(&x, 8, GRND_NORDRND));
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t hardware(void) {
|
||||
uint64_t x;
|
||||
CHECK_EQ(8, getrandom(&x, 8, GRND_NOSYSTEM));
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t rdrnd(void) {
|
||||
char cf;
|
||||
int i = 0;
|
||||
uint64_t x;
|
||||
CHECK(X86_HAVE(RDRND));
|
||||
for (;;) {
|
||||
asm volatile(CFLAG_ASM("rdrand\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) return x;
|
||||
if (++i < 10) continue;
|
||||
asm volatile("pause");
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t rdseed(void) {
|
||||
char cf;
|
||||
int i = 0;
|
||||
uint64_t x;
|
||||
CHECK(X86_HAVE(RDSEED));
|
||||
for (;;) {
|
||||
asm volatile(CFLAG_ASM("rdseed\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) return x;
|
||||
if (++i < 10) continue;
|
||||
asm volatile("pause");
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const struct Function {
|
||||
const char *s;
|
||||
uint64_t (*f)(void);
|
||||
} kFunctions[] = {
|
||||
{"ape", ape}, //
|
||||
{"hardware", hardware}, //
|
||||
{"inc", inc}, //
|
||||
{"kernel", kernel}, //
|
||||
{"knuth", knuth}, //
|
||||
{"libc", libc}, //
|
||||
{"moby", moby}, //
|
||||
{"rand64", rand64}, //
|
||||
{"rdrand", rdrnd}, //
|
||||
{"rdrnd", rdrnd}, //
|
||||
{"rdseed", rdseed}, //
|
||||
{"rngset64", rngset64}, //
|
||||
{"unixv6", unixv6}, //
|
||||
{"unixv7", unixv7}, //
|
||||
{"vigna", vigna}, //
|
||||
{"xorshift32", xorshift32}, //
|
||||
{"xorshift64", xorshift64}, //
|
||||
{"zero", zero}, //
|
||||
};
|
||||
|
||||
void OnInt(int sig) {
|
||||
isdone = true;
|
||||
}
|
||||
|
||||
wontreturn void PrintUsage(FILE *f, int rc) {
|
||||
fprintf(f, "Usage: %s [-b] [-n NUM] [FUNC]\n", program_invocation_name);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char *p;
|
||||
int i, opt;
|
||||
ssize_t rc;
|
||||
uint64_t x;
|
||||
static char buf[B];
|
||||
uint64_t (*f)(void);
|
||||
|
||||
while ((opt = getopt(argc, argv, "hbc:n:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'b':
|
||||
isbinary = true;
|
||||
break;
|
||||
case 'c':
|
||||
case 'n':
|
||||
count = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'h':
|
||||
PrintUsage(stdout, EXIT_SUCCESS);
|
||||
default:
|
||||
PrintUsage(stderr, EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
f = libc;
|
||||
} else {
|
||||
for (f = 0, i = 0; i < ARRAYLEN(kFunctions); ++i) {
|
||||
if (!strcasecmp(argv[optind], kFunctions[i].s)) {
|
||||
f = kFunctions[i].f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!f) {
|
||||
fprintf(stderr, "unknown function: %`'s\n", argv[optind]);
|
||||
fprintf(stderr, "try: ");
|
||||
for (i = 0; i < ARRAYLEN(kFunctions); ++i) {
|
||||
if (i) fprintf(stderr, ", ");
|
||||
fprintf(stderr, "%s", kFunctions[i].s);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
signal(SIGINT, OnInt);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (!isbinary) {
|
||||
for (; count && !isdone && !feof(stdout); --count) {
|
||||
printf("0x%016lx\n", f());
|
||||
}
|
||||
fflush(stdout);
|
||||
return ferror(stdout) ? 1 : 0;
|
||||
}
|
||||
|
||||
while (count && !isdone) {
|
||||
if (count >= B) {
|
||||
for (i = 0; i < B / 8; ++i) {
|
||||
x = f();
|
||||
p = buf + i * 8;
|
||||
WRITE64LE(p, x);
|
||||
}
|
||||
for (i = 0; i < B; i += rc) {
|
||||
rc = write(1, buf + i, B - i);
|
||||
if (rc == -1 && errno == EPIPE) exit(1);
|
||||
if (rc == -1) perror("write"), exit(1);
|
||||
}
|
||||
} else {
|
||||
x = f();
|
||||
rc = write(1, &x, MIN(8, count));
|
||||
}
|
||||
if (!rc) break;
|
||||
if (rc == -1 && errno == EPIPE) exit(1);
|
||||
if (rc == -1) perror("write"), exit(1);
|
||||
count -= rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/stb/stb_image.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Utility for printing HTML <img> tags.
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
void *p;
|
||||
size_t n;
|
||||
int yn, xn, cn;
|
||||
if (argc != 2) return 1;
|
||||
if (!(p = xslurp(argv[1], &n))) return 2;
|
||||
if (!(p = stbi_load_from_memory(p, n, &xn, &yn, &cn, 0))) return 3;
|
||||
printf("<img src=\"%s\" width=\"%d\" height=\"%d\"\n"
|
||||
" alt=\"[%s]\">\n",
|
||||
argv[1], (xn + 1) >> 1, (yn + 1) >> 1, argv[1]);
|
||||
return 0;
|
||||
}
|
||||
@@ -267,8 +267,12 @@ int editorReadKey(int64_t fd) {
|
||||
if (read(fd, seq + 2, 1) == 0) return CTRL('[');
|
||||
if (seq[2] == '~') {
|
||||
switch (seq[1]) {
|
||||
case '1':
|
||||
return HOME_KEY;
|
||||
case '3':
|
||||
return DEL_KEY;
|
||||
case '4':
|
||||
return END_KEY;
|
||||
case '5':
|
||||
return PAGE_UP;
|
||||
case '6':
|
||||
|
||||
@@ -106,6 +106,7 @@ int main(int argc, char *argv[]) {
|
||||
sigaction(SIGQUIT, &dflt, 0);
|
||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||
execvp(argv[1], argv + 1);
|
||||
fprintf(stderr, "exec failed %d\n", errno);
|
||||
_Exit(127);
|
||||
}
|
||||
while (wait4(pid, &wstatus, 0, &rusage) == -1) {
|
||||
|
||||
+16
-36
@@ -9,47 +9,27 @@
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Fast Growable Strings Tutorial
|
||||
*/
|
||||
|
||||
struct Buffer {
|
||||
size_t i, n;
|
||||
char *p;
|
||||
};
|
||||
|
||||
int AppendFmt(struct Buffer *b, const char *fmt, ...) {
|
||||
int n;
|
||||
char *p;
|
||||
va_list va, vb;
|
||||
va_start(va, fmt);
|
||||
va_copy(vb, va);
|
||||
n = vsnprintf(b->p + b->i, b->n - b->i, fmt, va);
|
||||
if (n >= b->n - b->i) {
|
||||
do {
|
||||
if (b->n) {
|
||||
b->n += b->n >> 1; /* this is the important line */
|
||||
} else {
|
||||
b->n = 16;
|
||||
}
|
||||
} while (b->i + n > b->n);
|
||||
b->p = realloc(b->p, b->n);
|
||||
vsnprintf(b->p + b->i, b->n - b->i, fmt, vb);
|
||||
}
|
||||
va_end(vb);
|
||||
va_end(va);
|
||||
b->i += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct Buffer b = {0};
|
||||
AppendFmt(&b, "hello ");
|
||||
AppendFmt(&b, " world\n");
|
||||
AppendFmt(&b, "%d arg%s\n", argc, argc == 1 ? "" : "s");
|
||||
AppendFmt(&b, "%s\n", "have a nice day");
|
||||
write(1, b.p, b.i);
|
||||
free(b.p);
|
||||
char *b = 0;
|
||||
appendf(&b, "hello "); // guarantees nul terminator
|
||||
CHECK_EQ(6, strlen(b));
|
||||
CHECK_EQ(6, appendz(b).i);
|
||||
appendf(&b, " world\n");
|
||||
CHECK_EQ(13, strlen(b));
|
||||
CHECK_EQ(13, appendz(b).i);
|
||||
appendd(&b, "\0", 1); // supports binary
|
||||
CHECK_EQ(13, strlen(b));
|
||||
CHECK_EQ(14, appendz(b).i);
|
||||
appendf(&b, "%d arg%s\n", argc, argc == 1 ? "" : "s");
|
||||
appendf(&b, "%s\n", "have a nice day");
|
||||
write(1, b, appendz(b).i);
|
||||
free(b);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_BITS_NEWBIE_H_
|
||||
#define COSMOPOLITAN_LIBC_BITS_NEWBIE_H_
|
||||
#include "libc/bits/bswap.h"
|
||||
|
||||
/*
|
||||
* Macros for newbies.
|
||||
* https://justine.lol/endian.html
|
||||
*/
|
||||
|
||||
#define BYTE_ORDER __BYTE_ORDER__
|
||||
#define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
|
||||
#define BIG_ENDIAN __ORDER_BIG_ENDIAN__
|
||||
#define PDP_ENDIAN __ORDER_PDP_ENDIAN__
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define htobe16(x) bswap_16(x)
|
||||
#define be16toh(x) bswap_16(x)
|
||||
#define betoh16(x) bswap_16(x)
|
||||
#define htobe32(x) bswap_32(x)
|
||||
#define be32toh(x) bswap_32(x)
|
||||
#define betoh32(x) bswap_32(x)
|
||||
#define htobe64(x) bswap_64(x)
|
||||
#define be64toh(x) bswap_64(x)
|
||||
#define betoh64(x) bswap_64(x)
|
||||
#define htole16(x) (uint16_t)(x)
|
||||
#define le16toh(x) (uint16_t)(x)
|
||||
#define letoh16(x) (uint16_t)(x)
|
||||
#define htole32(x) (uint32_t)(x)
|
||||
#define le32toh(x) (uint32_t)(x)
|
||||
#define letoh32(x) (uint32_t)(x)
|
||||
#define htole64(x) (uint64_t)(x)
|
||||
#define le64toh(x) (uint64_t)(x)
|
||||
#define letoh64(x) (uint64_t)(x)
|
||||
#else
|
||||
#define htobe16(x) (uint16_t)(x)
|
||||
#define be16toh(x) (uint16_t)(x)
|
||||
#define betoh16(x) (uint16_t)(x)
|
||||
#define htobe32(x) (uint32_t)(x)
|
||||
#define be32toh(x) (uint32_t)(x)
|
||||
#define betoh32(x) (uint32_t)(x)
|
||||
#define htobe64(x) (uint64_t)(x)
|
||||
#define be64toh(x) (uint64_t)(x)
|
||||
#define betoh64(x) (uint64_t)(x)
|
||||
#define htole16(x) bswap_16(x)
|
||||
#define le16toh(x) bswap_16(x)
|
||||
#define letoh16(x) bswap_16(x)
|
||||
#define htole32(x) bswap_32(x)
|
||||
#define le32toh(x) bswap_32(x)
|
||||
#define letoh32(x) bswap_32(x)
|
||||
#define htole64(x) bswap_64(x)
|
||||
#define le64toh(x) bswap_64(x)
|
||||
#define letoh64(x) bswap_64(x)
|
||||
#endif
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_BITS_NEWBIE_H_ */
|
||||
@@ -0,0 +1,39 @@
|
||||
/*-*- 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/calls/math.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
void AddRusage(struct rusage *x, const struct rusage *y) {
|
||||
AddTimeval(&x->ru_utime, &y->ru_utime);
|
||||
AddTimeval(&x->ru_stime, &y->ru_stime);
|
||||
x->ru_maxrss = MAX(x->ru_maxrss, y->ru_maxrss);
|
||||
x->ru_ixrss += y->ru_ixrss;
|
||||
x->ru_idrss += y->ru_idrss;
|
||||
x->ru_isrss += y->ru_isrss;
|
||||
x->ru_minflt += y->ru_minflt;
|
||||
x->ru_majflt += y->ru_majflt;
|
||||
x->ru_nswap += y->ru_nswap;
|
||||
x->ru_inblock += y->ru_inblock;
|
||||
x->ru_oublock += y->ru_oublock;
|
||||
x->ru_msgsnd += y->ru_msgsnd;
|
||||
x->ru_msgrcv += y->ru_msgrcv;
|
||||
x->ru_nsignals += y->ru_nsignals;
|
||||
x->ru_nvcsw += y->ru_nvcsw;
|
||||
x->ru_nivcsw += y->ru_nivcsw;
|
||||
}
|
||||
@@ -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 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/calls/math.h"
|
||||
|
||||
void AddTimeval(struct timeval *x, const struct timeval *y) {
|
||||
x->tv_sec += y->tv_sec;
|
||||
x->tv_usec += y->tv_usec;
|
||||
if (x->tv_usec >= 1000000) {
|
||||
x->tv_usec -= 1000000;
|
||||
x->tv_sec += 1;
|
||||
}
|
||||
}
|
||||
+17
-13
@@ -84,6 +84,7 @@ int arch_prctl();
|
||||
int chdir(const char *);
|
||||
int chmod(const char *, uint32_t);
|
||||
int chown(const char *, uint32_t, uint32_t);
|
||||
int chroot(const char *);
|
||||
int close(int);
|
||||
int closedir(DIR *);
|
||||
int creat(const char *, uint32_t) nodiscard;
|
||||
@@ -100,6 +101,7 @@ int execvp(const char *, char *const[]) paramsnonnull();
|
||||
int execvpe(const char *, char *const[], char *const[]) paramsnonnull();
|
||||
int faccessat(int, const char *, int, uint32_t);
|
||||
int fadvise(int, uint64_t, uint64_t, int);
|
||||
int fchdir(int);
|
||||
int fchmod(int, uint32_t) nothrow;
|
||||
int fchmodat(int, const char *, uint32_t, uint32_t);
|
||||
int fchown(int, uint32_t, uint32_t);
|
||||
@@ -115,13 +117,14 @@ int fsync(int);
|
||||
int ftruncate(int, int64_t);
|
||||
int getdomainname(char *, size_t);
|
||||
int gethostname(char *, size_t);
|
||||
int getpgid(int);
|
||||
int getpid(void);
|
||||
int getppid(void);
|
||||
int getpriority(int, unsigned);
|
||||
int getrlimit(int, struct rlimit *);
|
||||
int getrusage(int, struct rusage *);
|
||||
int kill(int, int);
|
||||
int killpg(int, int);
|
||||
int sigqueue(int, int, const union sigval);
|
||||
int link(const char *, const char *) nothrow;
|
||||
int linkat(int, const char *, int, const char *, uint32_t);
|
||||
int lstat(const char *, struct stat *);
|
||||
@@ -129,6 +132,7 @@ int madvise(void *, uint64_t, int);
|
||||
int mkdir(const char *, uint32_t);
|
||||
int mkdirat(int, const char *, uint32_t);
|
||||
int mkfifo(const char *, uint32_t);
|
||||
int mkfifoat(int, const char *, uint32_t);
|
||||
int mknod(const char *, uint32_t, uint64_t);
|
||||
int mknodat(int, const char *, int32_t, uint64_t);
|
||||
int mlock(const void *, size_t);
|
||||
@@ -146,8 +150,10 @@ int pipe(int[hasatleast 2]);
|
||||
int pipe2(int[hasatleast 2], int);
|
||||
int posix_fadvise(int, uint64_t, uint64_t, int);
|
||||
int posix_madvise(void *, uint64_t, int);
|
||||
int prctl();
|
||||
int raise(int);
|
||||
int readlink(const char *, char *, size_t);
|
||||
int reboot(int);
|
||||
int remove(const char *);
|
||||
int rename(const char *, const char *);
|
||||
int renameat(int, const char *, int, const char *);
|
||||
@@ -171,11 +177,13 @@ int setuid(uint32_t);
|
||||
int sigaction(int, const struct sigaction *, struct sigaction *);
|
||||
int sigignore(int);
|
||||
int sigprocmask(int, const struct sigset *, struct sigset *);
|
||||
int sigqueue(int, int, const union sigval);
|
||||
int sigsuspend(const struct sigset *);
|
||||
int stat(const char *, struct stat *);
|
||||
int symlink(const char *, const char *);
|
||||
int symlinkat(const char *, int, const char *);
|
||||
int sync_file_range(int, int64_t, int64_t, unsigned);
|
||||
int sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
||||
int sysinfo(struct sysinfo *);
|
||||
int touch(const char *, uint32_t);
|
||||
int truncate(const char *, uint64_t);
|
||||
@@ -189,21 +197,20 @@ int wait(int *);
|
||||
int wait3(int *, int, struct rusage *);
|
||||
int wait4(int, int *, int, struct rusage *);
|
||||
int waitpid(int, int *, int);
|
||||
ssize_t lseek(int, int64_t, unsigned);
|
||||
ssize_t pread(int, void *, size_t, int64_t);
|
||||
ssize_t preadv(int, struct iovec *, int, int64_t);
|
||||
ssize_t pwrite(int, const void *, size_t, int64_t);
|
||||
ssize_t pwritev(int, const struct iovec *, int, int64_t);
|
||||
intptr_t syscall(int, ...);
|
||||
void sync(void);
|
||||
long ptrace(int, int, void *, void *);
|
||||
long telldir(DIR *);
|
||||
int getpid(void);
|
||||
long times(struct tms *);
|
||||
sighandler_t signal(int, sighandler_t);
|
||||
size_t GetFileSize(const char *);
|
||||
size_t getfiledescriptorsize(int);
|
||||
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
|
||||
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
||||
ssize_t lseek(int, int64_t, unsigned);
|
||||
ssize_t pread(int, void *, size_t, int64_t);
|
||||
ssize_t preadv(int, struct iovec *, int, int64_t);
|
||||
ssize_t pwrite(int, const void *, size_t, int64_t);
|
||||
ssize_t pwritev(int, const struct iovec *, int, int64_t);
|
||||
ssize_t read(int, void *, size_t);
|
||||
ssize_t readansi(int, char *, size_t);
|
||||
ssize_t readlinkat(int, const char *, char *, size_t);
|
||||
@@ -219,11 +226,8 @@ uint32_t getsid(int) nosideeffect;
|
||||
uint32_t gettid(void) nosideeffect;
|
||||
uint32_t getuid(void) nosideeffect;
|
||||
uint32_t umask(int32_t);
|
||||
long ptrace(int, int, void *, void *);
|
||||
int chroot(const char *);
|
||||
int prctl();
|
||||
int sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
||||
int fchdir(int);
|
||||
void rewinddir(DIR *);
|
||||
void sync(void);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » formatting ─╬─│┼
|
||||
|
||||
+2
-1
@@ -41,10 +41,11 @@ LIBC_CALLS_A_DIRECTDEPS = \
|
||||
LIBC_INTRIN \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_IPHLPAPI \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_POWERPROF \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_NT_IPHLPAPI \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_SYSV_CALLS \
|
||||
|
||||
@@ -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 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/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
uint32_t cfgetispeed(const struct termios *t) {
|
||||
if (CBAUD) {
|
||||
return t->c_cflag & CBAUD;
|
||||
} else {
|
||||
return t->c_ispeed;
|
||||
}
|
||||
}
|
||||
@@ -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 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/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
uint32_t cfgetospeed(const struct termios *t) {
|
||||
if (CBAUD) {
|
||||
return t->c_cflag & CBAUD;
|
||||
} else {
|
||||
return t->c_ospeed;
|
||||
}
|
||||
}
|
||||
@@ -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 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/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
void cfmakeraw(struct termios *t) {
|
||||
t->c_iflag &=
|
||||
~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||
t->c_oflag &= ~OPOST;
|
||||
t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
t->c_cflag &= ~(CSIZE | PARENB);
|
||||
t->c_cflag |= CS8;
|
||||
t->c_cc[VMIN] = 1;
|
||||
t->c_cc[VTIME] = 0;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*-*- 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/calls/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int cfsetispeed(struct termios *t, int speed) {
|
||||
if (speed) {
|
||||
if (CBAUD) {
|
||||
if (speed & ~CBAUD) return einval();
|
||||
t->c_cflag &= ~CBAUD;
|
||||
t->c_cflag |= speed;
|
||||
} else {
|
||||
t->c_ispeed = speed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*-*- 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/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int cfsetospeed(struct termios *t, int speed) {
|
||||
if (CBAUD) {
|
||||
if (!(speed & ~CBAUD)) {
|
||||
t->c_cflag &= ~CBAUD;
|
||||
t->c_cflag |= speed;
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
} else {
|
||||
t->c_ospeed = speed;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,9 @@ static bool AccessCommand(char path[hasatleast PATH_MAX], const char *name,
|
||||
size_t namelen, size_t pathlen) {
|
||||
if (pathlen + 1 + namelen + 1 + 4 + 1 > PATH_MAX) return -1;
|
||||
if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) {
|
||||
path[pathlen] =
|
||||
!IsWindows() ? '/' : memchr(path, '\\', pathlen) ? '\\' : '/';
|
||||
path[pathlen] = !IsWindows() ? '/'
|
||||
: memchr(path, '\\', pathlen) ? '\\'
|
||||
: '/';
|
||||
pathlen++;
|
||||
}
|
||||
memcpy(path + pathlen, name, namelen + 1);
|
||||
@@ -93,7 +94,9 @@ char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
|
||||
(AccessCommand(pathbuf, name, namelen,
|
||||
stpcpy(pathbuf, kNtSystemDirectory) - pathbuf) ||
|
||||
AccessCommand(pathbuf, name, namelen,
|
||||
stpcpy(pathbuf, kNtWindowsDirectory) - pathbuf))) ||
|
||||
stpcpy(pathbuf, kNtWindowsDirectory) - pathbuf) ||
|
||||
AccessCommand(pathbuf, name, namelen,
|
||||
stpcpy(pathbuf, ".") - pathbuf))) ||
|
||||
SearchPath(pathbuf, name, namelen)) {
|
||||
errno = olderr;
|
||||
return pathbuf;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/flock.h"
|
||||
@@ -37,6 +38,40 @@
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static textwindows int sys_fcntl_nt_reservefd(int start) {
|
||||
int fd;
|
||||
for (;;) {
|
||||
fd = start;
|
||||
if (fd >= g_fds.n) {
|
||||
if (__ensurefds(fd) == -1) return -1;
|
||||
}
|
||||
cmpxchg(&g_fds.f, fd, fd + 1);
|
||||
if (cmpxchg(&g_fds.p[fd].kind, kFdEmpty, kFdReserved)) {
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static textwindows int sys_fcntl_nt_dupfd(int oldfd, int cmd, int start) {
|
||||
int newfd;
|
||||
int64_t proc;
|
||||
if ((newfd = sys_fcntl_nt_reservefd(start)) != -1) {
|
||||
proc = GetCurrentProcess();
|
||||
if (DuplicateHandle(proc, g_fds.p[oldfd].handle, proc,
|
||||
&g_fds.p[newfd].handle, 0, true,
|
||||
kNtDuplicateSameAccess)) {
|
||||
g_fds.p[newfd].kind = g_fds.p[oldfd].kind;
|
||||
g_fds.p[newfd].flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
|
||||
return newfd;
|
||||
} else {
|
||||
__releasefd(newfd);
|
||||
return __winerr();
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static textwindows int sys_fcntl_nt_lock(struct Fd *f, int cmd, uintptr_t arg) {
|
||||
struct flock *l;
|
||||
uint32_t flags, err;
|
||||
@@ -123,6 +158,8 @@ textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
|
||||
}
|
||||
} else if (cmd == F_SETLK || cmd == F_SETLKW) {
|
||||
return sys_fcntl_nt_lock(g_fds.p + fd, cmd, arg);
|
||||
} else if (cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC) {
|
||||
return sys_fcntl_nt_dupfd(fd, cmd, arg);
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) {
|
||||
st->st_size = (uint64_t)wst.nFileSizeHigh << 32 | wst.nFileSizeLow;
|
||||
st->st_blksize = PAGESIZE;
|
||||
st->st_dev = wst.dwVolumeSerialNumber;
|
||||
st->st_rdev = wst.dwVolumeSerialNumber;
|
||||
st->st_ino = (uint64_t)wst.nFileIndexHigh << 32 | wst.nFileIndexLow;
|
||||
st->st_nlink = wst.nNumberOfLinks;
|
||||
if (GetFileInformationByHandleEx(handle, kNtFileCompressionInfo, &fci,
|
||||
|
||||
@@ -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 2020 Justine Alexandra Roberts Tunney │
|
||||
│ 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 │
|
||||
@@ -17,15 +17,12 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
textwindows void FileTimeToTimeVal(struct timeval *tv, struct NtFileTime ft) {
|
||||
uint64_t x;
|
||||
x = ft.dwHighDateTime;
|
||||
x <<= 32;
|
||||
x |= ft.dwLowDateTime;
|
||||
tv->tv_sec = x / HECTONANOSECONDS - MODERNITYSECONDS;
|
||||
tv->tv_usec = x % HECTONANOSECONDS / 10;
|
||||
int ftok(const char *path, int id) {
|
||||
struct stat st;
|
||||
if (stat(path, &st) == -1) return -1;
|
||||
return (uint32_t)id << 24 | (st.st_dev & 0xff) << 16 | (st.st_ino & 0xffff);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_
|
||||
#include "libc/nt/enum/ctrlevent.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
static inline int GetConsoleCtrlEvent(int sig) {
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
return kNtCtrlCEvent;
|
||||
case SIGHUP:
|
||||
return kNtCtrlCloseEvent;
|
||||
case SIGQUIT:
|
||||
return kNtCtrlBreakEvent;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ */
|
||||
@@ -0,0 +1,32 @@
|
||||
/*-*- 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/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Returns process group id.
|
||||
*/
|
||||
int getpgid(int pid) {
|
||||
if (!IsWindows()) {
|
||||
return sys_getpgid(pid);
|
||||
} else {
|
||||
return getpid();
|
||||
}
|
||||
}
|
||||
@@ -38,8 +38,8 @@ textwindows int sys_getrusage_nt(int who, struct rusage *usage) {
|
||||
if ((who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)(
|
||||
(who == RUSAGE_SELF ? GetCurrentProcess : GetCurrentThread)(),
|
||||
&CreationFileTime, &ExitFileTime, &KernelFileTime, &UserFileTime)) {
|
||||
FileTimeToTimeVal(&usage->ru_utime, UserFileTime);
|
||||
FileTimeToTimeVal(&usage->ru_stime, KernelFileTime);
|
||||
usage->ru_utime = FileTimeToTimeVal(UserFileTime);
|
||||
usage->ru_stime = FileTimeToTimeVal(KernelFileTime);
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
int sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz) {
|
||||
struct NtFileTime ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
FileTimeToTimeVal(tv, ft);
|
||||
*tv = FileTimeToTimeVal(ft);
|
||||
if (tz) memset(tz, 0, sizeof(*tz));
|
||||
return 0;
|
||||
}
|
||||
+10
-1
@@ -142,11 +142,12 @@ i32 sys_ftruncate(i32, i64, i64) hidden;
|
||||
i32 sys_futimes(i32, const struct timeval *) hidden;
|
||||
i32 sys_futimesat(i32, const char *, const struct timeval *) hidden;
|
||||
i32 sys_getitimer(i32, struct itimerval *) hidden;
|
||||
i32 sys_getpgid(i32) hidden;
|
||||
i32 sys_getppid(void) hidden;
|
||||
i32 sys_getpriority(i32, u32) hidden;
|
||||
i32 sys_getrlimit(i32, struct rlimit *) hidden;
|
||||
i32 sys_getrusage(i32, struct rusage *) hidden;
|
||||
i32 sys_ioctl(i32, u64, void *) hidden;
|
||||
i32 sys_ioctl(i32, u64, ...) hidden;
|
||||
i32 sys_kill(i32, i32, i32) hidden;
|
||||
i32 sys_linkat(i32, const char *, i32, const char *, i32) hidden;
|
||||
i32 sys_lseek(i32, i64, i64, i64) hidden;
|
||||
@@ -233,6 +234,14 @@ ssize_t WritevUninterruptible(int, struct iovec *, int);
|
||||
void flock2cosmo(uintptr_t);
|
||||
void cosmo2flock(uintptr_t);
|
||||
|
||||
int sys_sendfile_xnu(int32_t infd, int32_t outfd, int64_t offset,
|
||||
int64_t *out_opt_sbytes, const void *opt_hdtr,
|
||||
int32_t flags) asm("sys_sendfile") hidden;
|
||||
int sys_sendfile_freebsd(int32_t infd, int32_t outfd, int64_t offset,
|
||||
size_t nbytes, const void *opt_hdtr,
|
||||
int64_t *out_opt_sbytes,
|
||||
int32_t flags) asm("sys_sendfile") hidden;
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § syscalls » windows nt » veneers ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
+7
-3
@@ -27,7 +27,11 @@
|
||||
* Controls settings on device.
|
||||
* @vforksafe
|
||||
*/
|
||||
int(ioctl)(int fd, uint64_t request, void *memory) {
|
||||
__IOCTL_DISPATCH(EQUAL, fd, request, memory);
|
||||
return ioctl_default(fd, request, memory);
|
||||
int(ioctl)(int fd, uint64_t request, ...) {
|
||||
void *arg;
|
||||
va_list va;
|
||||
va_start(va, request);
|
||||
arg = va_arg(va, void *);
|
||||
va_end(va);
|
||||
return __IOCTL_DISPATCH(EQUAL, -1, fd, request, arg);
|
||||
}
|
||||
+44
-26
@@ -1,8 +1,9 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_IOCTL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_IOCTL_H_
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/consts/fio.h"
|
||||
#include "libc/sysv/consts/sio.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
@@ -10,35 +11,55 @@ COSMOPOLITAN_C_START_
|
||||
│ cosmopolitan § system calls » ioctl ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
int ioctl(int, uint64_t, void *);
|
||||
int ioctl(int, uint64_t, ...);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » ioctl » undiamonding (size optimization) ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
|
||||
#define ioctl(FD, REQUEST, MEMORY) ioctl_dispatch(FD, REQUEST, MEMORY)
|
||||
#define ioctl(FD, REQUEST, ...) \
|
||||
__IOCTL_DISPATCH(__EQUIVALENT, ioctl_default(FD, REQUEST, ##__VA_ARGS__), \
|
||||
FD, REQUEST, ##__VA_ARGS__)
|
||||
|
||||
#define __EQUIVALENT(X, Y) (__builtin_constant_p((X) == (Y)) && ((X) == (Y)))
|
||||
#define __IOCTL_DISPATCH(CMP, FD, REQUEST, MEMORY) \
|
||||
do { \
|
||||
if (CMP(request, TIOCGWINSZ)) return ioctl_tiocgwinsz(FD, MEMORY); \
|
||||
if (CMP(request, TIOCSWINSZ)) return ioctl_tiocswinsz(FD, MEMORY); \
|
||||
if (CMP(request, TCGETS)) return ioctl_tcgets(FD, MEMORY); \
|
||||
if (CMP(request, TCSETS)) return ioctl_tcsets(FD, REQUEST, MEMORY); \
|
||||
if (CMP(request, TCSETSW)) return ioctl_tcsets(FD, REQUEST, MEMORY); \
|
||||
if (CMP(request, TCSETSF)) return ioctl_tcsets(FD, REQUEST, MEMORY); \
|
||||
if (CMP(request, SIOCGIFCONF)) return ioctl_siocgifconf(FD, MEMORY); \
|
||||
if (CMP(request, SIOCGIFADDR)) return ioctl_siocgifaddr(FD, MEMORY); \
|
||||
if (CMP(request, SIOCGIFNETMASK)) return ioctl_siocgifnetmask(FD, MEMORY); \
|
||||
if (CMP(request, SIOCGIFBRDADDR)) return ioctl_siocgifbrdaddr(FD, MEMORY); \
|
||||
if (CMP(request, SIOCGIFDSTADDR)) return ioctl_siocgifdstaddr(FD, MEMORY); \
|
||||
if (CMP(request, SIOCGIFFLAGS)) return ioctl_siocgifflags(FD, MEMORY); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
if (CMP(request, SIOCGIFFLAGS)) return ioctl_siocgifflags(FD, REQUEST, MEMORY); \
|
||||
*/
|
||||
#define __IOCTL_DISPATCH(CMP, DEFAULT, FD, REQUEST, ...) \
|
||||
({ \
|
||||
int ReZ; \
|
||||
if (CMP(REQUEST, TIOCGWINSZ)) { \
|
||||
ReZ = ioctl_tiocgwinsz(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, TIOCSWINSZ)) { \
|
||||
ReZ = ioctl_tiocswinsz(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, TCGETS)) { \
|
||||
ReZ = ioctl_tcgets(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, TCSETS)) { \
|
||||
ReZ = ioctl_tcsets(FD, REQUEST, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, TCSETSW)) { \
|
||||
ReZ = ioctl_tcsets(FD, REQUEST, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, TCSETSF)) { \
|
||||
ReZ = ioctl_tcsets(FD, REQUEST, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFCONF)) { \
|
||||
ReZ = ioctl_siocgifconf(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFADDR)) { \
|
||||
ReZ = ioctl_siocgifaddr(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFNETMASK)) { \
|
||||
ReZ = ioctl_siocgifnetmask(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFBRDADDR)) { \
|
||||
ReZ = ioctl_siocgifbrdaddr(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFDSTADDR)) { \
|
||||
ReZ = ioctl_siocgifdstaddr(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, SIOCGIFFLAGS)) { \
|
||||
ReZ = ioctl_siocgifflags(FD, __VA_ARGS__); \
|
||||
} else if (CMP(REQUEST, FIOCLEX)) { \
|
||||
ReZ = ioctl_fioclex(FD); \
|
||||
} else if (CMP(REQUEST, FIONCLEX)) { \
|
||||
ReZ = ioctl_fionclex(FD); \
|
||||
} else { \
|
||||
ReZ = DEFAULT; \
|
||||
} \
|
||||
ReZ; \
|
||||
})
|
||||
|
||||
int ioctl_tcgets(int, void *);
|
||||
int ioctl_tcgets_nt(int, void *);
|
||||
@@ -55,11 +76,8 @@ int ioctl_siocgifnetmask(int, void *);
|
||||
int ioctl_siocgifbrdaddr(int, void *);
|
||||
int ioctl_siocgifflags(int, void *);
|
||||
int ioctl_default(int, uint64_t, void *);
|
||||
|
||||
forceinline int ioctl_dispatch(int fd, uint64_t request, void *memory) {
|
||||
__IOCTL_DISPATCH(__EQUIVALENT, fd, request, memory);
|
||||
return ioctl_default(fd, request, memory);
|
||||
}
|
||||
int ioctl_fioclex(int);
|
||||
int ioctl_fionclex(int);
|
||||
|
||||
#endif /* GNUC && !ANSI */
|
||||
COSMOPOLITAN_C_END_
|
||||
|
||||
@@ -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 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/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int ioctl_fioclex_nt(int fd) {
|
||||
if (__isfdopen(fd)) {
|
||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||
return 0;
|
||||
} else {
|
||||
return ebadf();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*-*- 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/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
int ioctl_fioclex_nt(int);
|
||||
|
||||
/**
|
||||
* Sets "close on exec" on file descriptor the fast way.
|
||||
*
|
||||
* @see ioctl(fd, FIOCLEX, 0) dispatches here
|
||||
*/
|
||||
int ioctl_fioclex(int fd) {
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, FIOCLEX, 0);
|
||||
} else {
|
||||
return ioctl_fioclex_nt(fd);
|
||||
}
|
||||
}
|
||||
@@ -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 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/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int ioctl_fionclex_nt(int fd) {
|
||||
if (__isfdopen(fd)) {
|
||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||
return 0;
|
||||
} else {
|
||||
return ebadf();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*-*- 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/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
int ioctl_fionclex_nt(int);
|
||||
|
||||
/**
|
||||
* Clears "close on exec" on file descriptor the fast way.
|
||||
*
|
||||
* @see ioctl(fd, FIONCLEX, 0) dispatches here
|
||||
*/
|
||||
int ioctl_fionclex(int fd) {
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, FIONCLEX, 0);
|
||||
} else {
|
||||
return ioctl_fionclex_nt(fd);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,8 @@ textwindows int ioctl_tcgets_nt(int ignored, struct termios *tio) {
|
||||
if (inmode & kNtEnableProcessedInput) tio->c_lflag |= IEXTEN | ISIG;
|
||||
}
|
||||
if (outok) {
|
||||
if (inmode & kNtEnableProcessedInput) tio->c_lflag |= IEXTEN | ISIG;
|
||||
if (outmode & kNtEnableProcessedOutput) tio->c_oflag |= OPOST;
|
||||
if (!(outmode & kNtDisableNewlineAutoReturn)) tio->c_oflag |= ONLCR;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
|
||||
@@ -51,8 +51,8 @@ textwindows int ioctl_tcsets_nt(int ignored, uint64_t request,
|
||||
}
|
||||
if (outok) {
|
||||
outmode |= kNtEnableWrapAtEolOutput;
|
||||
outmode |= kNtEnableProcessedOutput;
|
||||
if (!(tio->c_oflag & OPOST)) outmode |= kNtDisableNewlineAutoReturn;
|
||||
if (tio->c_oflag & OPOST) outmode |= kNtEnableProcessedOutput;
|
||||
if (!(tio->c_oflag & ONLCR)) outmode |= kNtDisableNewlineAutoReturn;
|
||||
if (NtGetVersion() >= kNtVersionWindows10) {
|
||||
outmode |= kNtEnableVirtualTerminalProcessing;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_IPC_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_IPC_H_
|
||||
|
||||
#define IPC_PRIVATE 0
|
||||
#define IPC_RMID 0
|
||||
#define IPC_SET 1
|
||||
#define IPC_STAT 2
|
||||
#define IPC_INFO 3
|
||||
#define IPC_CREAT 01000
|
||||
#define IPC_EXCL 02000
|
||||
#define IPC_NOWAIT 04000
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int ftok(const char *, int);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_IPC_H_ */
|
||||
+21
-25
@@ -16,41 +16,37 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/getconsolectrlevent.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/enum/ctrlevent.h"
|
||||
#include "libc/nt/enum/processaccess.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_kill_nt(int pid, int sig) {
|
||||
int target;
|
||||
uint32_t event;
|
||||
if (!pid) return raise(sig);
|
||||
if ((pid > 0 && __isfdkind(pid, kFdProcess)) ||
|
||||
(pid < 0 && __isfdkind(-pid, kFdProcess))) {
|
||||
target = GetProcessId(g_fds.p[ABS(pid)].handle);
|
||||
} else {
|
||||
target = pid;
|
||||
}
|
||||
if (target == GetCurrentProcessId()) {
|
||||
return raise(sig);
|
||||
} else {
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
event = kNtCtrlCEvent;
|
||||
case SIGHUP:
|
||||
event = kNtCtrlCloseEvent;
|
||||
case SIGQUIT:
|
||||
event = kNtCtrlBreakEvent;
|
||||
default:
|
||||
return einval();
|
||||
}
|
||||
if (GenerateConsoleCtrlEvent(event, target)) {
|
||||
return 0;
|
||||
bool ok;
|
||||
int event;
|
||||
int64_t handle;
|
||||
if (pid) {
|
||||
pid = ABS(pid);
|
||||
if ((event = GetConsoleCtrlEvent(sig)) != -1) {
|
||||
ok = !!GenerateConsoleCtrlEvent(
|
||||
event, __isfdkind(pid, kFdProcess) ? GetProcessId(g_fds.p[pid].handle)
|
||||
: pid);
|
||||
} else if (__isfdkind(pid, kFdProcess)) {
|
||||
ok = !!TerminateProcess(g_fds.p[pid].handle, 128 + sig);
|
||||
} else if ((handle = OpenProcess(kNtProcessAllAccess, false, pid))) {
|
||||
ok = !!TerminateProcess(handle, 128 + sig);
|
||||
CloseHandle(handle);
|
||||
} else {
|
||||
return __winerr();
|
||||
ok = false;
|
||||
}
|
||||
return ok ? 0 : __winerr();
|
||||
} else {
|
||||
return raise(sig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_MAKEDEV_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_MAKEDEV_H_
|
||||
#include "libc/dce.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
static inline uint64_t major(uint64_t x) {
|
||||
if (IsXnu()) {
|
||||
return (x >> 24) & 0xff;
|
||||
} else if (IsNetbsd()) {
|
||||
return (x & 0x000fff00) >> 8;
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x >> 8) & 0xff;
|
||||
} else if (IsFreebsd()) {
|
||||
return ((x >> 32) & 0xffffff00) | ((x >> 8) & 0x000000ff);
|
||||
} else {
|
||||
return ((x >> 32) & 0xfffff000) | ((x >> 8) & 0x00000fff);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t minor(uint64_t x) {
|
||||
if (IsXnu()) {
|
||||
return x & 0x00ffffff;
|
||||
} else if (IsNetbsd()) {
|
||||
return (x & 0x000000ff) | (x & 0xfff00000) >> 12;
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x & 0x000000ff) | (x & 0x0ffff000) >> 8;
|
||||
} else if (IsFreebsd()) {
|
||||
return ((x >> 24) & 0x0000ff00) | (x & 0xffff00ff);
|
||||
} else {
|
||||
return ((x >> 12) & 0xffffff00) | (x & 0x000000ff);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t makedev(uint64_t x, uint64_t y) {
|
||||
if (IsXnu()) {
|
||||
return x << 24 | y;
|
||||
} else if (IsNetbsd()) {
|
||||
return ((x << 8) & 0x000fff00) | ((y << 12) & 0xfff00000u) |
|
||||
(y & 0x000000ff);
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x & 0xff) << 8 | (y & 0xff) | (y & 0xffff00) << 8;
|
||||
} else if (IsFreebsd()) {
|
||||
return (x & 0xffffff00) << 32 | (x & 0x000000ff) << 8 |
|
||||
(y & 0x0000ff00) << 24 | (y & 0xffff00ff);
|
||||
} else {
|
||||
return (x & 0xfffff000) << 32 | (x & 0x00000fff) << 8 |
|
||||
(y & 0xffffff00) << 12 | (y & 0x000000ff);
|
||||
}
|
||||
}
|
||||
|
||||
#define major(x) major(x)
|
||||
#define minor(x) minor(x)
|
||||
#define makedev(x, y) makedev(x, y)
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_MAKEDEV_H_ */
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_MATH_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_MATH_H_
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
void AddTimeval(struct timeval *, const struct timeval *);
|
||||
void AddRusage(struct rusage *, const struct rusage *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_MATH_H_ */
|
||||
@@ -0,0 +1,100 @@
|
||||
/*-*- 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/calls/mount.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int32_t sys_mount_linux(const char *source, const char *target,
|
||||
const char *filesystemtype, uint64_t mountflags,
|
||||
const void *data) asm("sys_mount");
|
||||
int32_t sys_mount_bsd(const char *type, const char *dir, int32_t flags,
|
||||
void *data) asm("sys_mount");
|
||||
|
||||
/**
|
||||
* Mounts file system.
|
||||
*
|
||||
* The following flags may be specified:
|
||||
*
|
||||
* - `MS_RDONLY` (mount read-only)
|
||||
* - `MS_NOSUID` (don't honor S_ISUID bit)
|
||||
* - `MS_NODEV` (disallow special files)
|
||||
* - `MS_NOEXEC` (disallow program execution)
|
||||
* - `MS_SYNCHRONOUS` (writes are synced at once)
|
||||
* - `MS_NOATIME` (do not update access times)
|
||||
* - `MS_REMOUNT` (tune existing mounting)
|
||||
*
|
||||
* The following flags may also be used, but could be set to zero at
|
||||
* runtime if the underlying kernel doesn't support them.
|
||||
*
|
||||
* - `MNT_ASYNC` (xnu, freebsd, openbsd, netbsd)
|
||||
* - `MNT_RELOAD` (xnu, freebsd, openbsd, netbsd)
|
||||
* - `MS_STRICTATIME` (linux, xnu)
|
||||
* - `MS_RELATIME` (linux, netbsd)
|
||||
* - `MNT_SNAPSHOT` (xnu, freebsd)
|
||||
* - `MS_MANDLOCK` (linux)
|
||||
* - `MS_DIRSYNC` (linux)
|
||||
* - `MS_NODIRATIME` (linux)
|
||||
* - `MS_BIND` (linux)
|
||||
* - `MS_MOVE` (linux)
|
||||
* - `MS_REC` (linux)
|
||||
* - `MS_SILENT` (linux)
|
||||
* - `MS_POSIXACL` (linux)
|
||||
* - `MS_UNBINDABLE` (linux)
|
||||
* - `MS_PRIVATE` (linux)
|
||||
* - `MS_SLAVE` (linux)
|
||||
* - `MS_SHARED` (linux)
|
||||
* - `MS_KERNMOUNT` (linux)
|
||||
* - `MS_I_VERSION` (linux)
|
||||
* - `MS_LAZYTIME` (linux)
|
||||
* - `MS_ACTIVE` (linux)
|
||||
* - `MS_NOUSER` (linux)
|
||||
* - `MS_RMT`_MASK (linux)
|
||||
* - `MNT_SUIDDIR` (freebsd)
|
||||
* - `MNT_NOCLUSTERR` (freebsd)
|
||||
* - `MNT_NOCLUSTERW` (freebsd)
|
||||
*
|
||||
* Some example values for the `type` parameter:
|
||||
*
|
||||
* - `"nfs"`
|
||||
* - `"vfat"`
|
||||
* - `"tmpfs"`
|
||||
* - `"iso8601"`
|
||||
*
|
||||
*/
|
||||
int mount(const char *source, const char *target, const char *type,
|
||||
unsigned long flags, const void *data) {
|
||||
if (!IsWindows()) {
|
||||
if (!IsBsd()) {
|
||||
return sys_mount_linux(source, target, type, flags, data);
|
||||
} else {
|
||||
if (!strcmp(type, "iso9660")) type = "cd9660";
|
||||
if (!strcmp(type, "vfat")) {
|
||||
if (IsOpenbsd() || IsNetbsd()) {
|
||||
type = "msdos";
|
||||
} else {
|
||||
type = "msdosfs";
|
||||
}
|
||||
}
|
||||
return sys_mount_bsd(type, target, flags, data);
|
||||
}
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_MOUNT_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_MOUNT_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int mount(const char *, const char *, const char *, unsigned long,
|
||||
const void *);
|
||||
int unmount(const char *, int);
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
int umount(const char *);
|
||||
int umount2(const char *, int);
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_MOUNT_H_ */
|
||||
+6
-16
@@ -17,25 +17,12 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/getconsolectrlevent.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/enum/ctrlevent.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
static textwindows uint32_t GetCtrlEvent(int sig) {
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
return kNtCtrlCEvent;
|
||||
case SIGHUP:
|
||||
return kNtCtrlCloseEvent;
|
||||
case SIGQUIT:
|
||||
return kNtCtrlBreakEvent;
|
||||
default:
|
||||
ExitProcess(128 + sig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends signal to this process.
|
||||
*
|
||||
@@ -44,6 +31,7 @@ static textwindows uint32_t GetCtrlEvent(int sig) {
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int raise(int sig) {
|
||||
int event;
|
||||
if (sig == SIGTRAP) {
|
||||
DebugBreak();
|
||||
return 0;
|
||||
@@ -55,11 +43,13 @@ int raise(int sig) {
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_kill(getpid(), sig, 1);
|
||||
} else {
|
||||
if (GenerateConsoleCtrlEvent(GetCtrlEvent(sig), 0)) {
|
||||
} else if ((event = GetConsoleCtrlEvent(sig))) {
|
||||
if (GenerateConsoleCtrlEvent(event, 0)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
} else {
|
||||
ExitProcess(128 + sig);
|
||||
}
|
||||
}
|
||||
@@ -102,6 +102,7 @@ ssize_t readansi(int fd, char *buf, size_t size) {
|
||||
break;
|
||||
case kCsi:
|
||||
switch (c) {
|
||||
case '[':
|
||||
case ':':
|
||||
case ';':
|
||||
case '<':
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*-*- 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/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/framebuffervirtualscreeninfo.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/system.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#define kNtShutdownForceOthers 1
|
||||
#define kNtShutdownForceSelf 2
|
||||
#define kNtShutdownGraceOverride 0x20
|
||||
#define kNtShutdownHybrid 0x200
|
||||
|
||||
int32_t sys_reboot_linux(int32_t, int32_t, int32_t) asm("sys_reboot");
|
||||
int32_t sys_reboot_bsd(int32_t, const char *) asm("sys_reboot");
|
||||
|
||||
/**
|
||||
* Reboots system.
|
||||
*
|
||||
* The `howto` argument may be one of the following:
|
||||
*
|
||||
* - `RB_AUTOBOOT`
|
||||
* - `RB_POWER_OFF`
|
||||
* - `RB_HALT_SYSTEM`
|
||||
* - `RB_SW_SUSPEND` (linux and windows only)
|
||||
* - `RB_KEXEC` (linux only)
|
||||
* - `RB_ENABLE_CAD` (linux only)
|
||||
* - `RB_DISABLE_CAD` (linux only)
|
||||
*
|
||||
* There's an implicit `sync()` operation before the reboot happens.
|
||||
* This can be prevented by or'ing `howto` with `RB_NOSYNC`. Setting
|
||||
* this option will also prevent apps on Windows from having time to
|
||||
* close themselves.
|
||||
*/
|
||||
int reboot(int howto) {
|
||||
bool ok, immediately;
|
||||
if (howto != -1) {
|
||||
if (!(howto & 0x20000000)) {
|
||||
sync();
|
||||
immediately = false;
|
||||
} else {
|
||||
howto &= ~0x20000000;
|
||||
immediately = true;
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
if (IsLinux()) {
|
||||
return sys_reboot_linux(0xFEE1DEAD, 0x28121969, howto);
|
||||
} else {
|
||||
return sys_reboot_bsd(howto, 0);
|
||||
}
|
||||
} else {
|
||||
if (howto == 0xD000FCE2u) {
|
||||
ok = !!SetSuspendState(0, 0, 0);
|
||||
} else {
|
||||
howto |= kNtShutdownForceOthers;
|
||||
howto |= kNtShutdownForceSelf;
|
||||
if (NtGetVersion() >= 8) {
|
||||
howto |= kNtShutdownHybrid;
|
||||
}
|
||||
if (immediately) {
|
||||
ok = !!InitiateShutdown(0, 0, 0, howto | kNtShutdownGraceOverride, 0);
|
||||
} else {
|
||||
ok = !!InitiateShutdown(0, 0, 20, howto, 0);
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
@@ -28,6 +27,7 @@
|
||||
* @param rlim specifies new resource limit
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @see libc/sysv/consts.sh
|
||||
* @vforksafe
|
||||
*/
|
||||
int setrlimit(int resource, const struct rlimit *rlim) {
|
||||
if (resource == 127) return einval();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/intrin/repstosb.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
@@ -401,7 +402,14 @@ noasan static void xnuthreadstate2linux(
|
||||
mc->fs = xnuss->__fs;
|
||||
mc->eflags = xnuss->__rflags;
|
||||
uc->uc_flags = xnuss->__rflags;
|
||||
memcpy(&mc->r8, &xnuss->__r8, 8 * sizeof(int64_t));
|
||||
mc->r8 = xnuss->__r8;
|
||||
mc->r9 = xnuss->__r9;
|
||||
mc->r10 = xnuss->__r10;
|
||||
mc->r11 = xnuss->__r11;
|
||||
mc->r12 = xnuss->__r12;
|
||||
mc->r13 = xnuss->__r13;
|
||||
mc->r14 = xnuss->__r14;
|
||||
mc->r15 = xnuss->__r15;
|
||||
}
|
||||
|
||||
noasan static void linuxthreadstate2xnu(
|
||||
@@ -420,7 +428,21 @@ noasan static void linuxthreadstate2xnu(
|
||||
xnuss->__fs = mc->fs;
|
||||
xnuss->__rflags = mc->eflags;
|
||||
xnuss->__rflags = uc->uc_flags;
|
||||
memcpy(&xnuss->__r8, &mc->r8, 8 * sizeof(int64_t));
|
||||
xnuss->__r8 = mc->r8;
|
||||
xnuss->__r9 = mc->r9;
|
||||
xnuss->__r10 = mc->r10;
|
||||
xnuss->__r11 = mc->r11;
|
||||
xnuss->__r12 = mc->r12;
|
||||
xnuss->__r13 = mc->r13;
|
||||
xnuss->__r14 = mc->r14;
|
||||
xnuss->__r15 = mc->r15;
|
||||
}
|
||||
|
||||
noasan static void CopyFpXmmRegs(void *d, const void *s) {
|
||||
size_t i;
|
||||
for (i = 0; i < (8 + 16) * 16; i += 16) {
|
||||
__builtin_memcpy((char *)d + i, (const char *)s + i, 16);
|
||||
}
|
||||
}
|
||||
|
||||
noasan static void xnussefpustate2linux(
|
||||
@@ -433,8 +455,7 @@ noasan static void xnussefpustate2linux(
|
||||
fs->rdp = xnufs->__fpu_dp;
|
||||
fs->mxcsr = xnufs->__fpu_mxcsr;
|
||||
fs->mxcr_mask = xnufs->__fpu_mxcsrmask;
|
||||
/* copy st0-st7 as well as xmm0-xmm15 */
|
||||
memcpy(fs->st, &xnufs->__fpu_stmm0, (8 + 16) * sizeof(uint128_t));
|
||||
CopyFpXmmRegs(fs->st, &xnufs->__fpu_stmm0);
|
||||
}
|
||||
|
||||
noasan static void linuxssefpustate2xnu(
|
||||
@@ -447,8 +468,7 @@ noasan static void linuxssefpustate2xnu(
|
||||
xnufs->__fpu_dp = fs->rdp;
|
||||
xnufs->__fpu_mxcsr = fs->mxcsr;
|
||||
xnufs->__fpu_mxcsrmask = fs->mxcr_mask;
|
||||
/* copy st0-st7 as well as xmm0-xmm15 */
|
||||
memcpy(&xnufs->__fpu_stmm0, fs->st, (8 + 16) * sizeof(uint128_t));
|
||||
CopyFpXmmRegs(&xnufs->__fpu_stmm0, fs->st);
|
||||
}
|
||||
|
||||
noasan void __sigenter_xnu(void *fn, int infostyle, int sig,
|
||||
@@ -462,10 +482,9 @@ noasan void __sigenter_xnu(void *fn, int infostyle, int sig,
|
||||
} g;
|
||||
rva = __sighandrvas[sig & (NSIG - 1)];
|
||||
if (rva >= kSigactionMinRva) {
|
||||
memset(&g, 0, sizeof(g));
|
||||
repstosb(&g, 0, sizeof(g));
|
||||
if (xnuctx) {
|
||||
memcpy(&g.uc.uc_sigmask, &xnuctx->uc_sigmask,
|
||||
MIN(sizeof(g.uc.uc_sigmask), sizeof(xnuctx->uc_sigmask)));
|
||||
g.uc.uc_sigmask.__bits[0] = xnuctx->uc_sigmask;
|
||||
g.uc.uc_stack.ss_sp = xnuctx->uc_stack.ss_sp;
|
||||
g.uc.uc_stack.ss_flags = xnuctx->uc_stack.ss_flags;
|
||||
g.uc.uc_stack.ss_size = xnuctx->uc_stack.ss_size;
|
||||
|
||||
@@ -18,13 +18,25 @@
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/tokeninformationclass.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/privilege.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/luid.h"
|
||||
#include "libc/nt/struct/tokenprivileges.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static bool g_can_symlink;
|
||||
|
||||
textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
|
||||
const char *linkpath) {
|
||||
const char *linkpath) {
|
||||
uint32_t flags;
|
||||
char16_t target16[PATH_MAX];
|
||||
char16_t linkpath16[PATH_MAX];
|
||||
if (!g_can_symlink) return eacces();
|
||||
flags = isdirectory(target) ? kNtSymbolicLinkFlagDirectory : 0;
|
||||
if (__mkntpathat(newdirfd, linkpath, 0, linkpath16) == -1) return -1;
|
||||
if (__mkntpath(target, target16) == -1) return -1;
|
||||
@@ -34,3 +46,24 @@ textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
|
||||
return __winerr();
|
||||
}
|
||||
}
|
||||
|
||||
static textstartup bool EnableSymlink(void) {
|
||||
int64_t tok;
|
||||
struct NtLuid id;
|
||||
struct NtTokenPrivileges tp;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), kNtTokenAllAccess, &tok)) return 0;
|
||||
if (!LookupPrivilegeValue(0, u"SeCreateSymbolicLinkPrivilege", &id)) return 0;
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Luid = id;
|
||||
tp.Privileges[0].Attributes = kNtSePrivilegeEnabled;
|
||||
if (!AdjustTokenPrivileges(tok, 0, &tp, sizeof(tp), 0, 0)) return 0;
|
||||
return GetLastError() != kNtErrorNotAllAssigned;
|
||||
}
|
||||
|
||||
static textstartup void g_can_symlink_init() {
|
||||
g_can_symlink = EnableSymlink();
|
||||
}
|
||||
|
||||
const void *const g_can_symlink_ctor[] initarray = {
|
||||
g_can_symlink_init,
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
/*-*- 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/calls/internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
|
||||
int tcdrain(int fd) {
|
||||
return ioctl(fd, TCSBRK, (void *)(intptr_t)1);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*-*- 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/calls/internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
int tcflow(int fd, int action) {
|
||||
/* TODO(jart): BSD support */
|
||||
return sys_ioctl(fd, TCXONC, (void *)(intptr_t)action);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*-*- 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/calls/internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
int tcflush(int fd, int x) {
|
||||
/* TODO(jart): BSD Support */
|
||||
return sys_ioctl(fd, TCFLSH, x);
|
||||
}
|
||||
@@ -28,4 +28,6 @@
|
||||
* @return -1 w/ errno on error
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int(tcgetattr)(int fd, struct termios *tio) { return ioctl(fd, TCGETS, tio); }
|
||||
int(tcgetattr)(int fd, struct termios *tio) {
|
||||
return ioctl(fd, TCGETS, tio);
|
||||
}
|
||||
@@ -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/calls/internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
int tcgetsid(int fd) {
|
||||
int sid;
|
||||
if (sys_ioctl(fd, TIOCGSID, &sid) < 0) return -1;
|
||||
return sid;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*-*- 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/calls/internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
int tcsendbreak(int fd, int len) {
|
||||
if (!IsBsd()) {
|
||||
return sys_ioctl(fd, TCSBRK, 0);
|
||||
} else {
|
||||
if (sys_ioctl(fd, TIOCSBRK, 0) == -1) return -1;
|
||||
usleep(400000);
|
||||
if (sys_ioctl(fd, TIOCCBRK, 0) == -1) return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,17 @@ int grantpt(int);
|
||||
int unlockpt(int);
|
||||
int posix_openpt(int) nodiscard;
|
||||
|
||||
int tcdrain(int);
|
||||
int tcgetsid(int);
|
||||
int tcflow(int, int);
|
||||
int tcflush(int, int);
|
||||
int tcsendbreak(int, int);
|
||||
void cfmakeraw(struct termios *);
|
||||
int cfsetospeed(struct termios *, int);
|
||||
int cfsetispeed(struct termios *, int);
|
||||
uint32_t cfgetospeed(const struct termios *);
|
||||
uint32_t cfgetispeed(const struct termios *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § teletypewriter » undiamonding ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_CALLS_TTYDEFAULTS_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_TTYDEFAULTS_H_
|
||||
#include "libc/sysv/consts/baud.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)
|
||||
#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS)
|
||||
#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE | ECHOKE | ECHOCTL)
|
||||
#define TTYDEF_CFLAG (CREAD | CS8 | HUPCL)
|
||||
#define TTYDEF_SPEED (B9600)
|
||||
|
||||
#define CTRL(x) ((x) ^ 0100)
|
||||
#define CEOF CTRL('D')
|
||||
#define CERASE CTRL('?')
|
||||
#define CINTR CTRL('C')
|
||||
#define CKILL CTRL('U')
|
||||
#define CQUIT CTRL('\\')
|
||||
#define CSUSP CTRL('Z')
|
||||
#define CDSUSP CTRL('Y')
|
||||
#define CSTART CTRL('Q')
|
||||
#define CSTOP CTRL('S')
|
||||
#define CLNEXT CTRL('V')
|
||||
#define CDISCARD CTRL('O')
|
||||
#define CWERASE CTRL('W')
|
||||
#define CREPRINT CTRL('R')
|
||||
#define CEOT CEOF
|
||||
#define CBRK CEOL
|
||||
#define CRPRNT CREPRINT
|
||||
#define CFLUSH CDISCARD
|
||||
#define CMIN 1
|
||||
#define CTIME 0
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_TTYDEFAULTS_H_ */
|
||||
@@ -0,0 +1,41 @@
|
||||
/*-*- 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/calls/mount.h"
|
||||
|
||||
int sys_unmount(const char *, int);
|
||||
|
||||
/**
|
||||
* Unmounts file system.
|
||||
*
|
||||
* The following flags may be specified:
|
||||
*
|
||||
* - `MNT_FORCE`
|
||||
*
|
||||
* The following flags may also be used, but could be set to zero at
|
||||
* runtime if the underlying kernel doesn't support them.
|
||||
*
|
||||
* - `MNT_DETACH`
|
||||
* - `MNT_EXPIRE`
|
||||
* - `UMOUNT_NOFOLLOW`
|
||||
* - `MNT_BYFSID`
|
||||
*
|
||||
*/
|
||||
int unmount(const char *target, int flags) {
|
||||
return sys_unmount(target, flags);
|
||||
}
|
||||
+11
-4
@@ -74,10 +74,17 @@ textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options,
|
||||
}
|
||||
if (opt_out_rusage) {
|
||||
memset(opt_out_rusage, 0, sizeof(*opt_out_rusage));
|
||||
GetProcessTimes(GetCurrentProcess(), &createfiletime, &exitfiletime,
|
||||
&kernelfiletime, &userfiletime);
|
||||
FileTimeToTimeVal(&opt_out_rusage->ru_utime, userfiletime);
|
||||
FileTimeToTimeVal(&opt_out_rusage->ru_stime, kernelfiletime);
|
||||
if (GetProcessTimes(g_fds.p[pids[i]].handle, &createfiletime,
|
||||
&exitfiletime, &kernelfiletime, &userfiletime)) {
|
||||
opt_out_rusage->ru_utime.tv_sec =
|
||||
ReadFileTime(userfiletime) / HECTONANOSECONDS;
|
||||
opt_out_rusage->ru_utime.tv_usec =
|
||||
ReadFileTime(userfiletime) % HECTONANOSECONDS;
|
||||
opt_out_rusage->ru_stime.tv_sec =
|
||||
ReadFileTime(kernelfiletime) / HECTONANOSECONDS;
|
||||
opt_out_rusage->ru_stime.tv_usec =
|
||||
ReadFileTime(kernelfiletime) % HECTONANOSECONDS;
|
||||
}
|
||||
}
|
||||
CloseHandle(g_fds.p[pids[i]].handle);
|
||||
g_fds.p[pids[i]].kind = kFdEmpty;
|
||||
|
||||
+2
-2
@@ -64,8 +64,8 @@ int CompareDnsNames(const char *, const char *) paramsnonnull();
|
||||
int PascalifyDnsName(uint8_t *, size_t, const char *) paramsnonnull();
|
||||
int ResolveDns(const struct ResolvConf *, int, const char *, struct sockaddr *,
|
||||
uint32_t) paramsnonnull();
|
||||
int ResolveDnsReverse(const struct ResolvConf *resolvconf, int, const char *,
|
||||
char *, size_t) paramsnonnull();
|
||||
int ResolveDnsReverse(const struct ResolvConf *, int, const char *, char *,
|
||||
size_t) paramsnonnull();
|
||||
struct addrinfo *newaddrinfo(uint16_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
||||
+38
-1
@@ -1,12 +1,24 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_DNS_ENT_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_ENT_H_
|
||||
#include "libc/dns/dns.h"
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
struct netent {
|
||||
char *n_name; /* official network name */
|
||||
char **n_aliases; /* alias list */
|
||||
int n_addrtype; /* net address type */
|
||||
uint32_t n_net; /* network number */
|
||||
};
|
||||
|
||||
struct protoent {
|
||||
char *p_name; /* official protocol name */
|
||||
char **p_aliases; /* alias list */
|
||||
int p_proto; /* protocol number */
|
||||
};
|
||||
|
||||
struct hostent {
|
||||
char *h_name; /* official name of host */
|
||||
char **h_aliases; /* alias list */
|
||||
@@ -16,12 +28,37 @@ struct hostent {
|
||||
};
|
||||
#define h_addr h_addr_list[0]
|
||||
|
||||
struct servent {
|
||||
char *s_name; /* official service name */
|
||||
char **s_aliases; /* alias list */
|
||||
int s_port; /* port number (in network byte order) */
|
||||
char *s_proto; /* protocol to use */
|
||||
};
|
||||
|
||||
struct netent *getnetent(void);
|
||||
struct netent *getnetbyname(const char *);
|
||||
struct netent *getnetbyaddr(uint32_t, int);
|
||||
void setnetent(int);
|
||||
void endnetent(void);
|
||||
|
||||
struct protoent *getprotoent(void);
|
||||
struct protoent *getprotobyname(const char *);
|
||||
struct protoent *getprotobynumber(int);
|
||||
void setprotoent(int);
|
||||
void endprotoent(void);
|
||||
|
||||
struct hostent *gethostent(void);
|
||||
struct hostent *gethostbyname(const char *);
|
||||
struct hostent *gethostbyaddr(const void *, socklen_t, int);
|
||||
void sethostent(int);
|
||||
void endhostent(void);
|
||||
|
||||
struct servent *getservent(void);
|
||||
struct servent *getservbyname(const char *, const char *);
|
||||
struct servent *getservbyport(int, const char *);
|
||||
void setservent(int);
|
||||
void endservent(void);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_ENT_H_ */
|
||||
+18
-1
@@ -21,12 +21,15 @@
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/inaddr.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
@@ -43,11 +46,24 @@ int getaddrinfo(const char *name, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **res) {
|
||||
int rc, port;
|
||||
const char *canon;
|
||||
size_t protolen;
|
||||
struct addrinfo *ai;
|
||||
char proto[32];
|
||||
port = 0;
|
||||
if (!name && !service) return EAI_NONAME;
|
||||
if (service && (port = parseport(service)) == -1) return EAI_NONAME;
|
||||
if (!name && (hints->ai_flags & AI_CANONNAME)) return EAI_BADFLAGS;
|
||||
if (service && (port = parseport(service)) == -1) {
|
||||
if (hints->ai_socktype == SOCK_STREAM)
|
||||
strcpy(proto, "tcp");
|
||||
else if (hints->ai_socktype == SOCK_DGRAM)
|
||||
strcpy(proto, "udp");
|
||||
else /* ai_socktype == 0 */
|
||||
strcpy(proto, "");
|
||||
if ((port = LookupServicesByName(service, proto, sizeof(proto), NULL, 0,
|
||||
NULL)) == -1) {
|
||||
return EAI_NONAME;
|
||||
}
|
||||
}
|
||||
if (!(ai = newaddrinfo(port))) return EAI_MEMORY;
|
||||
if (service) ai->ai_addr4->sin_port = htons(port);
|
||||
if (hints) {
|
||||
@@ -59,6 +75,7 @@ int getaddrinfo(const char *name, const char *service,
|
||||
(hints && (hints->ai_flags & AI_PASSIVE) == AI_PASSIVE)
|
||||
? INADDR_ANY
|
||||
: INADDR_LOOPBACK;
|
||||
*res = ai;
|
||||
return 0;
|
||||
}
|
||||
if (inet_pton(AF_INET, name, &ai->ai_addr4->sin_addr.s_addr) == 1) {
|
||||
|
||||
+10
-22
@@ -23,7 +23,6 @@
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/mem/mem.h"
|
||||
@@ -31,40 +30,29 @@
|
||||
|
||||
struct hostent *gethostbyaddr(const void *s_addr, socklen_t len, int type) {
|
||||
static struct hostent *ptr1, he1;
|
||||
static char h_name[DNS_NAME_MAX + 1];
|
||||
static char *h_aliases[1];
|
||||
static char *h_addr_list[2];
|
||||
static char h_addr_list0[4];
|
||||
struct sockaddr_in addr;
|
||||
char name[DNS_NAME_MAX + 1];
|
||||
|
||||
if (!ptr1) {
|
||||
he1.h_name = NULL;
|
||||
|
||||
he1.h_aliases = (char **)malloc(sizeof(char *) * 1);
|
||||
if (!he1.h_aliases) return NULL;
|
||||
he1.h_name = h_name;
|
||||
he1.h_aliases = h_aliases;
|
||||
he1.h_aliases[0] = NULL;
|
||||
|
||||
he1.h_addrtype = AF_INET;
|
||||
he1.h_length = 4;
|
||||
he1.h_addr_list = (char **)malloc(sizeof(char *) * 2);
|
||||
if (!he1.h_addr_list) return NULL;
|
||||
|
||||
he1.h_addr_list[0] = (char *)malloc(sizeof(uint32_t));
|
||||
if (!he1.h_addr_list[0]) return NULL;
|
||||
he1.h_addr_list = h_addr_list;
|
||||
he1.h_addr_list[0] = h_addr_list0;
|
||||
he1.h_addr_list[1] = NULL;
|
||||
|
||||
ptr1 = &he1;
|
||||
}
|
||||
|
||||
if (type != AF_INET || len != sizeof(uint32_t)) return NULL;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 0;
|
||||
addr.sin_addr.s_addr = *(uint32_t *)(s_addr);
|
||||
|
||||
if (getnameinfo((struct sockaddr *)&addr, sizeof(addr), name, sizeof(name),
|
||||
NULL, 0, 0))
|
||||
if (getnameinfo((struct sockaddr *)&addr, sizeof(addr), ptr1->h_name,
|
||||
DNS_NAME_MAX, NULL, 0, 0))
|
||||
return NULL;
|
||||
|
||||
if (ptr1->h_name) free(ptr1->h_name);
|
||||
ptr1->h_name = strdup(name);
|
||||
*((uint32_t *)ptr1->h_addr_list[0]) = (addr.sin_addr.s_addr);
|
||||
|
||||
return ptr1;
|
||||
}
|
||||
+15
-14
@@ -23,30 +23,31 @@
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
||||
struct hostent *gethostbyname(const char *name) {
|
||||
static struct hostent *ptr0, he0;
|
||||
static char h_name[DNS_NAME_MAX + 1];
|
||||
static char *h_aliases[1];
|
||||
static char *h_addr_list[2];
|
||||
static char h_addr_list0[4];
|
||||
struct addrinfo *result = NULL;
|
||||
|
||||
if (!ptr0) {
|
||||
he0.h_name = NULL;
|
||||
he0.h_name = h_name;
|
||||
|
||||
he0.h_aliases = (char **)malloc(sizeof(char *) * 1);
|
||||
if (!he0.h_aliases) return NULL;
|
||||
he0.h_aliases = h_aliases;
|
||||
he0.h_aliases[0] = NULL;
|
||||
|
||||
he0.h_addrtype = AF_INET;
|
||||
he0.h_length = 4;
|
||||
he0.h_addr_list = (char **)malloc(sizeof(char *) * 2);
|
||||
if (!he0.h_addr_list) return NULL;
|
||||
he0.h_addr_list = h_addr_list;
|
||||
|
||||
he0.h_addr_list[0] = (char *)malloc(sizeof(uint32_t));
|
||||
if (!he0.h_addr_list[0]) return NULL;
|
||||
he0.h_addr_list[0] = h_addr_list0;
|
||||
he0.h_addr_list[1] = NULL;
|
||||
|
||||
ptr0 = &he0;
|
||||
@@ -54,12 +55,12 @@ struct hostent *gethostbyname(const char *name) {
|
||||
|
||||
if (getaddrinfo(name, NULL, NULL, &result) || result == NULL) return NULL;
|
||||
|
||||
if (ptr0->h_name) free(ptr0->h_name);
|
||||
if (result->ai_canonname) {
|
||||
ptr0->h_name = strdup(result->ai_canonname);
|
||||
} else {
|
||||
ptr0->h_name = strdup(name);
|
||||
}
|
||||
/* 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);
|
||||
|
||||
*((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 */
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
@@ -31,6 +30,7 @@
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
@@ -58,7 +58,7 @@ int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *name,
|
||||
socklen_t namelen, char *service, socklen_t servicelen,
|
||||
int flags) {
|
||||
char *p, rdomain[1 + sizeof "255.255.255.255.in-addr.arpa"];
|
||||
char info[512];
|
||||
char info[NI_MAXHOST + 1];
|
||||
int rc, port;
|
||||
uint8_t *ip;
|
||||
unsigned int valid_flags;
|
||||
@@ -102,8 +102,10 @@ int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *name,
|
||||
port = ntohs(((struct sockaddr_in *)addr)->sin_port);
|
||||
info[0] = '\0';
|
||||
if (service != NULL && servicelen != 0) {
|
||||
itoa(port, info, 10);
|
||||
/* TODO: reverse lookup on /etc/services to get name of service */
|
||||
if ((flags & NI_NUMERICSERV) ||
|
||||
LookupServicesByPort(port, ((flags & NI_DGRAM) ? "udp" : "tcp"), 4,
|
||||
info, sizeof(info), NULL) == -1)
|
||||
itoa(port, info, 10);
|
||||
if (strlen(info) + 1 > servicelen) return EAI_OVERFLOW;
|
||||
strcpy(service, info);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/prototxt.h"
|
||||
#include "libc/nt/systeminfo.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];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/nt/systeminfo.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];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/dns/prototxt.h"
|
||||
|
||||
struct protoent *getprotobyname(const char *name) {
|
||||
static struct protoent *ptr0, pe0;
|
||||
static char p_name[DNS_NAME_MAX + 1];
|
||||
|
||||
if (!ptr0) {
|
||||
pe0.p_name = p_name;
|
||||
if (!(pe0.p_aliases = calloc(1, sizeof(char *)))) return NULL;
|
||||
pe0.p_proto = -1;
|
||||
ptr0 = &pe0;
|
||||
}
|
||||
|
||||
ptr0->p_proto = LookupProtoByName(name, ptr0->p_name, DNS_NAME_MAX, NULL);
|
||||
if (ptr0->p_proto == -1) return NULL;
|
||||
|
||||
return ptr0;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/dns/prototxt.h"
|
||||
|
||||
struct protoent *getprotobynumber(int proto) {
|
||||
static struct protoent *ptr1, pe1;
|
||||
static char p_name[DNS_NAME_MAX + 1];
|
||||
|
||||
if (!ptr1) {
|
||||
pe1.p_name = p_name;
|
||||
if (!(pe1.p_aliases = calloc(1, sizeof(char *)))) return NULL;
|
||||
pe1.p_proto = -1;
|
||||
ptr1 = &pe1;
|
||||
}
|
||||
|
||||
if (LookupProtoByNumber(proto, ptr1->p_name, DNS_NAME_MAX, NULL) == -1)
|
||||
return NULL;
|
||||
|
||||
ptr1->p_proto = proto;
|
||||
return ptr1;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
struct servent *getservbyname(const char *name, const char *proto) {
|
||||
static struct servent *ptr0, se0;
|
||||
static char s_name[DNS_NAME_MAX + 1];
|
||||
static char localproto[DNS_NAME_MAX + 1];
|
||||
int p;
|
||||
if (!ptr0) {
|
||||
se0.s_name = s_name;
|
||||
if (!(se0.s_aliases = calloc(1, sizeof(char *)))) return NULL;
|
||||
se0.s_port = 0;
|
||||
se0.s_proto = localproto;
|
||||
ptr0 = &se0;
|
||||
}
|
||||
if (proto) {
|
||||
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) return NULL;
|
||||
} else
|
||||
strcpy(localproto, "");
|
||||
p = LookupServicesByName(name, ptr0->s_proto, DNS_NAME_MAX, ptr0->s_name,
|
||||
DNS_NAME_MAX, NULL);
|
||||
if (p == -1) return NULL;
|
||||
ptr0->s_port = htons(p);
|
||||
return ptr0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
struct servent *getservbyport(int port, const char *proto) {
|
||||
static struct servent *ptr1, se1;
|
||||
static char s_name[DNS_NAME_MAX + 1];
|
||||
static char localproto[DNS_NAME_MAX + 1];
|
||||
if (!ptr1) {
|
||||
se1.s_name = s_name;
|
||||
if (!(se1.s_aliases = calloc(1, sizeof(char *)))) return NULL;
|
||||
se1.s_port = 0;
|
||||
se1.s_proto = localproto;
|
||||
ptr1 = &se1;
|
||||
}
|
||||
if (proto) {
|
||||
if (!memccpy(localproto, proto, '\0', DNS_NAME_MAX)) return NULL;
|
||||
} else
|
||||
strcpy(localproto, "");
|
||||
if (LookupServicesByPort(ntohs(port), ptr1->s_proto, DNS_NAME_MAX,
|
||||
ptr1->s_name, DNS_NAME_MAX, NULL) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
ptr1->s_port = port;
|
||||
return ptr1;
|
||||
}
|
||||
+1
-2
@@ -23,11 +23,10 @@
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
|
||||
int h_errno = 0;
|
||||
int h_errno;
|
||||
|
||||
void herror(const char *s) {
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/dns/prototxt.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
/**
|
||||
* Opens and searches /etc/protocols to find number for a given name.
|
||||
*
|
||||
* @param protoname is a NULL-terminated string
|
||||
* @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 protocols file
|
||||
* (if NULL, uses /etc/protocols)
|
||||
* @return -1 on error, or
|
||||
* positive protocol number
|
||||
*
|
||||
* @note aliases are read from file for comparison, but not returned.
|
||||
* @see LookupProtoByNumber
|
||||
*/
|
||||
int LookupProtoByName(const char *protoname, char *buf, size_t bufsize,
|
||||
const char *filepath) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
char pathbuf[PATH_MAX];
|
||||
const char *path;
|
||||
size_t linesize;
|
||||
int found, result;
|
||||
char *name, *number, *alias, *comment, *tok;
|
||||
if (!(path = filepath)) {
|
||||
path = "/etc/protocols";
|
||||
if (IsWindows()) {
|
||||
path =
|
||||
firstnonnull(GetNtProtocolsTxtPath(pathbuf, ARRAYLEN(pathbuf)), path);
|
||||
}
|
||||
}
|
||||
if (bufsize == 0 || !(f = fopen(path, "r"))) {
|
||||
return -1;
|
||||
}
|
||||
line = NULL;
|
||||
linesize = 0;
|
||||
found = 0;
|
||||
result = -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)
|
||||
alias = strtok_r(NULL, " \t\r\n\v", &tok);
|
||||
if (alias) /* alias matched with protoname */
|
||||
{
|
||||
if (!memccpy(buf, name, '\0', bufsize)) {
|
||||
strcpy(buf, "");
|
||||
break;
|
||||
}
|
||||
result = atoi(number);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
if (ferror(f)) {
|
||||
errno = ferror(f);
|
||||
return -1;
|
||||
}
|
||||
fclose(f);
|
||||
if (!found) return -1;
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/dns/prototxt.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
/**
|
||||
* Opens and searches /etc/protocols to find name for a given number.
|
||||
*
|
||||
* The format of /etc/protocols is like this:
|
||||
*
|
||||
* # comment
|
||||
* # NAME PROTOCOL ALIASES
|
||||
* ip 0 IP
|
||||
* icmp 1 ICMP
|
||||
*
|
||||
* @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)
|
||||
* @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) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
char pathbuf[PATH_MAX];
|
||||
const char *path;
|
||||
size_t linesize;
|
||||
int found;
|
||||
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"))) {
|
||||
return -1;
|
||||
}
|
||||
line = NULL;
|
||||
linesize = 0;
|
||||
found = 0;
|
||||
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 && protonum == atoi(number)) {
|
||||
if (!memccpy(buf, name, '\0', bufsize)) {
|
||||
strcpy(buf, "");
|
||||
break;
|
||||
}
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
if (ferror(f)) {
|
||||
errno = ferror(f);
|
||||
return -1;
|
||||
}
|
||||
fclose(f);
|
||||
if (!found) return -1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
/**
|
||||
* Opens and searches /etc/services to find port for a given name.
|
||||
*
|
||||
* @param servname is a NULL-terminated string
|
||||
* @param servproto is a NULL-terminated string (eg "tcp", "udp")
|
||||
* (if servproto is an empty string,
|
||||
* if is filled with the first matching
|
||||
* protocol)
|
||||
* @param servprotolen the size of servproto
|
||||
* @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
|
||||
* (if NULL, uses /etc/services)
|
||||
* @return -1 on error, or positive port number
|
||||
* @note aliases are read from file for comparison, but not returned.
|
||||
* @see LookupServicesByPort
|
||||
*/
|
||||
int LookupServicesByName(const char *servname, char *servproto,
|
||||
size_t servprotolen, char *buf, size_t bufsize,
|
||||
const char *filepath) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
char pathbuf[PATH_MAX];
|
||||
const char *path;
|
||||
size_t linesize;
|
||||
int found, result;
|
||||
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"))) {
|
||||
return -1;
|
||||
}
|
||||
line = NULL;
|
||||
linesize = 0;
|
||||
found = 0;
|
||||
result = -1;
|
||||
if (buf && bufsize != 0) 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);
|
||||
port = strtok_r(NULL, "/ \t\r\n\v", &tok);
|
||||
proto = strtok_r(NULL, " \t\r\n\v", &tok);
|
||||
if (name && port && proto) {
|
||||
alias = name;
|
||||
while (alias && strcasecmp(alias, servname) != 0)
|
||||
alias = strtok_r(NULL, " \t\r\n\v", &tok);
|
||||
if (alias) /* alias matched with servname */
|
||||
{
|
||||
if (!servproto[0] || strncasecmp(proto, servproto, servprotolen) == 0) {
|
||||
if (!servproto[0] && !memccpy(servproto, proto, '\0', servprotolen)) {
|
||||
strcpy(servproto, "");
|
||||
break;
|
||||
}
|
||||
if (buf && bufsize != 0 && !memccpy(buf, name, '\0', bufsize)) {
|
||||
strcpy(buf, "");
|
||||
break;
|
||||
}
|
||||
result = atoi(port);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
if (ferror(f)) {
|
||||
errno = ferror(f);
|
||||
return -1;
|
||||
}
|
||||
fclose(f);
|
||||
if (!found) return -1;
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/dns/servicestxt.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
/**
|
||||
* Opens and searches /etc/services to find name for a given port.
|
||||
*
|
||||
* The format of /etc/services is like this:
|
||||
*
|
||||
* # comment
|
||||
* # NAME PORT/PROTOCOL ALIASES
|
||||
* ftp 21/tcp
|
||||
* fsp 21/udp fspd
|
||||
* ssh 22/tcp
|
||||
*
|
||||
* @param servport is the port number
|
||||
* @param servproto is a NULL-terminated string (eg "tcp", "udp")
|
||||
* (if servproto is an empty string,
|
||||
* if is filled with the first matching
|
||||
* protocol)
|
||||
* @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)
|
||||
* @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) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
char pathbuf[PATH_MAX];
|
||||
const char *path;
|
||||
size_t linesize;
|
||||
int found;
|
||||
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"))) {
|
||||
return -1;
|
||||
}
|
||||
line = NULL;
|
||||
linesize = 0;
|
||||
found = 0;
|
||||
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);
|
||||
port = strtok_r(NULL, "/ \t\r\n\v", &tok);
|
||||
proto = strtok_r(NULL, " \t\r\n\v", &tok);
|
||||
if (name && port && proto && servport == atoi(port)) {
|
||||
if (!servproto[0] || strncasecmp(proto, servproto, servprotolen) == 0) {
|
||||
if (!servproto[0] && !memccpy(servproto, proto, '\0', servprotolen)) {
|
||||
strcpy(servproto, "");
|
||||
break;
|
||||
}
|
||||
if (!memccpy(buf, name, '\0', bufsize)) {
|
||||
strcpy(buf, "");
|
||||
break;
|
||||
}
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
if (ferror(f)) {
|
||||
errno = ferror(f);
|
||||
return -1;
|
||||
}
|
||||
fclose(f);
|
||||
if (!found) return -1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*-*- 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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
|
||||
struct netent *getnetent(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct netent *getnetbyname(const char *name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct netent *getnetbyaddr(uint32_t net, int type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void setnetent(int stayopen) {
|
||||
}
|
||||
|
||||
void endnetent(void) {
|
||||
}
|
||||
@@ -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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
|
||||
struct protoent *getprotoent(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void setprotoent(int stayopen) {
|
||||
}
|
||||
|
||||
void endprotoent(void) {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_DNS_PROTOTXT_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_PROTOTXT_H_
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
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? */
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_PROTOTXT_H_ */
|
||||
@@ -23,7 +23,6 @@
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
@@ -52,7 +51,6 @@
|
||||
* @param name is a reversed IP address string ending with .in-addr.arpa
|
||||
* @param buf to store the obtained hostname if any
|
||||
* @param bufsize is size of buf
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @error EAFNOSUPPORT, ENETDOWN, ENAMETOOLONG, EBADMSG
|
||||
*/
|
||||
@@ -63,7 +61,6 @@ int ResolveDnsReverse(const struct ResolvConf *resolvconf, int af,
|
||||
struct DnsHeader h, h2;
|
||||
uint8_t *p, *pe, msg[512];
|
||||
uint16_t rtype, rclass, rdlength;
|
||||
|
||||
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
||||
if (!resolvconf->nameservers.i) return 0;
|
||||
memset(&h, 0, sizeof(h));
|
||||
@@ -76,7 +73,6 @@ int ResolveDnsReverse(const struct ResolvConf *resolvconf, int af,
|
||||
q.qclass = DNS_CLASS_IN;
|
||||
memset(msg, 0, sizeof(msg));
|
||||
SerializeDnsHeader(msg, &h);
|
||||
|
||||
if ((n = SerializeDnsQuestion(msg + 12, 500, &q)) == -1) return -1;
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return -1;
|
||||
if (sendto(fd, msg, 12 + n, 0, resolvconf->nameservers.p,
|
||||
@@ -103,7 +99,6 @@ int ResolveDnsReverse(const struct ResolvConf *resolvconf, int af,
|
||||
rclass = READ16BE(p), p += 2;
|
||||
/* ttl */ p += 4;
|
||||
rdlength = READ16BE(p), p += 2;
|
||||
|
||||
if (p + rdlength <= pe && rtype == DNS_TYPE_PTR &&
|
||||
rclass == DNS_CLASS_IN) {
|
||||
if (strnlen((char *)p, pe - p) + 1 > bufsize)
|
||||
|
||||
@@ -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│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
|
||||
struct servent *getservent(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void setservent(int stayopen) {
|
||||
}
|
||||
|
||||
void endservent(void) {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_DNS_SERVICESTXT_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_SERVICESTXT_H_
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
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);
|
||||
|
||||
/* TODO: implement like struct HostsTxt? */
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_DNS_SERVICESTXT_H_ */
|
||||
+23
-10
@@ -16,21 +16,34 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Decodes decimal number from ASCII string.
|
||||
* Decodes decimal integer from ASCII string.
|
||||
*
|
||||
* @param s is a non-null NUL-terminated string
|
||||
* @return the decoded signed saturated number
|
||||
* @note calling strtoimax() directly with base 0 permits greater
|
||||
* flexibility in terms of inputs
|
||||
* @param s is a non-null nul-terminated string
|
||||
* @return the decoded signed saturated integer
|
||||
*/
|
||||
int atoi(const char *s) {
|
||||
int res;
|
||||
res = strtoimax(s, NULL, 10);
|
||||
if (res < INT_MIN) return INT_MIN;
|
||||
if (res > INT_MAX) return INT_MAX;
|
||||
return res;
|
||||
int x, c, d;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (c == ' ' || c == '\t');
|
||||
d = c == '-' ? -1 : 1;
|
||||
if (c == '-' || c == '+') c = *s++;
|
||||
for (x = 0; isdigit(c); c = *s++) {
|
||||
if (__builtin_mul_overflow(x, 10, &x) ||
|
||||
__builtin_add_overflow(x, (c - '0') * d, &x)) {
|
||||
errno = ERANGE;
|
||||
if (d > 0) {
|
||||
return INT_MAX;
|
||||
} else {
|
||||
return INT_MIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
+27
-5
@@ -16,13 +16,35 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Decodes decimal integer from ASCII string.
|
||||
*
|
||||
* @param s is a non-null nul-terminated string
|
||||
* @return the decoded signed saturated integer
|
||||
*/
|
||||
long atol(const char *s) {
|
||||
long res;
|
||||
res = strtoimax(s, NULL, 10);
|
||||
if (res < LONG_MIN) return LONG_MIN;
|
||||
if (res > LONG_MAX) return LONG_MAX;
|
||||
return res;
|
||||
long x;
|
||||
int c, d;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (c == ' ' || c == '\t');
|
||||
d = c == '-' ? -1 : 1;
|
||||
if (c == '-' || c == '+') c = *s++;
|
||||
for (x = 0; isdigit(c); c = *s++) {
|
||||
if (__builtin_mul_overflow(x, 10, &x) ||
|
||||
__builtin_add_overflow(x, (c - '0') * d, &x)) {
|
||||
errno = ERANGE;
|
||||
if (d > 0) {
|
||||
return LONG_MAX;
|
||||
} else {
|
||||
return LONG_MIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
+8
-5
@@ -19,10 +19,13 @@
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/limits.h"
|
||||
|
||||
/**
|
||||
* Decodes decimal number from ASCII string.
|
||||
*
|
||||
* @param s is a non-null nul-terminated string
|
||||
* @return the decoded signed saturated integer
|
||||
*/
|
||||
long long atoll(const char *s) {
|
||||
long long res;
|
||||
res = strtoimax(s, NULL, 10);
|
||||
if (res < LONG_LONG_MIN) return LONG_LONG_MIN;
|
||||
if (res > LONG_LONG_MAX) return LONG_LONG_MAX;
|
||||
return res;
|
||||
_Static_assert(LONG_MAX == LONG_LONG_MAX, "need atoll impl");
|
||||
return atol(s);
|
||||
}
|
||||
Loaded 100 of 3718 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user