Source file
src/syscall/pwd_plan9.go
1
2
3
4
5
6
7
8
9
10
11
12 package syscall
13
14 import (
15 "runtime"
16 "sync"
17 )
18
19 var (
20 wdmu sync.Mutex
21 wdSet bool
22 wdStr string
23 )
24
25
26
27
28
29
30
31 func Fixwd() {
32 wdmu.Lock()
33 defer wdmu.Unlock()
34 fixwdLocked()
35 }
36
37 func fixwdLocked() {
38 if !wdSet {
39 return
40 }
41
42 wd, _ := getwd()
43 if wd == wdStr {
44 return
45 }
46 if err := chdir(wdStr); err != nil {
47 return
48 }
49 }
50
51
52
53 func fixwd(paths ...string) bool {
54 for _, path := range paths {
55 if path != "" && path[0] != '/' && path[0] != '#' {
56 runtime.LockOSThread()
57 Fixwd()
58 return true
59 }
60 }
61 return false
62 }
63
64
65 func getwd() (wd string, err error) {
66 fd, err := open(".", O_RDONLY)
67 if err != nil {
68 return "", err
69 }
70 defer Close(fd)
71 return Fd2path(fd)
72 }
73
74 func Getwd() (wd string, err error) {
75 wdmu.Lock()
76 defer wdmu.Unlock()
77
78 if wdSet {
79 return wdStr, nil
80 }
81 wd, err = getwd()
82 if err != nil {
83 return
84 }
85 wdSet = true
86 wdStr = wd
87 return wd, nil
88 }
89
90 func Chdir(path string) error {
91
92 if fixwd(path) {
93 defer runtime.UnlockOSThread()
94 }
95 wdmu.Lock()
96 defer wdmu.Unlock()
97
98 runtime.LockOSThread()
99 defer runtime.UnlockOSThread()
100 if err := chdir(path); err != nil {
101 return err
102 }
103
104 wd, err := getwd()
105 if err != nil {
106 return err
107 }
108 wdSet = true
109 wdStr = wd
110 return nil
111 }
112
View as plain text