mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-06 17:06:23 +00:00
Make more fixes and improvements
This change attempts to fix some report build issues. It also builds upon development work described in previous changes.
This commit is contained in:
parent
9bfa6ec06e
commit
9d61e23c80
27 changed files with 980 additions and 902 deletions
|
@ -151,6 +151,14 @@ o/$(MODE)/examples/hello.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/examples/printargs.com.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/printargs.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
$(CRT) \
|
||||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/examples/nesemu1.o: QUOTA += -M512m
|
||||
|
||||
$(EXAMPLES_OBJS): examples/examples.mk
|
||||
|
|
|
@ -7,8 +7,30 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
int main() {
|
||||
__printargs("");
|
||||
int pip[2];
|
||||
char buf[PATH_MAX];
|
||||
char *args[2] = {0};
|
||||
if (strcmp(nulltoempty(getenv("TERM")), "dumb") && isatty(0) && isatty(1) &&
|
||||
((args[0] = commandv("less", buf)) ||
|
||||
(args[0] = commandv("more", buf)))) {
|
||||
close(0);
|
||||
close(2);
|
||||
pipe(pip);
|
||||
if (!vfork()) {
|
||||
close(2);
|
||||
execv(args[0], args);
|
||||
_Exit(127);
|
||||
}
|
||||
close(0);
|
||||
__printargs("");
|
||||
close(2);
|
||||
wait(0);
|
||||
} else {
|
||||
__printargs("");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1287,7 +1287,7 @@ struct bpf_spin_lock {
|
|||
};
|
||||
|
||||
struct bpf_sysctl {
|
||||
uint32_t write;
|
||||
uint32_t write_;
|
||||
uint32_t file_pos;
|
||||
};
|
||||
|
||||
|
|
|
@ -599,6 +599,8 @@ syscon sicode POLL_MSG 3 3 3 3 3 3 # SIGIO; input message availab
|
|||
syscon sicode POLL_ERR 4 4 4 4 4 4 # SIGIO; i/o error; unix consensus
|
||||
syscon sicode POLL_PRI 5 5 5 5 5 5 # SIGIO; high priority input available; unix consensus
|
||||
syscon sicode POLL_HUP 6 6 6 6 6 6 # SIGIO; device disconnected; unix consensus
|
||||
syscon sicode SYS_SECCOMP 1 -1 -1 -1 -1 -1 # SIGSYS; seccomp triggered
|
||||
syscon sicode SYS_USER_DISPATCH 2 -1 -1 -1 -1 -1 # SIGSYS; syscall user dispatch triggered
|
||||
|
||||
# sigaltstack() values
|
||||
#
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon reboot,RB_DISABLE_CAD,0,-1,-1,-1,-1,-1
|
||||
.syscon reboot,RB_DISABLE_CAD,0,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon reboot,RB_ENABLE_CAD,0x89abcdef,-1,-1,-1,-1,-1
|
||||
.syscon reboot,RB_ENABLE_CAD,0x89abcdef,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon reboot,RB_KEXEC,0x45584543,-1,-1,-1,-1,-1
|
||||
.syscon reboot,RB_KEXEC,0x45584543,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon reboot,RB_POWERDOWN,0x4321fedc,-1,0x4000,0x1000,0x808,8
|
||||
.syscon reboot,RB_POWERDOWN,0x4321fedc,0xffffffff,0x4000,0x1000,0x808,8
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon reboot,RB_POWEROFF,0x4321fedc,-1,0x4000,0x1000,0x808,8
|
||||
.syscon reboot,RB_POWEROFF,0x4321fedc,0xffffffff,0x4000,0x1000,0x808,8
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon reboot,RB_POWER_OFF,0x4321fedc,-1,0x4000,0x1000,0x808,8
|
||||
.syscon reboot,RB_POWER_OFF,0x4321fedc,0xffffffff,0x4000,0x1000,0x808,8
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon reboot,RB_SW_SUSPEND,0xd000fce2,-1,-1,-1,-1,0xd000fce2
|
||||
.syscon reboot,RB_SW_SUSPEND,0xd000fce2,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xd000fce2
|
||||
|
|
2
libc/sysv/consts/SYS_SECCOMP.S
Normal file
2
libc/sysv/consts/SYS_SECCOMP.S
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sicode,SYS_SECCOMP,1,-1,-1,-1,-1,-1
|
2
libc/sysv/consts/SYS_USER_DISPATCH.S
Normal file
2
libc/sysv/consts/SYS_USER_DISPATCH.S
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon sicode,SYS_USER_DISPATCH,2,-1,-1,-1,-1,-1
|
|
@ -52,6 +52,8 @@ extern const long POLL_MSG;
|
|||
extern const long POLL_ERR;
|
||||
extern const long POLL_PRI;
|
||||
extern const long POLL_HUP;
|
||||
extern const long SYS_SECCOMP;
|
||||
extern const long SYS_USER_DISPATCH;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
@ -80,30 +82,32 @@ COSMOPOLITAN_C_END_
|
|||
#define POLL_PRI LITERALLY(5)
|
||||
#define POLL_HUP LITERALLY(6)
|
||||
|
||||
#define SI_USER SYMBOLIC(SI_USER)
|
||||
#define SI_QUEUE SYMBOLIC(SI_QUEUE)
|
||||
#define SI_TIMER SYMBOLIC(SI_TIMER)
|
||||
#define SI_MESGQ SYMBOLIC(SI_MESGQ)
|
||||
#define SI_ASYNCIO SYMBOLIC(SI_ASYNCIO)
|
||||
#define SI_TKILL SYMBOLIC(SI_TKILL)
|
||||
#define SI_ASYNCNL SYMBOLIC(SI_ASYNCNL)
|
||||
#define SI_KERNEL SYMBOLIC(SI_KERNEL)
|
||||
#define SI_NOINFO SYMBOLIC(SI_NOINFO)
|
||||
#define SEGV_PKUERR SYMBOLIC(SEGV_PKUERR)
|
||||
#define FPE_INTDIV SYMBOLIC(FPE_INTDIV)
|
||||
#define FPE_INTOVF SYMBOLIC(FPE_INTOVF)
|
||||
#define FPE_FLTDIV SYMBOLIC(FPE_FLTDIV)
|
||||
#define FPE_FLTOVF SYMBOLIC(FPE_FLTOVF)
|
||||
#define FPE_FLTUND SYMBOLIC(FPE_FLTUND)
|
||||
#define FPE_FLTRES SYMBOLIC(FPE_FLTRES)
|
||||
#define FPE_FLTINV SYMBOLIC(FPE_FLTINV)
|
||||
#define FPE_FLTSUB SYMBOLIC(FPE_FLTSUB)
|
||||
#define ILL_ILLOPN SYMBOLIC(ILL_ILLOPN)
|
||||
#define ILL_ILLADR SYMBOLIC(ILL_ILLADR)
|
||||
#define ILL_ILLTRP SYMBOLIC(ILL_ILLTRP)
|
||||
#define ILL_PRVOPC SYMBOLIC(ILL_PRVOPC)
|
||||
#define BUS_OOMERR SYMBOLIC(BUS_OOMERR)
|
||||
#define BUS_MCEERR_AR SYMBOLIC(BUS_MCEERR_AR)
|
||||
#define BUS_MCEERR_AO SYMBOLIC(BUS_MCEERR_AO)
|
||||
#define SI_USER SYMBOLIC(SI_USER)
|
||||
#define SI_QUEUE SYMBOLIC(SI_QUEUE)
|
||||
#define SI_TIMER SYMBOLIC(SI_TIMER)
|
||||
#define SI_MESGQ SYMBOLIC(SI_MESGQ)
|
||||
#define SI_ASYNCIO SYMBOLIC(SI_ASYNCIO)
|
||||
#define SI_TKILL SYMBOLIC(SI_TKILL)
|
||||
#define SI_ASYNCNL SYMBOLIC(SI_ASYNCNL)
|
||||
#define SI_KERNEL SYMBOLIC(SI_KERNEL)
|
||||
#define SI_NOINFO SYMBOLIC(SI_NOINFO)
|
||||
#define SEGV_PKUERR SYMBOLIC(SEGV_PKUERR)
|
||||
#define FPE_INTDIV SYMBOLIC(FPE_INTDIV)
|
||||
#define FPE_INTOVF SYMBOLIC(FPE_INTOVF)
|
||||
#define FPE_FLTDIV SYMBOLIC(FPE_FLTDIV)
|
||||
#define FPE_FLTOVF SYMBOLIC(FPE_FLTOVF)
|
||||
#define FPE_FLTUND SYMBOLIC(FPE_FLTUND)
|
||||
#define FPE_FLTRES SYMBOLIC(FPE_FLTRES)
|
||||
#define FPE_FLTINV SYMBOLIC(FPE_FLTINV)
|
||||
#define FPE_FLTSUB SYMBOLIC(FPE_FLTSUB)
|
||||
#define ILL_ILLOPN SYMBOLIC(ILL_ILLOPN)
|
||||
#define ILL_ILLADR SYMBOLIC(ILL_ILLADR)
|
||||
#define ILL_ILLTRP SYMBOLIC(ILL_ILLTRP)
|
||||
#define ILL_PRVOPC SYMBOLIC(ILL_PRVOPC)
|
||||
#define BUS_OOMERR SYMBOLIC(BUS_OOMERR)
|
||||
#define BUS_MCEERR_AR SYMBOLIC(BUS_MCEERR_AR)
|
||||
#define BUS_MCEERR_AO SYMBOLIC(BUS_MCEERR_AO)
|
||||
#define SYS_SECCOMP SYMBOLIC(SYS_SECCOMP)
|
||||
#define SYS_USER_DISPATCH SYMBOLIC(SYS_USER_DISPATCH)
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SICODE_H_ */
|
||||
|
|
|
@ -148,19 +148,6 @@ noasan int main(int argc, char *argv[]) {
|
|||
EmptySignalMask();
|
||||
ShowCrashReports();
|
||||
|
||||
// so the test runner can terminate unknown children without
|
||||
// accidentally killing parent processes
|
||||
if (!IsWindows() && weaken(fork)) {
|
||||
setpgrp();
|
||||
}
|
||||
|
||||
// prevent runaway tests from bombing the computer
|
||||
cpus = GetCpuCount();
|
||||
cpus = MAX(4, cpus);
|
||||
SetLimit(RLIMIT_NOFILE, 32, 128);
|
||||
SetLimit(RLIMIT_SIGPENDING, 16, 16384);
|
||||
SetLimit(RLIMIT_NPROC, cpus * 8, 2048);
|
||||
|
||||
// now get down to business
|
||||
g_testlib_shoulddebugbreak = IsDebuggerPresent(false);
|
||||
if (!IsWindows()) sys_getpid(); // make strace easier to read
|
||||
|
|
34
third_party/mbedtls/test/test_suite_ssl.c
vendored
34
third_party/mbedtls/test/test_suite_ssl.c
vendored
|
@ -615,14 +615,14 @@ typedef struct mbedtls_test_message_socket_context
|
|||
{
|
||||
mbedtls_test_message_queue* queue_input;
|
||||
mbedtls_test_message_queue* queue_output;
|
||||
mbedtls_mock_socket* socket;
|
||||
mbedtls_mock_socket* socket_;
|
||||
} mbedtls_test_message_socket_context;
|
||||
|
||||
void mbedtls_message_socket_init( mbedtls_test_message_socket_context *ctx )
|
||||
{
|
||||
ctx->queue_input = NULL;
|
||||
ctx->queue_output = NULL;
|
||||
ctx->socket = NULL;
|
||||
ctx->socket_ = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -645,7 +645,7 @@ int mbedtls_message_socket_setup( mbedtls_test_message_queue* queue_input,
|
|||
return ret;
|
||||
ctx->queue_input = queue_input;
|
||||
ctx->queue_output = queue_output;
|
||||
ctx->socket = socket;
|
||||
ctx->socket_ = socket;
|
||||
mbedtls_mock_socket_init( socket );
|
||||
|
||||
return 0;
|
||||
|
@ -661,7 +661,7 @@ void mbedtls_message_socket_close( mbedtls_test_message_socket_context* ctx )
|
|||
return;
|
||||
|
||||
mbedtls_test_message_queue_free( ctx->queue_input );
|
||||
mbedtls_mock_socket_close( ctx->socket );
|
||||
mbedtls_mock_socket_close( ctx->socket_ );
|
||||
memset( ctx, 0, sizeof( *ctx ) );
|
||||
}
|
||||
|
||||
|
@ -683,14 +683,14 @@ int mbedtls_mock_tcp_send_msg( void *ctx, const unsigned char *buf, size_t len )
|
|||
mbedtls_mock_socket* socket;
|
||||
mbedtls_test_message_socket_context *context = (mbedtls_test_message_socket_context*) ctx;
|
||||
|
||||
if( context == NULL || context->socket == NULL
|
||||
if( context == NULL || context->socket_ == NULL
|
||||
|| context->queue_output == NULL )
|
||||
{
|
||||
return MBEDTLS_TEST_ERROR_CONTEXT_ERROR;
|
||||
}
|
||||
|
||||
queue = context->queue_output;
|
||||
socket = context->socket;
|
||||
socket = context->socket_;
|
||||
|
||||
if( queue->num >= queue->capacity )
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
|
@ -722,14 +722,14 @@ int mbedtls_mock_tcp_recv_msg( void *ctx, unsigned char *buf, size_t buf_len )
|
|||
size_t msg_len;
|
||||
int ret;
|
||||
|
||||
if( context == NULL || context->socket == NULL
|
||||
if( context == NULL || context->socket_ == NULL
|
||||
|| context->queue_input == NULL )
|
||||
{
|
||||
return MBEDTLS_TEST_ERROR_CONTEXT_ERROR;
|
||||
}
|
||||
|
||||
queue = context->queue_input;
|
||||
socket = context->socket;
|
||||
socket = context->socket_;
|
||||
|
||||
/* Peek first, so that in case of a socket error the data remains in
|
||||
* the queue. */
|
||||
|
@ -788,7 +788,7 @@ typedef struct mbedtls_endpoint
|
|||
mbedtls_ssl_config conf;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_mock_socket socket;
|
||||
mbedtls_mock_socket socket_;
|
||||
mbedtls_endpoint_certificate cert;
|
||||
} mbedtls_endpoint;
|
||||
|
||||
|
@ -939,12 +939,12 @@ int mbedtls_endpoint_init( mbedtls_endpoint *ep, int endpoint_type, int pk_alg,
|
|||
if( dtls_context != NULL )
|
||||
{
|
||||
TEST_ASSERT( mbedtls_message_socket_setup( input_queue, output_queue,
|
||||
100, &( ep->socket ),
|
||||
100, &( ep->socket_ ),
|
||||
dtls_context ) == 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mbedtls_mock_socket_init( &( ep->socket ) );
|
||||
mbedtls_mock_socket_init( &( ep->socket_ ) );
|
||||
}
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed( &( ep->ctr_drbg ), mbedtls_entropy_func,
|
||||
|
@ -962,7 +962,7 @@ int mbedtls_endpoint_init( mbedtls_endpoint *ep, int endpoint_type, int pk_alg,
|
|||
}
|
||||
else
|
||||
{
|
||||
mbedtls_ssl_set_bio( &( ep->ssl ), &( ep->socket ),
|
||||
mbedtls_ssl_set_bio( &( ep->ssl ), &( ep->socket_ ),
|
||||
mbedtls_mock_tcp_send_nb,
|
||||
mbedtls_mock_tcp_recv_nb,
|
||||
NULL );
|
||||
|
@ -1020,7 +1020,7 @@ void mbedtls_endpoint_free( mbedtls_endpoint *ep,
|
|||
}
|
||||
else
|
||||
{
|
||||
mbedtls_mock_socket_close( &( ep->socket ) );
|
||||
mbedtls_mock_socket_close( &( ep->socket_ ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1870,8 +1870,8 @@ void perform_handshake( handshake_test_options* options )
|
|||
}
|
||||
#endif
|
||||
|
||||
TEST_ASSERT( mbedtls_mock_socket_connect( &(client.socket),
|
||||
&(server.socket),
|
||||
TEST_ASSERT( mbedtls_mock_socket_connect( &(client.socket_),
|
||||
&(server.socket_),
|
||||
BUFFSIZE ) == 0 );
|
||||
|
||||
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
|
||||
|
@ -4375,8 +4375,8 @@ void test_move_handshake_to_state(int endpoint_type, int state, int need_pass)
|
|||
MBEDTLS_PK_RSA, NULL, NULL, NULL );
|
||||
TEST_ASSERT( ret == 0 );
|
||||
|
||||
ret = mbedtls_mock_socket_connect( &(base_ep.socket),
|
||||
&(second_ep.socket),
|
||||
ret = mbedtls_mock_socket_connect( &(base_ep.socket_),
|
||||
&(second_ep.socket_),
|
||||
BUFFSIZE );
|
||||
TEST_ASSERT( ret == 0 );
|
||||
|
||||
|
|
4
third_party/python/python.mk
vendored
4
third_party/python/python.mk
vendored
|
@ -466,12 +466,12 @@ THIRD_PARTY_PYTHON_STAGE1_A_DIRECTDEPS = \
|
|||
THIRD_PARTY_PYTHON_STAGE1_A_DEPS = \
|
||||
$(call uniq,$(foreach x,$(THIRD_PARTY_PYTHON_STAGE1_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/third_party/python/Python/importlib.inc: \
|
||||
o//third_party/python/Python/importlib.inc: \
|
||||
o/$(MODE)/third_party/python/freeze.com \
|
||||
third_party/python/Lib/importlib/_bootstrap.py
|
||||
@$(COMPILE) -AFREEZE -T$@ $^ $@
|
||||
|
||||
o/$(MODE)/third_party/python/Python/importlib_external.inc: \
|
||||
o//third_party/python/Python/importlib_external.inc: \
|
||||
o/$(MODE)/third_party/python/freeze.com \
|
||||
third_party/python/Lib/importlib/_bootstrap_external.py
|
||||
@$(COMPILE) -AFREEZE -T$@ $^ $@
|
||||
|
|
160
tool/build/jail.c
Normal file
160
tool/build/jail.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/filter.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/user_regs_struct.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/pr.h"
|
||||
#include "libc/sysv/consts/ptrace.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "tool/net/sandbox.h"
|
||||
|
||||
#define __WALL 0x40000000
|
||||
|
||||
static const struct sock_filter kSandboxFilter[] = {
|
||||
_SECCOMP_MACHINE(AUDIT_ARCH_X86_64), //
|
||||
_SECCOMP_LOAD_SYSCALL_NR(), //
|
||||
_SECCOMP_ALLOW_SYSCALL(0x000), // read
|
||||
_SECCOMP_ALLOW_SYSCALL(0x001), // write
|
||||
_SECCOMP_ALLOW_SYSCALL(0x013), // readv
|
||||
_SECCOMP_ALLOW_SYSCALL(0x014), // writev
|
||||
_SECCOMP_ALLOW_SYSCALL(0x005), // fstat
|
||||
_SECCOMP_ALLOW_SYSCALL(0x007), // poll
|
||||
_SECCOMP_ALLOW_SYSCALL(0x008), // lseek
|
||||
_SECCOMP_ALLOW_SYSCALL(0x009), // mmap
|
||||
_SECCOMP_ALLOW_SYSCALL(0x00b), // munmap
|
||||
_SECCOMP_ALLOW_SYSCALL(0x003), // close
|
||||
_SECCOMP_ALLOW_SYSCALL(0x010), // ioctl todo
|
||||
_SECCOMP_ALLOW_SYSCALL(0x016), // pipe
|
||||
_SECCOMP_ALLOW_SYSCALL(0x125), // pipe2
|
||||
_SECCOMP_ALLOW_SYSCALL(0x035), // socketpair
|
||||
_SECCOMP_ALLOW_SYSCALL(0x020), // dup
|
||||
_SECCOMP_ALLOW_SYSCALL(0x021), // dup2
|
||||
_SECCOMP_ALLOW_SYSCALL(0x124), // dup3
|
||||
_SECCOMP_ALLOW_SYSCALL(0x039), // fork
|
||||
_SECCOMP_ALLOW_SYSCALL(0x03a), // vfork
|
||||
_SECCOMP_ALLOW_SYSCALL(0x011), // pread
|
||||
_SECCOMP_ALLOW_SYSCALL(0x012), // pwrite
|
||||
_SECCOMP_ALLOW_SYSCALL(0x127), // preadv
|
||||
_SECCOMP_ALLOW_SYSCALL(0x128), // pwritev
|
||||
_SECCOMP_ALLOW_SYSCALL(0x0d9), // getdents
|
||||
_SECCOMP_ALLOW_SYSCALL(0x028), // sendfile
|
||||
_SECCOMP_ALLOW_SYSCALL(0x02d), // recvfrom
|
||||
_SECCOMP_ALLOW_SYSCALL(0x033), // getsockname
|
||||
_SECCOMP_ALLOW_SYSCALL(0x034), // getpeername
|
||||
_SECCOMP_ALLOW_SYSCALL(0x00f), // rt_sigreturn
|
||||
_SECCOMP_ALLOW_SYSCALL(0x0e4), // clock_gettime
|
||||
_SECCOMP_ALLOW_SYSCALL(0x060), // gettimeofday
|
||||
_SECCOMP_ALLOW_SYSCALL(0x027), // getpid
|
||||
_SECCOMP_ALLOW_SYSCALL(0x03f), // uname
|
||||
_SECCOMP_ALLOW_SYSCALL(0x03c), // exit
|
||||
_SECCOMP_ALLOW_SYSCALL(0x0e7), // exit_group
|
||||
_SECCOMP_TRACE_SYSCALL(0x03e, 0), // kill
|
||||
_SECCOMP_TRACE_SYSCALL(0x101, 0), // openat
|
||||
_SECCOMP_TRACE_SYSCALL(0x106, 0), // newfstatat
|
||||
_SECCOMP_TRACE_SYSCALL(0x029, 0), // socket
|
||||
_SECCOMP_TRACE_SYSCALL(0x031, 0), // bind
|
||||
_SECCOMP_TRACE_SYSCALL(0x02a, 0), // connect
|
||||
_SECCOMP_TRACE_SYSCALL(0x02c, 0), // sendto
|
||||
_SECCOMP_TRACE_SYSCALL(0x036, 0), // setsockopt
|
||||
_SECCOMP_TRACE_SYSCALL(0x048, 0), // fcntl
|
||||
_SECCOMP_TRACE_SYSCALL(0x03b, 0), // execve
|
||||
_SECCOMP_TRACE_SYSCALL(0x102, 0), // mkdirat
|
||||
_SECCOMP_TRACE_SYSCALL(0x104, 0), // chownat
|
||||
_SECCOMP_TRACE_SYSCALL(0x107, 0), // unlinkat
|
||||
_SECCOMP_TRACE_SYSCALL(0x108, 0), // renameat
|
||||
_SECCOMP_TRACE_SYSCALL(0x109, 0), // linkat
|
||||
_SECCOMP_TRACE_SYSCALL(0x10a, 0), // symlinkat
|
||||
_SECCOMP_TRACE_SYSCALL(0x10b, 0), // readlinkat
|
||||
_SECCOMP_TRACE_SYSCALL(0x10c, 0), // fchmodat
|
||||
_SECCOMP_TRACE_SYSCALL(0x10d, 0), // faccessat
|
||||
_SECCOMP_TRACE_SYSCALL(0x0eb, 0), // utimes
|
||||
_SECCOMP_TRACE_SYSCALL(0x105, 0), // futimesat
|
||||
_SECCOMP_TRACE_SYSCALL(0x118, 0), // utimensat
|
||||
_SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM
|
||||
};
|
||||
|
||||
static const struct sock_fprog kSandbox = {
|
||||
.len = ARRAYLEN(kSandboxFilter),
|
||||
.filter = kSandboxFilter,
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct user_regs_struct regs;
|
||||
int child, evpid, signal, wstatus;
|
||||
|
||||
if (!IsLinux()) {
|
||||
kprintf("error: %s is only supported on linux right now%n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (argc < 2) {
|
||||
kprintf("Usage: %s PROGRAM [ARGS...]%n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
ShowCrashReports();
|
||||
|
||||
CHECK_NE(-1, (child = fork()));
|
||||
if (!child) {
|
||||
if (ptrace(PTRACE_TRACEME) == -1) _Exit(124);
|
||||
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) _Exit(125);
|
||||
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &kSandbox) == -1) _Exit(126);
|
||||
execvp(argv[1], argv + 1);
|
||||
_Exit(127);
|
||||
}
|
||||
|
||||
sigaction(SIGINT, &(struct sigaction){.sa_handler = SIG_IGN}, 0);
|
||||
sigaction(SIGQUIT, &(struct sigaction){.sa_handler = SIG_IGN}, 0);
|
||||
|
||||
// wait for ptrace(PTRACE_TRACEME) to be called
|
||||
CHECK_EQ(child, waitpid(child, &wstatus, 0));
|
||||
|
||||
// configure linux process tracing
|
||||
CHECK_NE(-1, ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESECCOMP));
|
||||
|
||||
// continue child process
|
||||
CHECK_NE(-1, ptrace(PTRACE_CONT, child, 0, 0));
|
||||
|
||||
for (;;) {
|
||||
CHECK_NE(-1, (evpid = waitpid(-1, &wstatus, __WALL)));
|
||||
if (WIFSTOPPED(wstatus)) {
|
||||
signal = (wstatus >> 8) & 0xffff;
|
||||
if (signal == SIGTRAP | PTRACE_EVENT_SECCOMP) {
|
||||
// CHECK_NE(-1, ptrace(PTRACE_GETEVENTMSG, evpid, 0, &msg));
|
||||
CHECK_NE(-1, ptrace(PTRACE_GETREGS, evpid, 0, regs));
|
||||
regs.rax = -EPERM;
|
||||
CHECK_NE(-1, ptrace(PTRACE_GETREGS, evpid, 0, regs));
|
||||
ptrace(PTRACE_CONT, evpid, 0, 0);
|
||||
} else {
|
||||
ptrace(PTRACE_CONT, evpid, 0, signal & 127);
|
||||
}
|
||||
} else if (WIFEXITED(wstatus)) {
|
||||
exit(WEXITSTATUS(wstatus));
|
||||
} else {
|
||||
exit(128 + WTERMSIG(wstatus));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -167,7 +167,7 @@ struct Packages {
|
|||
struct Symbol {
|
||||
uint32_t name; // pkg->strings.p[name]
|
||||
enum SectionKind kind : 8;
|
||||
uint8_t bind : 4;
|
||||
uint8_t bind_ : 4;
|
||||
uint8_t type : 4;
|
||||
uint16_t object; // pkg->objects.p[object]
|
||||
} * p; // persisted as pkg+RVA
|
||||
|
@ -342,9 +342,9 @@ void LoadSymbols(struct Package *pkg, uint32_t object) {
|
|||
obj = &pkg->objects.p[object];
|
||||
symbol.object = object;
|
||||
for (i = 0; i < obj->symcount; ++i) {
|
||||
symbol.bind = ELF64_ST_BIND(obj->syms[i].st_info);
|
||||
symbol.bind_ = ELF64_ST_BIND(obj->syms[i].st_info);
|
||||
symbol.type = ELF64_ST_TYPE(obj->syms[i].st_info);
|
||||
if (symbol.bind != STB_LOCAL &&
|
||||
if (symbol.bind_ != STB_LOCAL &&
|
||||
(symbol.type == STT_OBJECT || symbol.type == STT_FUNC ||
|
||||
symbol.type == STT_COMMON || symbol.type == STT_NOTYPE)) {
|
||||
name = GetElfString(obj->elf, obj->size, obj->strs, obj->syms[i].st_name);
|
||||
|
@ -448,7 +448,7 @@ void CheckStrictDeps(struct Package *pkg, struct Packages *deps) {
|
|||
struct Symbol *undef;
|
||||
for (i = 0; i < pkg->undefs.i; ++i) {
|
||||
undef = &pkg->undefs.p[i];
|
||||
if (undef->bind == STB_WEAK) continue;
|
||||
if (undef->bind_ == STB_WEAK) continue;
|
||||
if (!FindSymbol(pkg->strings.p + undef->name, pkg, deps, NULL, NULL)) {
|
||||
fprintf(stderr, "%s: %`'s (%s) %s %s\n", "error",
|
||||
pkg->strings.p + undef->name,
|
||||
|
|
|
@ -600,7 +600,11 @@
|
|||
(when root
|
||||
(let ((default-directory root))
|
||||
(save-buffer)
|
||||
(cond ((file-executable-p file)
|
||||
(cond ((save-excursion
|
||||
(goto-char (point-min))
|
||||
(looking-at "#!"))
|
||||
(compile (format "sh %s" file)))
|
||||
((file-executable-p file)
|
||||
(compile (if (cosmo-contains "/" file)
|
||||
file
|
||||
(format "./%s" file))))
|
||||
|
@ -610,6 +614,8 @@
|
|||
(compile compile-command)))
|
||||
((eq major-mode 'sh-mode)
|
||||
(compile (format "sh %s" file)))
|
||||
((eq major-mode 'lua-mode)
|
||||
(compile (format "lua.com %s" file)))
|
||||
((and (eq major-mode 'python-mode)
|
||||
(cosmo-startswith "third_party/python/Lib/test/" file))
|
||||
(let ((mode (cosmo--make-mode arg)))
|
||||
|
@ -673,6 +679,7 @@
|
|||
(define-key c-mode-base-map (kbd "C-c C-r") 'cosmo-run)
|
||||
(define-key fortran-mode-map (kbd "C-c C-r") 'cosmo-run)
|
||||
(define-key sh-mode-map (kbd "C-c C-r") 'cosmo-run)
|
||||
(define-key lua-mode-map (kbd "C-c C-r") 'cosmo-run)
|
||||
(define-key python-mode-map (kbd "C-c C-r") 'cosmo-run)
|
||||
(define-key c-mode-map (kbd "C-c C-s") 'cosmo-run-test)
|
||||
(define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win10))
|
||||
|
|
149
tool/net/echo.c
Normal file
149
tool/net/echo.c
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ 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/fmt/conv.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "net/http/http.h"
|
||||
|
||||
/**
|
||||
* @fileoverview tcp/udp echo servers/clients
|
||||
* use it to fill your network with junk data
|
||||
*/
|
||||
|
||||
int sock;
|
||||
char buf[1000];
|
||||
struct sockaddr_in addr = {0};
|
||||
uint32_t addrsize = sizeof(struct sockaddr_in);
|
||||
|
||||
void PrintUsage(char **argv) {
|
||||
kprintf("usage: %s udp server [ip port]%n", argv[0]);
|
||||
kprintf(" %s tcp server [ip port]%n", argv[0]);
|
||||
kprintf(" %s udp client [ip port]%n", argv[0]);
|
||||
kprintf(" %s tcp client [ip port]%n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void UdpServer(void) {
|
||||
ssize_t rc;
|
||||
struct sockaddr_in addr2;
|
||||
uint32_t addrsize2 = sizeof(struct sockaddr_in);
|
||||
CHECK_NE(-1, (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)));
|
||||
CHECK_NE(-1, bind(sock, &addr, addrsize));
|
||||
CHECK_NE(-1, getsockname(sock, &addr2, &addrsize2));
|
||||
kprintf("udp server %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24,
|
||||
addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8,
|
||||
addr2.sin_addr.s_addr, addr2.sin_port);
|
||||
for (;;) {
|
||||
CHECK_NE(-1,
|
||||
(rc = recvfrom(sock, buf, sizeof(buf), 0, &addr2, &addrsize2)));
|
||||
CHECK_NE(-1, sendto(sock, buf, rc, 0, &addr2, addrsize2));
|
||||
}
|
||||
}
|
||||
|
||||
void UdpClient(void) {
|
||||
CHECK_NE(-1, (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)));
|
||||
CHECK_NE(-1, connect(sock, &addr, addrsize));
|
||||
for (;;) {
|
||||
rngset(buf, sizeof(buf), rand64, -1);
|
||||
CHECK_NE(-1, write(sock, &addr, addrsize));
|
||||
}
|
||||
}
|
||||
|
||||
void TcpServer(void) {
|
||||
int client;
|
||||
ssize_t rc;
|
||||
struct sockaddr_in addr2;
|
||||
uint32_t addrsize2 = sizeof(struct sockaddr_in);
|
||||
CHECK_NE(-1, (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)));
|
||||
CHECK_NE(-1, bind(sock, &addr, addrsize));
|
||||
CHECK_NE(-1, listen(sock, 10));
|
||||
CHECK_NE(-1, getsockname(sock, &addr2, &addrsize2));
|
||||
kprintf("tcp server %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24,
|
||||
addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8,
|
||||
addr2.sin_addr.s_addr, addr2.sin_port);
|
||||
for (;;) {
|
||||
addrsize2 = sizeof(struct sockaddr_in);
|
||||
CHECK_NE(-1, (client = accept(sock, &addr2, &addrsize2)));
|
||||
kprintf("got client %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24,
|
||||
addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8,
|
||||
addr2.sin_addr.s_addr, addr2.sin_port);
|
||||
for (;;) {
|
||||
CHECK_NE(-1, (rc = read(client, buf, sizeof(buf))));
|
||||
if (!rc) break;
|
||||
CHECK_NE(-1, write(client, buf, rc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TcpClient(void) {
|
||||
CHECK_NE(-1, (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)));
|
||||
CHECK_NE(-1, connect(sock, &addr, addrsize));
|
||||
for (;;) {
|
||||
rngset(buf, sizeof(buf), rand64, -1);
|
||||
CHECK_NE(-1, write(sock, buf, sizeof(buf)));
|
||||
CHECK_NE(-1, read(sock, buf, sizeof(buf)));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int port = 0;
|
||||
int64_t ip = 0;
|
||||
if (argc < 3) PrintUsage(argv);
|
||||
if (argc >= 4) {
|
||||
if ((ip = ParseIp(argv[3], -1)) == -1) {
|
||||
PrintUsage(argv);
|
||||
}
|
||||
}
|
||||
if (argc >= 5) {
|
||||
port = atoi(argv[4]);
|
||||
if (port & 0xffff0000) {
|
||||
PrintUsage(argv);
|
||||
}
|
||||
}
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = htonl(ip);
|
||||
if (!strcmp(argv[1], "udp")) {
|
||||
if (!strcmp(argv[2], "server")) {
|
||||
UdpServer();
|
||||
} else if (!strcmp(argv[2], "client")) {
|
||||
UdpClient();
|
||||
} else {
|
||||
PrintUsage(argv);
|
||||
}
|
||||
} else if (!strcmp(argv[1], "tcp")) {
|
||||
if (!strcmp(argv[2], "server")) {
|
||||
TcpServer();
|
||||
} else if (!strcmp(argv[2], "client")) {
|
||||
TcpClient();
|
||||
} else {
|
||||
PrintUsage(argv);
|
||||
}
|
||||
} else {
|
||||
PrintUsage(argv);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,297 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ 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/alg/arraylist.internal.h"
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/interruptiblecall.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/msg.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/so.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Asynchronous TCP/UDP Echo Server.
|
||||
*
|
||||
* make -j8 o/default/tool/net/echoserver.com
|
||||
* o/default/tool/net/echoserver.com udp:0.0.0.0:7 tcp:0.0.0.0:7
|
||||
*/
|
||||
|
||||
enum SocketKind {
|
||||
kSocketServer,
|
||||
kSocketClient,
|
||||
};
|
||||
|
||||
struct Message {
|
||||
struct iovec data;
|
||||
struct sockaddr_in dest;
|
||||
uint32_t destsize;
|
||||
};
|
||||
|
||||
struct Messages {
|
||||
size_t i, n;
|
||||
struct Message *p;
|
||||
};
|
||||
|
||||
struct Socket {
|
||||
int64_t fd;
|
||||
enum SocketKind kind;
|
||||
int type;
|
||||
int protocol;
|
||||
struct sockaddr_in addr;
|
||||
struct Messages egress; /* LIFO */
|
||||
};
|
||||
|
||||
struct Sockets {
|
||||
size_t i, n;
|
||||
struct Socket *p;
|
||||
};
|
||||
|
||||
struct Polls {
|
||||
size_t i, n;
|
||||
struct pollfd *p;
|
||||
};
|
||||
|
||||
struct Sockets g_sockets;
|
||||
struct Polls g_polls;
|
||||
|
||||
dontdiscard char *DescribeAddress(struct sockaddr_in *addr) {
|
||||
char ip4buf[16];
|
||||
return xasprintf("%s:%hu",
|
||||
inet_ntop(addr->sin_family, &addr->sin_addr.s_addr, ip4buf,
|
||||
sizeof(ip4buf)),
|
||||
ntohs(addr->sin_port));
|
||||
}
|
||||
|
||||
dontdiscard char *DescribeSocket(struct Socket *s) {
|
||||
return xasprintf("%s:%s", s->protocol == IPPROTO_UDP ? "udp" : "tcp",
|
||||
gc(DescribeAddress(&s->addr)));
|
||||
}
|
||||
|
||||
wontreturn void ShowUsageAndExit(bool iserror) {
|
||||
FILE *f = iserror ? stderr : stdout;
|
||||
int rc = iserror ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
fprintf(f, "%s: %s %s\n", "Usage", __argv[0], "PROTOCOL:ADDR:PORT...");
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
void GetFlags(int argc, char *argv[]) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "h")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
ShowUsageAndExit(false);
|
||||
default:
|
||||
ShowUsageAndExit(true);
|
||||
}
|
||||
}
|
||||
if (optind == argc) ShowUsageAndExit(true);
|
||||
}
|
||||
|
||||
void AddSocket(const struct Socket *s) {
|
||||
struct pollfd pfd;
|
||||
pfd.fd = s->fd;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
CHECK_NE(-1L, append(&g_sockets, s));
|
||||
CHECK_NE(-1L, append(&g_polls, &pfd));
|
||||
}
|
||||
|
||||
void RemoveSocket(size_t i) {
|
||||
DCHECK_LT(i, g_sockets.i);
|
||||
INFOF("removing: %s", gc(DescribeSocket(&g_sockets.p[i])));
|
||||
CHECK_NE(-1, close(g_sockets.p[i].fd));
|
||||
while (g_sockets.p[i].egress.i) {
|
||||
free(g_sockets.p[i].egress.p[g_sockets.p[i].egress.i - 1].data.iov_base);
|
||||
}
|
||||
memcpy(&g_sockets.p[i], &g_sockets.p[i + 1],
|
||||
(intptr_t)&g_sockets.p[g_sockets.i] - (intptr_t)&g_sockets.p[i + 1]);
|
||||
memcpy(&g_polls.p[i], &g_polls.p[i + 1],
|
||||
(intptr_t)&g_polls.p[g_polls.i] - (intptr_t)&g_polls.p[i + 1]);
|
||||
g_sockets.i--;
|
||||
g_polls.i--;
|
||||
}
|
||||
|
||||
void GetListeningAddressesFromCommandLine(int argc, char *argv[]) {
|
||||
int i;
|
||||
for (i = optind; i < argc; ++i) {
|
||||
struct Socket server;
|
||||
bzero(&server, sizeof(server));
|
||||
char scheme[4];
|
||||
unsigned char *ip4 = (unsigned char *)&server.addr.sin_addr.s_addr;
|
||||
uint16_t port;
|
||||
if (sscanf(argv[i], "%3s:%hhu.%hhu.%hhu.%hhu:%hu", scheme, &ip4[0], &ip4[1],
|
||||
&ip4[2], &ip4[3], &port) != 6) {
|
||||
fprintf(stderr, "error: bad ip4 uri\n");
|
||||
ShowUsageAndExit(true);
|
||||
}
|
||||
server.fd = -1;
|
||||
server.kind = kSocketServer;
|
||||
server.addr.sin_family = AF_INET;
|
||||
server.addr.sin_port = htons(port);
|
||||
if (strcasecmp(scheme, "tcp") == 0) {
|
||||
server.type = SOCK_STREAM;
|
||||
server.protocol = IPPROTO_TCP;
|
||||
} else if (strcasecmp(scheme, "udp") == 0) {
|
||||
server.type = SOCK_DGRAM;
|
||||
server.protocol = IPPROTO_UDP;
|
||||
} else {
|
||||
fprintf(stderr, "%s: %s\n", "error", "bad scheme (should be tcp or udp)");
|
||||
ShowUsageAndExit(true);
|
||||
}
|
||||
AddSocket(&server);
|
||||
}
|
||||
}
|
||||
|
||||
void BeginListeningForIncomingTraffic(void) {
|
||||
size_t i;
|
||||
for (i = 0; i < g_sockets.i; ++i) {
|
||||
int yes = 1;
|
||||
struct Socket *s = &g_sockets.p[i];
|
||||
CHECK_NE(-1L, (g_polls.p[i].fd = s->fd =
|
||||
socket(s->addr.sin_family, s->type, s->protocol)));
|
||||
CHECK_NE(-1L,
|
||||
setsockopt(s->fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)));
|
||||
CHECK_NE(-1, bind(s->fd, &s->addr, sizeof(s->addr)));
|
||||
if (s->protocol == IPPROTO_TCP) {
|
||||
CHECK_NE(-1, listen(s->fd, 1));
|
||||
}
|
||||
uint32_t addrsize = sizeof(s->addr);
|
||||
CHECK_NE(-1, getsockname(s->fd, &s->addr, &addrsize));
|
||||
INFOF("listening on %s", gc(DescribeSocket(s)));
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptConnection(size_t i) {
|
||||
struct Socket *server = &g_sockets.p[i];
|
||||
struct Socket client;
|
||||
bzero(&client, sizeof(client));
|
||||
client.kind = kSocketClient;
|
||||
client.type = server->type;
|
||||
client.protocol = server->protocol;
|
||||
uint32_t addrsize = sizeof(client.addr);
|
||||
CHECK_NE(-1L, (client.fd = accept(server->fd, &client.addr, &addrsize)));
|
||||
INFOF("%s accepted %s", gc(DescribeSocket(server)),
|
||||
gc(DescribeSocket(&client)));
|
||||
AddSocket(&client);
|
||||
}
|
||||
|
||||
bool ReceiveData(size_t i) {
|
||||
ssize_t got;
|
||||
struct Message msg;
|
||||
bool isudp = g_sockets.p[i].protocol == IPPROTO_UDP;
|
||||
bzero(&msg, sizeof(msg));
|
||||
msg.destsize = sizeof(msg.dest);
|
||||
msg.data.iov_len = PAGESIZE;
|
||||
msg.data.iov_base = xmalloc(msg.data.iov_len);
|
||||
CHECK_NE(-1L, (got = recvfrom(g_sockets.p[i].fd, msg.data.iov_base,
|
||||
msg.data.iov_len, 0, isudp ? &msg.dest : NULL,
|
||||
isudp ? &msg.destsize : NULL)));
|
||||
if (0 < got && got <= msg.data.iov_len) {
|
||||
INFOF("%s received %lu bytes from %s", gc(DescribeSocket(&g_sockets.p[i])),
|
||||
got, gc(DescribeAddress(&msg.dest)));
|
||||
msg.data.iov_base = xrealloc(msg.data.iov_base, (msg.data.iov_len = got));
|
||||
append(&g_sockets.p[i].egress, &msg);
|
||||
g_polls.p[i].events |= POLLOUT;
|
||||
return true;
|
||||
} else {
|
||||
RemoveSocket(i);
|
||||
free_s(&msg.data.iov_base);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SendData(size_t i) {
|
||||
ssize_t sent;
|
||||
struct Socket *s = &g_sockets.p[i];
|
||||
struct Message *msg = &s->egress.p[s->egress.i - 1];
|
||||
bool isudp = s->protocol == IPPROTO_UDP;
|
||||
DCHECK(s->egress.i);
|
||||
CHECK_NE(-1L, (sent = sendto(s->fd, msg->data.iov_base, msg->data.iov_len, 0,
|
||||
isudp ? &msg->dest : NULL,
|
||||
isudp ? msg->destsize : 0)));
|
||||
INFOF("%s sent %lu bytes to %s", gc(DescribeSocket(s)), msg->data.iov_len,
|
||||
gc(DescribeAddress(&msg->dest)));
|
||||
if (!(msg->data.iov_len -= min((size_t)sent, (size_t)msg->data.iov_len))) {
|
||||
free_s(&msg->data.iov_base);
|
||||
if (!--s->egress.i) {
|
||||
g_polls.p[i].events &= ~POLLOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSomeNetworkTraffic(void) {
|
||||
size_t i;
|
||||
int eventcount;
|
||||
CHECK_GE((eventcount = poll(g_polls.p, g_polls.i, -1)), 0);
|
||||
for (i = 0; eventcount && i < g_sockets.i; ++i) {
|
||||
if (!g_polls.p[i].revents) continue;
|
||||
--eventcount;
|
||||
if (g_polls.p[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
|
||||
CHECK_EQ(kSocketClient, g_sockets.p[i].kind);
|
||||
RemoveSocket(i);
|
||||
} else {
|
||||
if (g_polls.p[i].revents & POLLIN) {
|
||||
if (g_sockets.p[i].kind == kSocketServer &&
|
||||
g_sockets.p[i].protocol == IPPROTO_TCP) {
|
||||
AcceptConnection(i);
|
||||
} else {
|
||||
if (!ReceiveData(i)) continue;
|
||||
}
|
||||
}
|
||||
if (g_polls.p[i].revents & POLLOUT) {
|
||||
SendData(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EchoServer(void) {
|
||||
for (;;) HandleSomeNetworkTraffic();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
STATIC_YOINK("isatty");
|
||||
GetFlags(argc, argv);
|
||||
GetListeningAddressesFromCommandLine(argc, argv);
|
||||
BeginListeningForIncomingTraffic();
|
||||
struct InterruptibleCall icall;
|
||||
bzero(&icall, sizeof(icall));
|
||||
interruptiblecall(&icall, (void *)EchoServer, 0, 0, 0, 0);
|
||||
fputc('\r', stderr);
|
||||
INFOF("%s", "shutting down...");
|
||||
size_t i;
|
||||
for (i = g_sockets.i; i; --i) RemoveSocket(i - 1);
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load diff
162
tool/net/lunix.c
162
tool/net/lunix.c
|
@ -381,23 +381,23 @@ static int LuaUnixExecve(lua_State *L) {
|
|||
|
||||
// unix.commandv(prog:str) → path:str[, errno:int]
|
||||
static int LuaUnixCommandv(lua_State *L) {
|
||||
int rc, olderr;
|
||||
const char *prog;
|
||||
int rc, olderr, pushed;
|
||||
char *pathbuf, *resolved;
|
||||
olderr = errno;
|
||||
pathbuf = xmalloc(PATH_MAX);
|
||||
prog = luaL_checkstring(L, 1);
|
||||
if ((resolved = commandv(prog, pathbuf))) {
|
||||
lua_pushstring(L, resolved);
|
||||
pushed = 1;
|
||||
if ((pathbuf = malloc(PATH_MAX))) {
|
||||
prog = luaL_checkstring(L, 1);
|
||||
if ((resolved = commandv(prog, pathbuf))) {
|
||||
lua_pushstring(L, resolved);
|
||||
free(pathbuf);
|
||||
return 1;
|
||||
} else {
|
||||
free(pathbuf);
|
||||
return ReturnErrno(L, 1, olderr);
|
||||
}
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, errno);
|
||||
errno = olderr;
|
||||
pushed = 2;
|
||||
return ReturnErrno(L, 1, olderr);
|
||||
}
|
||||
free(pathbuf);
|
||||
return pushed;
|
||||
}
|
||||
|
||||
// unix.realpath(path:str) → path:str[, errno:int]
|
||||
|
@ -720,31 +720,31 @@ static int LuaUnixTruncate(lua_State *L) {
|
|||
static int LuaUnixRead(lua_State *L) {
|
||||
char *buf;
|
||||
size_t got;
|
||||
int fd, olderr, pushed;
|
||||
int fd, olderr;
|
||||
int64_t rc, bufsiz, offset;
|
||||
olderr = errno;
|
||||
fd = luaL_checkinteger(L, 1);
|
||||
bufsiz = luaL_optinteger(L, 2, BUFSIZ);
|
||||
offset = luaL_optinteger(L, 3, -1);
|
||||
bufsiz = MIN(bufsiz, 0x7ffff000);
|
||||
buf = xmalloc(bufsiz);
|
||||
if (offset == -1) {
|
||||
rc = read(fd, buf, bufsiz);
|
||||
if ((buf = malloc(bufsiz))) {
|
||||
if (offset == -1) {
|
||||
rc = read(fd, buf, bufsiz);
|
||||
} else {
|
||||
rc = pread(fd, buf, bufsiz, offset);
|
||||
}
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
free(buf);
|
||||
return 1;
|
||||
} else {
|
||||
free(buf);
|
||||
return ReturnErrno(L, 1, olderr);
|
||||
}
|
||||
} else {
|
||||
rc = pread(fd, buf, bufsiz, offset);
|
||||
return ReturnErrno(L, 1, olderr);
|
||||
}
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
pushed = 1;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, errno);
|
||||
errno = olderr;
|
||||
pushed = 2;
|
||||
}
|
||||
free(buf);
|
||||
return pushed;
|
||||
}
|
||||
|
||||
// unix.write(fd:int, data:str[, offset:int]) → rc:int[, errno:int]
|
||||
|
@ -773,29 +773,31 @@ static int LuaUnixStat(lua_State *L) {
|
|||
int rc, fd, olderr;
|
||||
struct UnixStat **ust, *st;
|
||||
olderr = errno;
|
||||
st = xmalloc(sizeof(struct UnixStat));
|
||||
if (lua_isinteger(L, 1)) {
|
||||
fd = luaL_checkinteger(L, 1);
|
||||
rc = fstat(fd, &st->st);
|
||||
} else if (lua_isstring(L, 1)) {
|
||||
path = luaL_checkstring(L, 1);
|
||||
rc = stat(path, &st->st);
|
||||
if ((st = malloc(sizeof(struct UnixStat)))) {
|
||||
if (lua_isinteger(L, 1)) {
|
||||
fd = luaL_checkinteger(L, 1);
|
||||
rc = fstat(fd, &st->st);
|
||||
} else if (lua_isstring(L, 1)) {
|
||||
path = luaL_checkstring(L, 1);
|
||||
rc = stat(path, &st->st);
|
||||
} else {
|
||||
free(st);
|
||||
luaL_argerror(L, 1, "not integer or string");
|
||||
unreachable;
|
||||
}
|
||||
if (rc != -1) {
|
||||
st->refs = 1;
|
||||
ust = lua_newuserdatauv(L, sizeof(st), 1);
|
||||
luaL_setmetatable(L, "UnixStat*");
|
||||
*ust = st;
|
||||
return 1;
|
||||
} else {
|
||||
free(st);
|
||||
return ReturnErrno(L, 1, olderr);
|
||||
}
|
||||
} else {
|
||||
luaL_argerror(L, 1, "not integer or string");
|
||||
unreachable;
|
||||
return ReturnErrno(L, 1, olderr);
|
||||
}
|
||||
if (rc == -1) {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, errno);
|
||||
errno = olderr;
|
||||
free(st);
|
||||
return 2;
|
||||
}
|
||||
st->refs = 1;
|
||||
ust = lua_newuserdatauv(L, sizeof(st), 1);
|
||||
luaL_setmetatable(L, "UnixStat*");
|
||||
*ust = st;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// unix.opendir(path:str) → UnixDir*[, errno]
|
||||
|
@ -918,7 +920,6 @@ static int LuaUnixGetsockname(lua_State *L) {
|
|||
uint32_t addrsize;
|
||||
struct sockaddr_in sa;
|
||||
olderr = errno;
|
||||
bzero(&sa, sizeof(sa));
|
||||
addrsize = sizeof(sa);
|
||||
fd = luaL_checkinteger(L, 1);
|
||||
if (!getsockname(fd, &sa, &addrsize)) {
|
||||
|
@ -936,7 +937,6 @@ static int LuaUnixGetpeername(lua_State *L) {
|
|||
uint32_t addrsize;
|
||||
struct sockaddr_in sa;
|
||||
olderr = errno;
|
||||
bzero(&sa, sizeof(sa));
|
||||
addrsize = sizeof(sa);
|
||||
fd = luaL_checkinteger(L, 1);
|
||||
if (!getpeername(fd, &sa, &addrsize)) {
|
||||
|
@ -954,7 +954,6 @@ static int LuaUnixAccept(lua_State *L) {
|
|||
struct sockaddr_in sa;
|
||||
int clientfd, serverfd, olderr;
|
||||
olderr = errno;
|
||||
bzero(&sa, sizeof(sa));
|
||||
addrsize = sizeof(sa);
|
||||
serverfd = luaL_checkinteger(L, 1);
|
||||
clientfd = accept(serverfd, &sa, &addrsize);
|
||||
|
@ -976,32 +975,29 @@ static int LuaUnixRecvfrom(lua_State *L) {
|
|||
ssize_t rc;
|
||||
uint32_t addrsize;
|
||||
struct sockaddr_in sa;
|
||||
int fd, flags, bufsiz, olderr, pushed;
|
||||
int fd, flags, bufsiz, olderr;
|
||||
olderr = errno;
|
||||
bzero(&sa, sizeof(sa));
|
||||
addrsize = sizeof(sa);
|
||||
fd = luaL_checkinteger(L, 1);
|
||||
bufsiz = luaL_optinteger(L, 2, 1500);
|
||||
flags = luaL_optinteger(L, 3, 0);
|
||||
bufsiz = MIN(bufsiz, 0x7ffff000);
|
||||
buf = xmalloc(bufsiz);
|
||||
rc = recvfrom(fd, buf, bufsiz, flags, &sa, &addrsize);
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
lua_pushinteger(L, ntohl(sa.sin_addr.s_addr));
|
||||
lua_pushinteger(L, ntohs(sa.sin_port));
|
||||
pushed = 3;
|
||||
if ((buf = malloc(bufsiz))) {
|
||||
rc = recvfrom(fd, buf, bufsiz, flags, &sa, &addrsize);
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
lua_pushinteger(L, ntohl(sa.sin_addr.s_addr));
|
||||
lua_pushinteger(L, ntohs(sa.sin_port));
|
||||
free(buf);
|
||||
return 3;
|
||||
} else {
|
||||
free(buf);
|
||||
return ReturnErrno(L, 3, olderr);
|
||||
}
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, errno);
|
||||
errno = olderr;
|
||||
pushed = 4;
|
||||
return ReturnErrno(L, 3, olderr);
|
||||
}
|
||||
free(buf);
|
||||
return pushed;
|
||||
}
|
||||
|
||||
// unix.recv(fd[, bufsiz[, flags]]) → data[, errno]
|
||||
|
@ -1015,20 +1011,20 @@ static int LuaUnixRecv(lua_State *L) {
|
|||
bufsiz = luaL_optinteger(L, 2, 1500);
|
||||
flags = luaL_optinteger(L, 3, 0);
|
||||
bufsiz = MIN(bufsiz, 0x7ffff000);
|
||||
buf = xmalloc(bufsiz);
|
||||
rc = recv(fd, buf, bufsiz, flags);
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
pushed = 1;
|
||||
if ((buf = malloc(bufsiz))) {
|
||||
rc = recv(fd, buf, bufsiz, flags);
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
free(buf);
|
||||
return 1;
|
||||
} else {
|
||||
free(buf);
|
||||
return ReturnErrno(L, 1, olderr);
|
||||
}
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, errno);
|
||||
errno = olderr;
|
||||
pushed = 2;
|
||||
return ReturnErrno(L, 3, olderr);
|
||||
}
|
||||
free(buf);
|
||||
return pushed;
|
||||
}
|
||||
|
||||
// unix.send(fd, data[, flags]) → sent, errno
|
||||
|
|
|
@ -16,16 +16,18 @@ TOOL_NET_BINS = \
|
|||
|
||||
TOOL_NET_COMS = \
|
||||
o/$(MODE)/tool/net/dig.com \
|
||||
o/$(MODE)/tool/net/echoserver.com \
|
||||
o/$(MODE)/tool/net/redbean.com \
|
||||
o/$(MODE)/tool/net/redbean-demo.com \
|
||||
o/$(MODE)/tool/net/redbean-static.com \
|
||||
o/$(MODE)/tool/net/redbean-unsecure.com \
|
||||
o/$(MODE)/tool/net/redbean-original.com \
|
||||
o/$(MODE)/tool/net/redbean-assimilate.com \
|
||||
o/$(MODE)/tool/net/echoserver.com \
|
||||
o/$(MODE)/tool/net/wb.com
|
||||
|
||||
TOOL_NET_CHECKS = \
|
||||
o/$(MODE)/tool/net/net.pkg \
|
||||
$(TOOL_NET_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
TOOL_NET_DIRECTDEPS = \
|
||||
DSP_SCALE \
|
||||
LIBC_ALG \
|
||||
|
|
|
@ -2217,25 +2217,20 @@ static void *LoadAsset(struct Asset *a, size_t *out_size) {
|
|||
}
|
||||
}
|
||||
|
||||
static const char *GetPagerPath(char path[PATH_MAX]) {
|
||||
const char *s;
|
||||
if ((s = commandv("less", path))) return s;
|
||||
if ((s = commandv("more", path))) return s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static wontreturn void PrintUsage(int fd, int rc) {
|
||||
size_t n;
|
||||
int pip[2];
|
||||
const char *p;
|
||||
struct Asset *a;
|
||||
char buf[PATH_MAX];
|
||||
char *args[2] = {0};
|
||||
char pathbuf[PATH_MAX];
|
||||
if (!(a = GetAssetZip("/help.txt", 9)) || !(p = LoadAsset(a, &n))) {
|
||||
fprintf(stderr, "error: /help.txt is not a zip asset\n");
|
||||
exit(1);
|
||||
}
|
||||
if (isatty(0) && isatty(1) && (args[0] = GetPagerPath(pathbuf))) {
|
||||
if (strcmp(nulltoempty(getenv("TERM")), "dumb") && isatty(0) && isatty(1) &&
|
||||
((args[0] = commandv("less", buf)) ||
|
||||
(args[0] = commandv("more", buf)))) {
|
||||
sigaction(SIGPIPE, &(struct sigaction){.sa_handler = SIG_IGN}, 0);
|
||||
close(0);
|
||||
pipe(pip);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "libc/calls/struct/bpf.h"
|
||||
#include "libc/calls/struct/filter.h"
|
||||
#include "libc/calls/struct/seccomp.h"
|
||||
#include "libc/sysv/consts/audit.h"
|
||||
// clang-format off
|
||||
|
||||
#define _SECCOMP_MACHINE(MAGNUM) \
|
||||
|
@ -17,7 +18,15 @@
|
|||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, MAGNUM, 0, 1), \
|
||||
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
|
||||
|
||||
#define _SECCOMP_TRAP_SYSCALL(MAGNUM, DATA) \
|
||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, MAGNUM, 0, 1), \
|
||||
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP | ((DATA) & SECCOMP_RET_DATA))
|
||||
|
||||
#define _SECCOMP_TRACE_SYSCALL(MAGNUM, DATA) \
|
||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, MAGNUM, 0, 1), \
|
||||
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRACE | ((DATA) & SECCOMP_RET_DATA))
|
||||
|
||||
#define _SECCOMP_LOG_AND_RETURN_ERRNO(MAGNUM) \
|
||||
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (MAGNUM & SECCOMP_RET_DATA))
|
||||
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | ((MAGNUM) & SECCOMP_RET_DATA))
|
||||
|
||||
#endif /* COSMOPOLITAN_TOOL_NET_SANDBOX_H_ */
|
||||
|
|
Loading…
Add table
Reference in a new issue