-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcshared.go
More file actions
119 lines (104 loc) · 3.15 KB
/
Copy pathcshared.go
File metadata and controls
119 lines (104 loc) · 3.15 KB
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//go:build darwin && cshared
package main
/*
#include <stdint.h>
#include <stdlib.h>
*/
import "C"
import (
"errors"
"fmt"
"os"
"os/signal"
"syscall"
"unsafe"
"github.com/tmc/apple/objc"
"github.com/tmc/apple/x/fskitbridge"
)
func init() {
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGQUIT)
go func() {
for sig := range ch {
extensionLog("caught signal " + sig.String())
}
}()
}
// ninepExtension hosts the bridge server inside the FSKit extension. It owns
// the c-archive lifecycle (lazy retryable init, last-error, reply fallback,
// panic recovery); the exported entry points below are one-line wrappers,
// since a c-archive cannot re-export Go functions from an imported package.
var ninepExtension = fskitbridge.NewExtension(ninepShims, newNinepServer)
// newNinepServer builds the bridge server against the Swift-provided
// NinePFileSystem class. It is retried on every Init until the class is
// registered, so a call that races extension startup does not poison the
// process.
func newNinepServer() (*fskitbridge.Server, error) {
cls := objc.GetClass("NinePFileSystem")
if cls == 0 {
return nil, errors.New("swift shim did not register NinePFileSystem")
}
var srv *fskitbridge.Server
var err error
objc.AutoreleasePool(func() {
srv, err = ensureServer(cls, &ninepFileSystem{config: defaultFSConfigFromEnv()})
})
if err != nil {
extensionLog("register bridge: " + err.Error())
}
return srv, err
}
//export NinePFSInit
func NinePFSInit() C.int {
if ninepExtension.Init() != nil {
return -1
}
return 0
}
//export NinePFSNewFileSystem
func NinePFSNewFileSystem() unsafe.Pointer {
// An objc.ID is an object pointer; reinterpret rather than convert
// through uintptr, which vet rejects.
fs := ninepExtension.NewFileSystem()
return *(*unsafe.Pointer)(unsafe.Pointer(&fs))
}
//export NinePFSConfigureFileSystem
func NinePFSConfigureFileSystem(raw unsafe.Pointer) C.int {
extensionLog("configure file system begin")
if ninepExtension.Init() != nil {
extensionLog("configure file system: init failed")
return -1
}
if raw == nil {
extensionLog("configure file system: nil object")
return -1
}
extensionLog("configure file system ok")
return 0
}
//export NinePFSProbeResource
func NinePFSProbeResource(self, resource, reply unsafe.Pointer) {
ninepExtension.ProbeResource(objc.ID(uintptr(self)), objc.ID(uintptr(resource)), objc.ID(uintptr(reply)))
}
//export NinePFSLoadResource
func NinePFSLoadResource(self, resource, options, reply unsafe.Pointer) {
ninepExtension.LoadResource(objc.ID(uintptr(self)), objc.ID(uintptr(resource)), objc.ID(uintptr(options)), objc.ID(uintptr(reply)))
}
//export NinePFSUnloadResource
func NinePFSUnloadResource(self, resource, options, reply unsafe.Pointer) {
ninepExtension.UnloadResource(objc.ID(uintptr(self)), objc.ID(uintptr(resource)), objc.ID(uintptr(options)), objc.ID(uintptr(reply)))
}
//export NinePFSLastError
func NinePFSLastError() *C.char {
err := ninepExtension.LastError()
if err == nil {
return nil
}
return C.CString(err.Error())
}
func extensionLog(msg string) {
nativeExtensionLog(msg)
if os.Getenv("NINEPFS_DEBUG") != "" {
fmt.Fprintln(os.Stderr, "9pfs: "+msg)
}
}