Browse Source

Merge pull request #3733 from Feoramund/ci-freebsd

Add FreeBSD to the CI
gingerBill 1 year ago
parent
commit
39b166edd3

+ 29 - 0
.github/workflows/ci.yml

@@ -39,6 +39,35 @@ jobs:
           ./odin test tests/vendor -all-packages -define:ODIN_TEST_FANCY=false
           ./odin test tests/benchmark -all-packages -define:ODIN_TEST_FANCY=false
           (cd tests/issues; ./run.sh)
+  build_freebsd:
+    name: FreeBSD Build, Check, and Test
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v4
+    - name: Build, Check, and Test
+      timeout-minutes: 15
+      uses: vmactions/freebsd-vm@v1
+      with:
+        usesh: true
+        copyback: false
+        prepare: |
+          pkg install -y gmake git bash python3 libxml2 llvm17
+        run: |
+          # `set -e` is needed for test failures to register. https://github.com/vmactions/freebsd-vm/issues/72
+          set -e -x
+          git config --global --add safe.directory $(pwd)
+          gmake release
+          ./odin version
+          ./odin report
+          gmake -C vendor/stb/src
+          gmake -C vendor/cgltf/src
+          gmake -C vendor/miniaudio/src
+          ./odin check examples/all -vet -strict-style -target:freebsd_amd64
+          ./odin test tests/core/normal.odin -file -all-packages -define:ODIN_TEST_FANCY=false
+          ./odin test tests/core/speed.odin -file -all-packages -o:speed -define:ODIN_TEST_FANCY=false
+          ./odin test tests/vendor -all-packages -define:ODIN_TEST_FANCY=false
+          ./odin test tests/benchmark -all-packages -define:ODIN_TEST_FANCY=false
+          (cd tests/issues; ./run.sh)
   ci:
     strategy:
       fail-fast: false

+ 49 - 12
core/os/os_freebsd.odin

@@ -112,15 +112,15 @@ EOWNERDEAD:      Errno : 96
 O_RDONLY   :: 0x00000
 O_WRONLY   :: 0x00001
 O_RDWR     :: 0x00002
-O_CREATE   :: 0x00040
-O_EXCL     :: 0x00080
-O_NOCTTY   :: 0x00100
-O_TRUNC    :: 0x00200
-O_NONBLOCK :: 0x00800
-O_APPEND   :: 0x00400
-O_SYNC     :: 0x01000
-O_ASYNC    :: 0x02000
-O_CLOEXEC  :: 0x80000
+O_NONBLOCK :: 0x00004
+O_APPEND   :: 0x00008
+O_ASYNC    :: 0x00040
+O_SYNC     :: 0x00080
+O_CREATE   :: 0x00200
+O_TRUNC    :: 0x00400
+O_EXCL     :: 0x00800
+O_NOCTTY   :: 0x08000
+O_CLOEXEC  :: 0100000
 
 
 SEEK_DATA  :: 3
@@ -140,6 +140,8 @@ RTLD_NOLOAD       :: 0x02000
 
 MAX_PATH :: 1024
 
+KINFO_FILE_SIZE :: 1392
+
 args := _alloc_command_line_arguments()
 
 Unix_File_Time :: struct {
@@ -191,6 +193,21 @@ OS_Stat :: struct {
 	lspare: [10]u64,
 }
 
+KInfo_File :: struct {
+	structsize: c.int,
+	type:       c.int,
+	fd:         c.int,
+	ref_count:  c.int,
+	flags:      c.int,
+	pad0:       c.int,
+	offset:     i64,
+
+	// NOTE(Feoramund): This field represents a complicated union that I am
+	// avoiding implementing for now. I only need the path data below.
+	_union: [336]byte,
+
+	path: [MAX_PATH]c.char,
+}
 
 // since FreeBSD v12
 Dirent :: struct {
@@ -254,6 +271,8 @@ X_OK :: 1 // Test for execute permission
 W_OK :: 2 // Test for write permission
 R_OK :: 4 // Test for read permission
 
+F_KINFO :: 22
+
 foreign libc {
 	@(link_name="__error")		__errno_location :: proc() -> ^c.int ---
 
@@ -274,6 +293,7 @@ foreign libc {
 	@(link_name="unlink")           _unix_unlink        :: proc(path: cstring) -> c.int ---
 	@(link_name="rmdir")            _unix_rmdir         :: proc(path: cstring) -> c.int ---
 	@(link_name="mkdir")            _unix_mkdir         :: proc(path: cstring, mode: mode_t) -> c.int ---
+	@(link_name="fcntl")            _unix_fcntl         :: proc(fd: Handle, cmd: c.int, arg: uintptr) -> c.int ---
 	
 	@(link_name="fdopendir")        _unix_fdopendir     :: proc(fd: Handle) -> Dir ---
 	@(link_name="closedir")         _unix_closedir      :: proc(dirp: Dir) -> c.int ---
@@ -365,7 +385,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
 }
 
 file_size :: proc(fd: Handle) -> (i64, Errno) {
-	s, err := fstat(fd)
+	s, err := _fstat(fd)
 	if err != ERROR_NONE {
 		return -1, err
 	}
@@ -591,9 +611,26 @@ _readlink :: proc(path: string) -> (string, Errno) {
 	return "", Errno{}
 }
 
-// XXX FreeBSD
 absolute_path_from_handle :: proc(fd: Handle) -> (string, Errno) {
-	return "", Errno(ENOSYS)
+	// NOTE(Feoramund): The situation isn't ideal, but this was the best way I
+	// could find to implement this. There are a couple outstanding bug reports
+	// regarding the desire to retrieve an absolute path from a handle, but to
+	// my knowledge, there hasn't been any work done on it.
+	//
+	// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198570
+	//
+	// This may be unreliable, according to a comment from 2023.
+
+	kinfo: KInfo_File
+	kinfo.structsize = KINFO_FILE_SIZE
+
+	res := _unix_fcntl(fd, F_KINFO, cast(uintptr)&kinfo)
+	if res == -1 {
+		return "", Errno(get_last_error())
+	}
+
+	path := strings.clone_from_cstring_bounded(cast(cstring)&kinfo.path[0], len(kinfo.path))
+	return path, ERROR_NONE
 }
 
 absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {

+ 1 - 1
core/path/filepath/path_unix.odin

@@ -56,7 +56,7 @@ foreign libc {
 	@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
 
 }
-when ODIN_OS == .Darwin {
+when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
 	@(private)
 	foreign libc {
 		@(link_name="__error")          __error :: proc() -> ^i32 ---

+ 1 - 1
tests/core/net/test_core_net.odin

@@ -8,7 +8,7 @@
 
 	A test suite for `core:net`
 */
-//+build !netbsd
+//+build !netbsd !freebsd !openbsd
 package test_core_net
 
 import "core:testing"