mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Add NetBSD Support (#2661)
* Add NetBSD Support Includes: - Hints to find non-compatibility libc functions - Struct and constant definitions for sockets, polling, etc. - Changes to the linker code to work around some quirks in the NetBSD dynamic linker - A target triple for netbsd aarch64 so llvm builds/links the compiler properly on this platform * Updated releasenotes and some compacting --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
111
.github/workflows/main.yml
vendored
111
.github/workflows/main.yml
vendored
@@ -1059,6 +1059,117 @@ jobs:
|
||||
name: c3-openbsd-${{matrix.build_type}}
|
||||
path: c3-openbsd-${{matrix.build_type}}.tar.gz
|
||||
|
||||
build-netbsd:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
# Don't abort runners if a single one fails
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build_type: [Release, Debug]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: NetBSD VM
|
||||
uses: vmactions/netbsd-vm@v1
|
||||
with:
|
||||
prepare: |
|
||||
/usr/sbin/pkg_add cmake llvm-19.1.7 lld-19.1.7nb1 ninja
|
||||
|
||||
run: |
|
||||
echo "CMake"
|
||||
cmake -B build -S .
|
||||
cmake --build build
|
||||
echo "Compile and run some examples"
|
||||
cd resources
|
||||
../build/c3c compile examples/base64.c3
|
||||
../build/c3c compile examples/binarydigits.c3
|
||||
../build/c3c compile examples/brainfk.c3
|
||||
../build/c3c compile examples/factorial_macro.c3
|
||||
../build/c3c compile examples/fasta.c3
|
||||
../build/c3c compile examples/gameoflife.c3
|
||||
../build/c3c compile examples/hash.c3
|
||||
../build/c3c compile-only examples/levenshtein.c3
|
||||
../build/c3c compile examples/load_world.c3
|
||||
../build/c3c compile-only examples/map.c3
|
||||
../build/c3c compile examples/mandelbrot.c3
|
||||
../build/c3c compile examples/plus_minus.c3
|
||||
../build/c3c compile examples/nbodies.c3
|
||||
../build/c3c compile examples/spectralnorm.c3
|
||||
../build/c3c compile examples/swap.c3
|
||||
../build/c3c compile examples/contextfree/boolerr.c3
|
||||
../build/c3c compile examples/contextfree/dynscope.c3
|
||||
../build/c3c compile examples/contextfree/guess_number.c3
|
||||
../build/c3c compile examples/contextfree/multi.c3
|
||||
../build/c3c compile examples/contextfree/cleanup.c3
|
||||
../build/c3c compile-run examples/hello_world_many.c3
|
||||
../build/c3c compile-run examples/time.c3
|
||||
../build/c3c compile-run examples/fannkuch-redux.c3
|
||||
../build/c3c compile-run examples/contextfree/boolerr.c3
|
||||
../build/c3c compile-run examples/load_world.c3
|
||||
../build/c3c compile-run examples/process.c3
|
||||
../build/c3c compile-run examples/ls.c3
|
||||
../build/c3c compile-run examples/args.c3 -- foo -bar "baz baz"
|
||||
cd ..
|
||||
echo "Compile and run dynlib-test"
|
||||
cd resources/examples/dynlib-test
|
||||
../../../build/c3c -vv dynamic-lib add.c3
|
||||
mv add.so libadd.so
|
||||
cc test.c -L. -ladd -Wl,-rpath=.
|
||||
./a.out
|
||||
../../../build/c3c compile-run test.c3 -L . -l add -z -Wl,-rpath=.
|
||||
cd ../../../
|
||||
echo "Compile and run staticlib-test"
|
||||
cd resources/examples/staticlib-test
|
||||
../../../build/c3c -vv static-lib add.c3
|
||||
mv add.a libadd.a
|
||||
ranlib libadd.a
|
||||
cc test.c -L. -ladd
|
||||
./a.out
|
||||
../../../build/c3c compile-run test.c3 -L . -l add
|
||||
cd ../../../
|
||||
echo "Compile run unit tests"
|
||||
cd test
|
||||
../build/c3c compile-test unit -D SLOW_TESTS
|
||||
cd ..
|
||||
echo "Build testproject"
|
||||
cd resources/testproject
|
||||
../../build/c3c run -vvv --trust=full
|
||||
cd ../../
|
||||
echo "Test WASM"
|
||||
cd resources/testfragments
|
||||
../../build/c3c compile --target wasm32 -g0 --no-entry -Os wasm4.c3
|
||||
cd ../../
|
||||
echo "Build testproject direct linker"
|
||||
cd resources/testproject
|
||||
../../build/c3c run -vvv --linker=builtin --trust=full
|
||||
cd ../../
|
||||
echo "Init a library & a project"
|
||||
./build/c3c init-lib mylib
|
||||
ls mylib.c3l
|
||||
./build/c3c init myproject
|
||||
ls myproject
|
||||
echo "run compiler tests"
|
||||
cd test
|
||||
../build/c3c compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c test_suite/
|
||||
cd ..
|
||||
|
||||
- name: bundle_output
|
||||
run: |
|
||||
mkdir c3
|
||||
cp -r lib c3
|
||||
cp msvc_build_libraries.py c3
|
||||
cp build/c3c c3
|
||||
cp README.md c3
|
||||
cp releasenotes.md c3
|
||||
tar czf c3-netbsd-${{matrix.build_type}}.tar.gz c3
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: c3-netbsd-${{matrix.build_type}}
|
||||
path: c3-netbsd-${{matrix.build_type}}.tar.gz
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [build-msvc, build-linux, build-mac, build-linux-ubuntu22]
|
||||
|
||||
@@ -572,6 +572,7 @@ else()
|
||||
-Wno-unused-function
|
||||
-Wno-unused-variable
|
||||
-Wno-unused-parameter
|
||||
-Wno-char-subscripts
|
||||
)
|
||||
target_link_options(c3c PRIVATE -pthread)
|
||||
endif()
|
||||
|
||||
@@ -166,7 +166,7 @@ const bool MEMORY_SANITIZER = $$MEMORY_SANITIZER;
|
||||
const bool THREAD_SANITIZER = $$THREAD_SANITIZER;
|
||||
const bool ANY_SANITIZER = ADDRESS_SANITIZER || MEMORY_SANITIZER || THREAD_SANITIZER;
|
||||
const int LANGUAGE_DEV_VERSION = $$LANGUAGE_DEV_VERSION;
|
||||
const bool HAS_NATIVE_ERRNO = env::LINUX || env::ANDROID || env::OPENBSD || env::DARWIN || env::WIN32;
|
||||
const bool HAS_NATIVE_ERRNO = env::LINUX || env::ANDROID || env::OPENBSD || env::DARWIN || env::WIN32 || env::NETBSD;
|
||||
|
||||
macro bool os_is_darwin() @const
|
||||
{
|
||||
|
||||
@@ -80,7 +80,7 @@ const CInt SIGCHLD = BSD_FLAVOR_SIG ? 20 : 17;
|
||||
const bool BSD_FLAVOR_SIG @local = env::DARWIN || env::BSD_FAMILY;
|
||||
|
||||
alias Time_t = $typefrom(env::WIN32 ? long.typeid : CLong.typeid);
|
||||
alias Off_t = $typefrom(env::WIN32 ? int.typeid : usz.typeid);
|
||||
alias Off_t = $typefrom(env::WIN32 ? int.typeid : isz.typeid);
|
||||
|
||||
module libc @if(env::LIBC);
|
||||
|
||||
@@ -108,7 +108,7 @@ extern fn CInt ferror(CFile stream);
|
||||
extern fn CInt fflush(CFile stream);
|
||||
extern fn CInt fgetc(CFile stream);
|
||||
extern fn ZString fgets(char* string, CInt n, CFile stream);
|
||||
extern fn CInt fgetpos(CFile stream, Fpos_t* pos);
|
||||
extern fn CInt fgetpos(CFile stream, Fpos_t* pos) @if(!env::NETBSD);
|
||||
extern fn Fd fileno(CFile stream) @if(!env::WIN32);
|
||||
extern fn CFile fopen(ZString filename, ZString mode);
|
||||
extern fn CInt fprintf(CFile stream, ZString format, ...);
|
||||
@@ -119,7 +119,7 @@ extern fn void* free(void*);
|
||||
extern fn CFile freopen(ZString filename, ZString mode, CFile stream);
|
||||
extern fn CInt fscanf(CFile stream, ZString format, ...);
|
||||
extern fn CInt fseek(CFile stream, SeekIndex offset, CInt whence) @if(!env::WIN32);
|
||||
extern fn CInt fsetpos(CFile stream, Fpos_t* pos);
|
||||
extern fn CInt fsetpos(CFile stream, Fpos_t* pos) @if(!env::NETBSD);
|
||||
extern fn SeekIndex ftell(CFile stream) @if(!env::WIN32);
|
||||
extern fn usz fwrite(void* ptr, usz size, usz nmemb, CFile stream);
|
||||
extern fn CInt getc(CFile stream);
|
||||
@@ -127,13 +127,13 @@ extern fn CInt getchar();
|
||||
extern fn ZString getenv(ZString name);
|
||||
extern fn ZString gets(char* buffer);
|
||||
extern fn Tm* gmtime(Time_t* timer);
|
||||
extern fn Tm* gmtime_r(Time_t* timer, Tm* buf) @if(!env::WIN32);
|
||||
extern fn Tm* gmtime_r(Time_t* timer, Tm* buf) @if(!env::WIN32 && !env::NETBSD);
|
||||
extern fn CInt ioctl(CInt fd, ulong request, ...);
|
||||
extern fn CInt isatty(Fd fd) @if(!env::WIN32);
|
||||
extern fn CLong labs(CLong x);
|
||||
extern fn LongDivResult ldiv(CLong number, CLong denom);
|
||||
extern fn Tm* localtime(Time_t* timer);
|
||||
extern fn Tm* localtime_r(Time_t* timer, Tm* result) @if(!env::WIN32);
|
||||
extern fn Tm* localtime_r(Time_t* timer, Tm* result) @if(!env::WIN32 && !env::NETBSD);
|
||||
extern fn void longjmp(JmpBuf* buffer, CInt value) @if(!env::NETBSD && !env::OPENBSD);
|
||||
extern fn void* malloc(usz size);
|
||||
extern fn void* memchr(void* str, CInt c, usz n);
|
||||
@@ -192,17 +192,17 @@ extern fn CLong strtol(char* str, char** endptr, CInt base);
|
||||
extern fn CULong strtoul(char* str, char** endptr, CInt base);
|
||||
extern fn usz strxfrm(char* dest, ZString src, usz n);
|
||||
extern fn CInt system(ZString str);
|
||||
extern fn Time_t timegm(Tm* timeptr) @if(!env::WIN32);
|
||||
extern fn Time_t timegm(Tm* timeptr) @if(!env::WIN32 && !env::NETBSD);
|
||||
extern fn ZString tmpnam(ZString str);
|
||||
extern fn CFile tmpfile();
|
||||
extern fn CInt ungetc(CInt c, CFile stream);
|
||||
extern fn CInt unsetenv(ZString name);
|
||||
extern fn CInt unsetenv(ZString name) @if(!env::NETBSD);
|
||||
extern fn isz write(Fd fd, void* buffer, usz count) @if(!env::WIN32);
|
||||
|
||||
extern fn CFile fmemopen(void* ptr, usz size, ZString mode);
|
||||
extern fn isz getline(char** linep, usz* linecapp, CFile stream);
|
||||
extern fn CInt timespec_get(TimeSpec* ts, CInt base);
|
||||
extern fn CInt nanosleep(TimeSpec* req, TimeSpec* remaining);
|
||||
extern fn CInt nanosleep(TimeSpec* req, TimeSpec* remaining) @if(!env::NETBSD);
|
||||
extern fn ZString ctime(Time_t* timer);
|
||||
extern fn Time_t time(Time_t* timer);
|
||||
|
||||
@@ -229,6 +229,13 @@ extern fn int _longjmp(void*, int);
|
||||
macro usz longjmp(void* ptr, CInt i) => _longjmp(ptr, i);
|
||||
extern fn usz malloc_size(void* ptr);
|
||||
extern fn void* aligned_alloc(usz align, usz size);
|
||||
extern fn Tm* gmtime_r(Time_t* timer, Tm* buf) @cname("__gmtime_r50") @if(env::NETBSD);
|
||||
extern fn Tm* localtime_r(Time_t* timer, Tm* result) @cname("__localtime_r50") @if(env::NETBSD);
|
||||
extern fn CInt nanosleep(TimeSpec* req, TimeSpec* remaining) @cname("__nanosleep50") @if(env::NETBSD);
|
||||
extern fn CInt fgetpos(CFile stream, Fpos_t* pos) @cname("__fgetpos50") @if(env::NETBSD);
|
||||
extern fn CInt fsetpos(CFile stream, Fpos_t* pos) @cname("__fsetpos50") @if(env::NETBSD);
|
||||
extern fn Time_t timegm(Tm* timeptr) @cname("__timegm50") @if(env::NETBSD);
|
||||
extern fn CInt unsetenv(ZString name) @cname("__unsetenv13") @if(env::NETBSD);
|
||||
macro CFile stdin() { return fdopen(0, "r"); }
|
||||
macro CFile stdout() { return fdopen(1, "w"); }
|
||||
macro CFile stderr() { return fdopen(2, "w"); }
|
||||
@@ -469,8 +476,8 @@ const Errno EBADF = 9; // Bad file number
|
||||
const Errno ECHILD = 10; // No child processes
|
||||
|
||||
|
||||
const Errno EAGAIN @if(env::DARWIN) = 35; // Try again Macos
|
||||
const Errno EAGAIN @if(!env::DARWIN) = 11; // Try again
|
||||
const Errno EAGAIN @if(env::DARWIN || env::NETBSD) = 35; // Try again Macos
|
||||
const Errno EAGAIN @if(!env::DARWIN && !env::NETBSD) = 11; // Try again
|
||||
|
||||
const Errno ENOMEM = 12; // Out of memory
|
||||
const Errno EACCES = 13; // Permission denied
|
||||
@@ -566,6 +573,73 @@ const Errno EPROTO = 100; // Protocol error
|
||||
const Errno ETIME = 101; // STREAM ioctl() timeout
|
||||
const Errno EOPNOTSUPP = 102; // Operation not supported on socket
|
||||
|
||||
module libc::errno @if(env::NETBSD);
|
||||
const Errno EWOULDBLOCK = EAGAIN; // Operation would block
|
||||
const Errno EDEADLK = 11; // Resource deadlock avoided
|
||||
const Errno EINPROGRESS = 36; // Operation now in progress
|
||||
const Errno EALREADY = 37; // Operation already in progress
|
||||
const Errno ENOTSOCK = 38; // Socket operation on non-socket
|
||||
const Errno EDESTADDRREQ = 39; // Destination address required
|
||||
const Errno EMSGSIZE = 40; // Message too long
|
||||
const Errno EPROTOTYPE = 41; // Protocol wrong type for socket
|
||||
const Errno ENOPROTOOPT = 42; // Protocol option not available
|
||||
const Errno EPROTONOSUPPORT = 43; // Protocol not supported
|
||||
const Errno ESOCKTNOSUPPORT = 44; // Socket type not supported
|
||||
const Errno EOPNOTSUPP = 45; // Operation not supported
|
||||
const Errno EPFNOSUPPORT = 46; // Protocol family not supported
|
||||
const Errno EAFNOSUPPORT = 47; // Address family not supported by protocol family
|
||||
const Errno EADDRINUSE = 48; // Address already in use
|
||||
const Errno EADDRNOTAVAIL = 49; // Can't assign requested address
|
||||
const Errno ENETDOWN = 50; // Network is down
|
||||
const Errno ENETUNREACH = 51; // Network is unreachable
|
||||
const Errno ENETRESET = 52; // Network dropped connection on reset
|
||||
const Errno ECONNABORTED = 53; // Software caused connection abort
|
||||
const Errno ECONNRESET = 54; // Connection reset by peer
|
||||
const Errno ENOBUFS = 55; // No buffer space available
|
||||
const Errno EISCONN = 56; // Socket is already connected
|
||||
const Errno ENOTCONN = 57; // Socket is not connected
|
||||
const Errno ESHUTDOWN = 58; // Can't send after socket shutdown
|
||||
const Errno ETOOMANYREFS = 59; // Too many references: can't splice
|
||||
const Errno ETIMEDOUT = 60; // Operation timed out
|
||||
const Errno ECONNREFUSED = 61; // Connection refused
|
||||
const Errno ELOOP = 62; // Too many levels of symbolic links
|
||||
const Errno ENAMETOOLONG = 63; // File name too long
|
||||
const Errno EHOSTDOWN = 64; // Host is down
|
||||
const Errno EHOSTUNREACH = 65; // No route to host
|
||||
const Errno ENOTEMPTY = 66; // Directory not empty
|
||||
const Errno EPROCLIM = 67; // Too many processes
|
||||
const Errno EUSERS = 68; // Too many users
|
||||
const Errno EDQUOT = 69; // Disc quota exceeded
|
||||
const Errno ESTALE = 70; // Stale NFS file handle
|
||||
const Errno EREMOTE = 71; // Too many levels of remote in path
|
||||
const Errno EBADRPC = 72; // RPC struct is bad
|
||||
const Errno ERPCMISMATCH = 73; // RPC version wrong
|
||||
const Errno EPROGUNAVAIL = 74; // RPC prog. not avail
|
||||
const Errno EPROGMISMATCH = 75; // Program version wrong
|
||||
const Errno EPROCUNAVAIL = 76; // Bad procedure for program
|
||||
const Errno ENOLCK = 77; // No locks available
|
||||
const Errno ENOSYS = 78; // Function not implemented
|
||||
const Errno EFTYPE = 79; // Inappropriate file type or format
|
||||
const Errno EAUTH = 80; // Authentication error
|
||||
const Errno ENEEDAUTH = 81; // Need authenticator
|
||||
const Errno EIDRM = 82; // Identifier removed
|
||||
const Errno ENOMSG = 83; // No message of desired type
|
||||
const Errno EOVERFLOW = 84; // Value too large to be stored in data type
|
||||
const Errno EILSEQ = 85; // Illegal byte sequence
|
||||
const Errno ENOTSUP = 86; // Not supported
|
||||
const Errno ECANCELED = 87; // Operation canceled
|
||||
const Errno EBADMSG = 88; // Bad or Corrupt message
|
||||
const Errno ENODATA = 89; // No message available
|
||||
const Errno ENOSR = 90; // No STREAM resources
|
||||
const Errno ENOSTR = 91; // Not a STREAM
|
||||
const Errno ETIME = 92; // STREAM ioctl timeout
|
||||
const Errno ENOATTR = 93; // Attribute not found
|
||||
const Errno EMULTIHOP = 94; // Multihop attempted
|
||||
const Errno ENOLINK = 95; // Link has been severed
|
||||
const Errno EPROTO = 96; // Protocol error
|
||||
const Errno EOWNERDEAD = 97; // Previous owner died
|
||||
const Errno ENOTRECOVERABLE = 98; // State not recoverable
|
||||
|
||||
module libc::errno @if(env::WIN32);
|
||||
const Errno EDEADLK = 36; // Resource deadlock would occur Win32
|
||||
const Errno ENAMETOOLONG = 38; // File name too long Win32
|
||||
@@ -583,7 +657,7 @@ const Errno EINPROGRESS = 112; // Operation now in progress Win32
|
||||
const Errno EDQUOT = -122; // Quota exceeded, not in Win32
|
||||
const Errno EWOULDBLOCK = 140; // Operation would block
|
||||
|
||||
module libc::errno @if(!env::WIN32 && !env::DARWIN);
|
||||
module libc::errno @if(!env::WIN32 && !env::DARWIN && !env::NETBSD);
|
||||
const Errno EDEADLK = 35; // Resource deadlock would occur Linux (others?)
|
||||
const Errno ENAMETOOLONG = 36; // File name too long Linux (others?)
|
||||
const Errno ENOTEMPTY = 39; // Directory not empty
|
||||
|
||||
@@ -11,10 +11,10 @@ extern fn int* __errno() @if(env::ANDROID);
|
||||
macro int errno() @if(env::ANDROID) => *__errno();
|
||||
macro void errno_set(int err) @if(env::ANDROID) => *(__errno()) = err;
|
||||
|
||||
// OpenBSD
|
||||
extern fn int* __errno() @if(env::OPENBSD);
|
||||
macro int errno() @if(env::OPENBSD) => *__errno();
|
||||
macro void errno_set(int err) @if(env::OPENBSD) => *(__errno()) = err;
|
||||
// OpenBSD and NetBSD
|
||||
extern fn int* __errno() @if(env::OPENBSD || env::NETBSD);
|
||||
macro int errno() @if(env::OPENBSD || env::NETBSD) => *__errno();
|
||||
macro void errno_set(int err) @if(env::OPENBSD || env::NETBSD) => *(__errno()) = err;
|
||||
|
||||
// Darwin
|
||||
extern fn int* __error() @if(env::DARWIN);
|
||||
|
||||
38
lib/std/libc/os/netbsd.c3
Normal file
38
lib/std/libc/os/netbsd.c3
Normal file
@@ -0,0 +1,38 @@
|
||||
module libc @if(env::NETBSD);
|
||||
|
||||
alias Blksize_t = int;
|
||||
alias Nlink_t = uint;
|
||||
alias Dev_t = long;
|
||||
alias Ino_t = ulong;
|
||||
alias Mode_t = uint;
|
||||
alias Blkcnt_t = long;
|
||||
|
||||
struct Stat
|
||||
{
|
||||
Dev_t st_dev;
|
||||
Mode_t st_mode;
|
||||
Ino_t st_ino;
|
||||
Nlink_t st_nlink;
|
||||
Uid_t st_uid;
|
||||
Gid_t st_gid;
|
||||
Dev_t st_rdev;
|
||||
Time_t st_atime;
|
||||
long st_atimensec;
|
||||
Time_t st_mtime;
|
||||
long st_mtimensec;
|
||||
Time_t st_ctime;
|
||||
long st_ctimensec;
|
||||
Time_t st_birthtime;
|
||||
long st_birthtimensec;
|
||||
Off_t st_size;
|
||||
Blkcnt_t st_blocks;
|
||||
Blksize_t st_blksize;
|
||||
uint st_flags;
|
||||
uint st_gen;
|
||||
uint[2] st_spare;
|
||||
}
|
||||
|
||||
extern fn CInt stat(ZString path, Stat* stat) @cname("__stat50");
|
||||
|
||||
extern fn CInt sysctl(CInt *name, CUInt namelen, void *oldp, usz *oldlenp, void *newp, usz newlen);
|
||||
|
||||
@@ -60,7 +60,8 @@ struct Stack_t
|
||||
}
|
||||
|
||||
extern fn CInt sigaltstack(Stack_t* ss, Stack_t* old_ss);
|
||||
extern fn CInt sigaction(CInt signum, Sigaction *action, Sigaction *oldaction);
|
||||
extern fn CInt sigaction(CInt signum, Sigaction *action, Sigaction *oldaction) @if(!env::NETBSD);
|
||||
extern fn CInt sigaction(CInt signum, Sigaction *action, Sigaction *oldaction) @cname("__sigaction_siginfo") @if(env::NETBSD);
|
||||
|
||||
module libc::termios @if(env::LIBC &&& env::POSIX);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module std::net::os;
|
||||
const bool SUPPORTS_INET = env::LIBC && (env::WIN32 || env::DARWIN || env::LINUX || env::ANDROID || env::OPENBSD);
|
||||
const bool SUPPORTS_INET = env::LIBC && (env::WIN32 || env::DARWIN || env::LINUX || env::ANDROID || env::OPENBSD || env::NETBSD);
|
||||
|
||||
typedef AIFamily = CInt;
|
||||
typedef AIProtocol = CInt;
|
||||
@@ -18,7 +18,7 @@ struct AddrInfo
|
||||
AISockType ai_socktype;
|
||||
AIProtocol ai_protocol;
|
||||
Socklen_t ai_addrlen;
|
||||
struct @if(env::WIN32 || env::DARWIN || env::ANDROID)
|
||||
struct @if(env::WIN32 || env::DARWIN || env::ANDROID || env::NETBSD)
|
||||
{
|
||||
ZString ai_canonname;
|
||||
SockAddrPtr ai_addr;
|
||||
@@ -87,7 +87,7 @@ extern fn CInt setsockopt(NativeSocket socket, CInt level, CInt optname, void* o
|
||||
*>
|
||||
extern fn CInt getsockopt(NativeSocket socket, CInt level, CInt optname, void* optval, Socklen_t* optlen) @if(SUPPORTS_INET);
|
||||
|
||||
module std::net::os @if(!env::LIBC || !(env::WIN32 || env::DARWIN || env::LINUX || env::ANDROID || env::OPENBSD));
|
||||
module std::net::os @if(!env::LIBC || !(env::WIN32 || env::DARWIN || env::LINUX || env::ANDROID || env::OPENBSD || env::NETBSD));
|
||||
|
||||
const AIFamily PLATFORM_AF_INET6 = 0;
|
||||
const AIFamily PLATFORM_AF_IPX = 0;
|
||||
@@ -194,4 +194,4 @@ const IPPROTO_IPCOMP = 108;
|
||||
const IPPROTO_PGM = 113;
|
||||
const IPPROTO_SCTP = 132;
|
||||
const IPPROTO_DIVERT = 254;
|
||||
const IPPROTO_RAW = 255;
|
||||
const IPPROTO_RAW = 255;
|
||||
|
||||
108
lib/std/net/os/netbsd.c3
Normal file
108
lib/std/net/os/netbsd.c3
Normal file
@@ -0,0 +1,108 @@
|
||||
module std::net::os @if(env::NETBSD);
|
||||
import libc;
|
||||
|
||||
const AIFamily PLATFORM_AF_UNSPEC = 0; // unspecified
|
||||
const AIFamily PLATFORM_AF_LOCAL = 1; // local to host
|
||||
const AIFamily PLATFORM_AF_UNIX = PLATFORM_AF_LOCAL; // backward compatibility
|
||||
const AIFamily PLATFORM_AF_INET = 2; // internetwork: UDP, TCP, etc.
|
||||
const AIFamily PLATFORM_AF_IMPLINK = 3; // arpanet imp addresses
|
||||
const AIFamily PLATFORM_AF_PUP = 4; // pup protocols: e.g. BSP
|
||||
const AIFamily PLATFORM_AF_CHAOS = 5; // mit CHAOS protocols
|
||||
const AIFamily PLATFORM_AF_NS = 6; // XEROX NS protocols
|
||||
const AIFamily PLATFORM_AF_ISO = 7; // ISO protocols
|
||||
const AIFamily PLATFORM_AF_OSI = PLATFORM_AF_ISO;
|
||||
const AIFamily PLATFORM_AF_ECMA = 8; // european computer manufacturers
|
||||
const AIFamily PLATFORM_AF_DATAKIT = 9; // datakit protocols
|
||||
const AIFamily PLATFORM_AF_CCITT = 10; // CCITT protocols, X.25 etc
|
||||
const AIFamily PLATFORM_AF_SNA = 11; // IBM SNA
|
||||
const AIFamily PLATFORM_AF_DECNET = 12; // DECnet
|
||||
const AIFamily PLATFORM_AF_DLI = 13; // DEC Direct data link interface
|
||||
const AIFamily PLATFORM_AF_LAT = 14; // LAT
|
||||
const AIFamily PLATFORM_AF_HYLINK = 15; // NSC Hyperchannel
|
||||
const AIFamily PLATFORM_AF_APPLETALK = 16; // Apple Talk
|
||||
const AIFamily PLATFORM_AF_OROUTE = 17; // Internal Routing Protocol
|
||||
const AIFamily PLATFORM_AF_LINK = 18; // Link layer interface
|
||||
const AIFamily PLATFORM_PSEUDO_AF_XTP = 19; // eXpress Transfer Protocol (no AF)
|
||||
const AIFamily PLATFORM_AF_COIP = 20; // connection-oriented IP, aka ST II
|
||||
const AIFamily PLATFORM_AF_CNT = 21; // Computer Network Technology
|
||||
const AIFamily PLATFORM_PSEUDO_AF_RTIP = 22; // Help Identify RTIP packets
|
||||
const AIFamily PLATFORM_AF_IPX = 23; // Novell Internet Protocol
|
||||
const AIFamily PLATFORM_AF_INET6 = 24; // IP version 6
|
||||
const AIFamily PLATFORM_PSEUDO_AF_PIP = 25; // Help Identify PIP packets
|
||||
const AIFamily PLATFORM_AF_ISDN = 26; // Integrated Services Digital Networ
|
||||
const AIFamily PLATFORM_AF_E164 = PLATFORM_AF_ISDN; // CCITT E.164 recommendation
|
||||
const AIFamily PLATFORM_AF_NATM = 27; // native ATM access
|
||||
const AIFamily PLATFORM_AF_ARP = 28; // (rev.) addr. res. prot. (RFC 826)
|
||||
const AIFamily PLATFORM_PSEUDO_AF_KEY = 29; // Internal key management protocol
|
||||
const AIFamily PLATFORM_PSEUDO_AF_HDRCMPLT = 30; /* Used by BPF to not rewrite hdrs
|
||||
* in interface output routine */
|
||||
const AIFamily PLATFORM_AF_BLUETOOTH = 31; // Bluetooth: HCI, SCO, L2CAP, RFCOMM
|
||||
const AIFamily PLATFORM_AF_IEEE80211 = 32; // IEEE80211
|
||||
const AIFamily PLATFORM_AF_MPLS = 33; // MultiProtocol Label Switching
|
||||
const AIFamily PLATFORM_AF_ROUTE = 34; // Internal Routing Protocol
|
||||
const AIFamily PLATFORM_AF_CAN = 35;
|
||||
const AIFamily PLATFORM_AF_ETHER = 36;
|
||||
const AIFamily PLATFORM_AF_MAX = 37;
|
||||
|
||||
const int SOL_SOCKET = 0xFFFF;
|
||||
|
||||
const int SO_DEBUG = 0x0001; // turn on debugging info recording
|
||||
const int SO_ACCEPTCONN = 0x0002; // socket has had listen()
|
||||
const int SO_REUSEADDR = 0x0004; // allow local address reuse
|
||||
const int SO_KEEPALIVE = 0x0008; // keep connections alive
|
||||
const int SO_DONTROUTE = 0x0010; // just use interface addresses
|
||||
const int SO_BROADCAST = 0x0020; // permit sending of broadcast msgs
|
||||
const int SO_USELOOPBACK = 0x0040; // bypass hardware when possible
|
||||
const int SO_LINGER = 0x0080; // linger on close if data present
|
||||
const int SO_OOBINLINE = 0x0100; // leave received OOB data in line
|
||||
const int SO_REUSEPORT = 0x0200; // allow local address & port reuse
|
||||
const int SO_NOSIGPIPE = 0x0800; // no SIGPIPE from EPIPE
|
||||
const int SO_ACCEPTFILTER = 0x1000; // there is an accept filter
|
||||
const int SO_TIMESTAMP = 0x2000; // timestamp received dgram traffic
|
||||
const int SO_RERROR = 0x4000; // Keep track of receive errors
|
||||
|
||||
// additional
|
||||
const int SO_SNDBUF = 0x1001; // send buffer size
|
||||
const int SO_RCVBUF = 0x1002; // receive buffer size
|
||||
const int SO_SNDLOWAT = 0x1003; // send low-water mark
|
||||
const int SO_RCVLOWAT = 0x1004; // receive low-water mark
|
||||
const int SO_ERROR = 0x1007; // get error status and clear
|
||||
const int SO_TYPE = 0x1008; // get socket type
|
||||
const int SO_OVERFLOWED = 0x1009; // datagrams: return packets dropped
|
||||
|
||||
const int SO_NOHEADER = 0x100a; /* user supplies no header to kernel;
|
||||
* kernel removes header and supplies
|
||||
* payload
|
||||
*/
|
||||
const int SO_SNDTIMEO = 0x100b; // send timeout
|
||||
const int SO_RCVTIMEO = 0x100c; // receive timeout
|
||||
|
||||
// POLLIN through POLLNVAL are predefined by lib/std/net/os/posix.c3
|
||||
const CUShort POLLRDNORM = 0x0040;
|
||||
const CUShort POLLWRNORM = POLLOUT;
|
||||
const CUShort POLLRDBAND = 0x0080;
|
||||
const CUShort POLLWRBAND = 0x0100;
|
||||
|
||||
const CInt MSG_OOB = 0x0001; // process out-of-band data
|
||||
const CInt MSG_PEEK = 0x0002; // peek at incoming message
|
||||
const CInt MSG_DONTROUTE = 0x0004; // send without using routing tables
|
||||
const CInt MSG_EOR = 0x0008; // data completes record
|
||||
const CInt MSG_TRUNC = 0x0010; // data discarded before delivery
|
||||
const CInt MSG_CTRUNC = 0x0020; // control data lost before delivery
|
||||
const CInt MSG_WAITALL = 0x0040; // wait for full request or error
|
||||
const CInt MSG_DONTWAIT = 0x0080; // this message should be nonblocking
|
||||
const CInt MSG_BCAST = 0x0100; // this message was rcvd using link-level brdcst
|
||||
const CInt MSG_MCAST = 0x0200; // this message was rcvd using link-level mcast
|
||||
const CInt MSG_NOSIGNAL = 0x0400; // do not generate SIGPIPE on EOF
|
||||
const CInt MSG_CMSG_CLOEXEC = 0x0800; // close on exec receiving fd
|
||||
const CInt MSG_NBIO = 0x1000; // use non-blocking I/O
|
||||
const CInt MSG_WAITFORONE = 0x2000; // recvmmsg() wait for one message
|
||||
const CInt MSG_NOTIFICATION = 0x4000; // SCTP notification
|
||||
|
||||
// socket creation options
|
||||
const SOCK_CLOEXEC = 0x10000000; // set close on exec on socket
|
||||
const SOCK_NONBLOCK = 0x20000000; // set non blocking i/o socket
|
||||
const SOCK_NOSIGPIPE = 0x40000000; // don't send sigpipe
|
||||
const SOCK_FLAGS_MASK = 0xf0000000; // flags mask
|
||||
|
||||
const PLATFORM_O_NONBLOCK = SOCK_NONBLOCK;
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::os::posix @if(env::POSIX);
|
||||
import libc;
|
||||
|
||||
extern fn CInt clock_gettime(int type, TimeSpec *time);
|
||||
extern fn CInt clock_gettime(int type, TimeSpec *time) @cname(env::NETBSD ??? "__clock_gettime50" : "clock_gettime");
|
||||
|
||||
module std::os::posix @if(env::OPENBSD);
|
||||
const CLOCK_REALTIME = 0;
|
||||
|
||||
@@ -32,9 +32,9 @@ extern fn ZString getcwd(char* pwd, usz len);
|
||||
extern fn CInt pipe(CInt[2]* pipes);
|
||||
extern fn CFile fdopen(CInt fd, ZString mode);
|
||||
extern fn CInt access(ZString path, CInt mode);
|
||||
extern fn Posix_dirent* readdir(DIRPtr) @cname("readdir") @if(!USE_DARWIN_INODE64) ;
|
||||
extern fn DIRPtr opendir(ZString);
|
||||
extern fn void closedir(DIRPtr);
|
||||
extern fn Posix_dirent* readdir(DIRPtr) @cname(readdir_cname());
|
||||
extern fn DIRPtr opendir(ZString) @cname(env::NETBSD ??? "__opendir30" : "opendir");
|
||||
|
||||
const DT_UNKNOWN = 0;
|
||||
const DT_FIFO = 1;
|
||||
@@ -46,5 +46,12 @@ const DT_LNK = 10;
|
||||
const DT_SOCK = 12;
|
||||
const DT_WHT = 14;
|
||||
|
||||
const USE_DARWIN_INODE64 = env::DARWIN && env::X86_64;
|
||||
extern fn Posix_dirent* readdir(DIRPtr) @cname("readdir$INODE64") @if(USE_DARWIN_INODE64);
|
||||
|
||||
macro String readdir_cname() @local @const
|
||||
{
|
||||
$switch:
|
||||
$case env::DARWIN && env::X86_64: return "readdir$INODE64";
|
||||
$case env::NETBSD: return "__readdir30";
|
||||
$default: return "readdir";
|
||||
$endswitch
|
||||
}
|
||||
@@ -58,7 +58,7 @@ const CInt WUNTRACES = 2;
|
||||
JmpBuf backtrace_jmpbuf @local;
|
||||
alias BacktraceFn = fn CInt(void** buffer, CInt size);
|
||||
|
||||
extern fn CInt backtrace(void** buffer, CInt size) @if(env::OPENBSD);
|
||||
extern fn CInt backtrace(void** buffer, CInt size) @if(env::OPENBSD || env::NETBSD);
|
||||
|
||||
fn void install_signal_handler(CInt signal, SigActionFunction func)
|
||||
{
|
||||
@@ -69,7 +69,7 @@ fn void install_signal_handler(CInt signal, SigActionFunction func)
|
||||
libc::sigaction(signal, &action, &old);
|
||||
}
|
||||
|
||||
fn CInt backtrace(void** buffer, CInt size) @if(!env::OPENBSD)
|
||||
fn CInt backtrace(void** buffer, CInt size) @if(!env::OPENBSD && !env::NETBSD)
|
||||
{
|
||||
if (size < 1) return 0;
|
||||
void* handle = libc::dlopen("libc.so.6", libc::RTLD_LAZY|libc::RTLD_NODELETE);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
- Add `--custom-libc` option for custom libc implementations.
|
||||
- Remove use of LLVMGetGlobalContext for single module compilation.
|
||||
- Fixed bug where constants would get modified when slicing them. #2660
|
||||
- Support for NetBSD.
|
||||
|
||||
### Fixes
|
||||
- Regression with npot vector in struct triggering an assert #2219.
|
||||
|
||||
@@ -401,6 +401,7 @@ typedef enum
|
||||
MACOS_X64,
|
||||
MCU_X86,
|
||||
MINGW_X64,
|
||||
NETBSD_AARCH64,
|
||||
NETBSD_X86,
|
||||
NETBSD_X64,
|
||||
OPENBSD_X86,
|
||||
|
||||
@@ -1779,6 +1779,7 @@ const char *arch_os_target[ARCH_OS_TARGET_LAST + 1] = {
|
||||
[MACOS_X64] = "macos-x64",
|
||||
[MCU_X86] = "mcu-x86",
|
||||
[MINGW_X64] = "mingw-x64",
|
||||
[NETBSD_AARCH64] = "netbsd-aarch64",
|
||||
[NETBSD_X86] = "netbsd-x86",
|
||||
[NETBSD_X64] = "netbsd-x64",
|
||||
[OPENBSD_X86] = "openbsd-x86",
|
||||
|
||||
@@ -34,6 +34,8 @@ ArchOsTarget default_target = ELF_X64;
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#if defined(__MACH__)
|
||||
ArchOsTarget default_target = MACOS_AARCH64;
|
||||
#elif defined(__NetBSD__)
|
||||
ArchOsTarget default_target = NETBSD_AARCH64;
|
||||
#elif defined(__ANDROID__)
|
||||
ArchOsTarget default_target = ANDROID_AARCH64;
|
||||
#elif defined(__linux__) && __linux__
|
||||
@@ -286,6 +288,7 @@ static LinkLibc libc_from_arch_os(ArchOsTarget target)
|
||||
case MACOS_AARCH64:
|
||||
case MACOS_X64:
|
||||
case MINGW_X64:
|
||||
case NETBSD_AARCH64:
|
||||
case NETBSD_X86:
|
||||
case NETBSD_X64:
|
||||
case OPENBSD_X86:
|
||||
|
||||
@@ -186,6 +186,7 @@ const char* DEFAULT_TARGETS[] = {
|
||||
"linux-x64",
|
||||
"macos-aarch64",
|
||||
"macos-x64",
|
||||
"netbsd-aarch64",
|
||||
"netbsd-x64",
|
||||
"openbsd-x64",
|
||||
"wasm32",
|
||||
|
||||
@@ -1208,6 +1208,7 @@ static int jump_buffer_size()
|
||||
// Godbolt test
|
||||
return 25;
|
||||
case FREEBSD_X64:
|
||||
case NETBSD_AARCH64:
|
||||
case NETBSD_X64:
|
||||
case OPENBSD_X64:
|
||||
REMINDER("Guessing setjmp for platform.");
|
||||
|
||||
@@ -295,9 +295,9 @@ static void linker_setup_macos(const char ***args_ref, Linker linker_type)
|
||||
}
|
||||
|
||||
|
||||
static const char *find_freebsd_crt(void)
|
||||
static const char *find_bsd_crt(void)
|
||||
{
|
||||
if (file_exists("/usr/lib/crt1.o"))
|
||||
if (file_exists("/usr/lib/crt1.o") || file_exists("/usr/lib/crt0.o"))
|
||||
{
|
||||
return "/usr/lib/";
|
||||
}
|
||||
@@ -583,7 +583,7 @@ static void linker_setup_android(const char ***args_ref, Linker linker_type, boo
|
||||
add_plain_arg("-lc");
|
||||
}
|
||||
|
||||
static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, bool is_dylib)
|
||||
static void linker_setup_bsd(const char ***args_ref, Linker linker_type, bool is_dylib)
|
||||
{
|
||||
if (linker_type == LINKER_CC)
|
||||
{
|
||||
@@ -602,7 +602,7 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, boo
|
||||
|
||||
if (!link_libc()) return;
|
||||
|
||||
const char *crt_dir = find_freebsd_crt();
|
||||
const char *crt_dir = find_bsd_crt();
|
||||
if (!crt_dir)
|
||||
{
|
||||
error_exit("Failed to find the C runtime at link time.");
|
||||
@@ -613,22 +613,33 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, boo
|
||||
}
|
||||
if (is_pie_pic(compiler.platform.reloc_model))
|
||||
{
|
||||
add_plain_arg("-pie");
|
||||
if (!is_dylib) add_plain_arg("-pie");
|
||||
add_concat_file_arg(crt_dir, "crti.o");
|
||||
if (!is_dylib) add_concat_file_arg(crt_dir, "Scrt1.o");
|
||||
if (!is_dylib && compiler.platform.os != OS_TYPE_NETBSD)
|
||||
{
|
||||
add_concat_file_arg(crt_dir, "Scrt1.o");
|
||||
}
|
||||
add_concat_file_arg(crt_dir, "crtbeginS.o");
|
||||
add_concat_file_arg(crt_dir, "crtendS.o");
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *crt_o = compiler.platform.os == OS_TYPE_NETBSD ? "crt0.o" : "crt1.o";
|
||||
add_concat_file_arg(crt_dir, "crti.o");
|
||||
if (!is_dylib) add_concat_file_arg(crt_dir, "crt1.o");
|
||||
if (!is_dylib) add_concat_file_arg(crt_dir, crt_o);
|
||||
add_concat_file_arg(crt_dir, "crtbegin.o");
|
||||
add_concat_file_arg(crt_dir, "crtend.o");
|
||||
}
|
||||
add_concat_file_arg(crt_dir, "crtn.o");
|
||||
add_concat_quote_arg("-L", crt_dir);
|
||||
add_plain_arg("--dynamic-linker=/libexec/ld-elf.so.1");
|
||||
if (compiler.platform.os == OS_TYPE_NETBSD)
|
||||
{
|
||||
/* The following two flags are needed to work around ld-elf.so not being able
|
||||
* to handle more than two PT_LOAD segments. */
|
||||
add_plain_arg("--no-rosegment");
|
||||
add_plain_arg("-znorelro");
|
||||
}
|
||||
linking_add_link(&compiler.linking, "c");
|
||||
if (compiler.linking.link_math) linking_add_link(&compiler.linking, "m");
|
||||
linking_add_link(&compiler.linking, "gcc");
|
||||
@@ -735,7 +746,7 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns
|
||||
case OS_TYPE_FREEBSD:
|
||||
case OS_TYPE_OPENBSD:
|
||||
case OS_TYPE_NETBSD:
|
||||
linker_setup_freebsd(args_ref, linker_type, is_dylib);
|
||||
linker_setup_bsd(args_ref, linker_type, is_dylib);
|
||||
break;
|
||||
case OS_TYPE_LINUX:
|
||||
linker_setup_linux(args_ref, linker_type, is_dylib);
|
||||
|
||||
@@ -1197,6 +1197,7 @@ static char *arch_to_target_triple(ArchOsTarget target, LinuxLibc linux_libc)
|
||||
case MACOS_AARCH64: return "aarch64-apple-macosx";
|
||||
case ELF_AARCH64: return "aarch64-unknown-elf";
|
||||
case WINDOWS_AARCH64: return "aarch64-pc-windows-msvc";
|
||||
case NETBSD_AARCH64: return "aarch64-unknown-netbsd";
|
||||
case LINUX_RISCV32: return linux_libc == LINUX_LIBC_MUSL ? "riscv32-unknown-linux-musl" : "riscv32-unknown-linux";
|
||||
case ELF_RISCV32: return "riscv32-unknown-elf";
|
||||
case LINUX_RISCV64: return linux_libc == LINUX_LIBC_MUSL ? "riscv64-unknown-linux-musl" : "riscv64-unknown-linux";
|
||||
|
||||
@@ -255,8 +255,8 @@ fn void fdopen() @test @if(!env::WIN32)
|
||||
|
||||
fn void fflush() @test
|
||||
{
|
||||
CFile stdin = libc::stdin();
|
||||
assert(libc::fflush(stdin) == 0);
|
||||
CFile stdout = libc::stdout();
|
||||
assert(libc::fflush(stdout) == 0);
|
||||
}
|
||||
|
||||
fn void fgets_fget() @test
|
||||
|
||||
Reference in New Issue
Block a user