runtime,os: add os.Executable() for Darwin

This commit is contained in:
Damian Gryski
2025-04-30 10:31:15 -07:00
committed by Ron Evans
parent 72b19555dc
commit 5428bfd270
3 changed files with 46 additions and 1 deletions
+10
View File
@@ -0,0 +1,10 @@
//go:build darwin
package os
// via runtime because we need argc/argv ptrs
func runtime_executable_path() string
func Executable() (string, error) {
return runtime_executable_path(), nil
}
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build !linux || baremetal
//go:build (!linux && !darwin) || baremetal
package os
+35
View File
@@ -229,3 +229,38 @@ func call_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) int32
//export tinygo_syscall6X
func call_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) uintptr
//go:linkname os_runtime_executable_path os.runtime_executable_path
func os_runtime_executable_path() string {
argv := (*unsafe.Pointer)(unsafe.Pointer(main_argv))
// skip over argv
argv = (*unsafe.Pointer)(unsafe.Add(unsafe.Pointer(argv), (uintptr(main_argc)+1)*unsafe.Sizeof(argv)))
// skip over envv
for (*argv) != nil {
argv = (*unsafe.Pointer)(unsafe.Add(unsafe.Pointer(argv), unsafe.Sizeof(argv)))
}
// next string is exe path
argv = (*unsafe.Pointer)(unsafe.Add(unsafe.Pointer(argv), unsafe.Sizeof(argv)))
cstr := unsafe.Pointer(*argv)
length := strlen(cstr)
argString := _string{
length: length,
ptr: (*byte)(cstr),
}
executablePath := *(*string)(unsafe.Pointer(&argString))
// strip "executable_path=" prefix if available, it's added after OS X 10.11.
executablePath = stringsTrimPrefix(executablePath, "executable_path=")
return executablePath
}
func stringsTrimPrefix(s, prefix string) string {
if len(s) >= len(prefix) && s[:len(prefix)] == prefix {
return s[len(prefix):]
}
return s
}