aboutsummaryrefslogtreecommitdiff
path: root/core/os/path_openbsd.odin
blob: 55b6b7d1f2f55f032f4d8ee55e8a7c53e64c4389 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package os

import "base:runtime"

import "core:strings"
import "core:sys/posix"

_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error) {
	// OpenBSD does not have an API for this, we do our best below.

	if len(runtime.args__) <= 0 {
		err = .Invalid_Path
		return
	}

	real :: proc(path: cstring, allocator: runtime.Allocator) -> (out: string, err: Error) {
		real := posix.realpath(path)
		if real == nil {
			err = _get_platform_error()
			return
		}
		defer posix.free(real)
		return clone_string(string(real), allocator)
	} 

	arg := runtime.args__[0]
	sarg := string(arg)

	if len(sarg) == 0 {
		err = .Invalid_Path
		return
	}

	if sarg[0] == '.' || sarg[0] == '/' {
		return real(arg, allocator)
	}

	temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })

	buf := strings.builder_make(temp_allocator)

	paths := get_env("PATH", temp_allocator)
	for dir in strings.split_iterator(&paths, ":") {
		strings.builder_reset(&buf)
		strings.write_string(&buf, dir)
		strings.write_string(&buf, "/")
		strings.write_string(&buf, sarg)

		cpath := strings.to_cstring(&buf) or_return
		if posix.access(cpath, {.X_OK}) == .OK {
			return real(cpath, allocator)
		}
	}

	err = .Invalid_Path
	return
}