aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/os/getwd.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/os/getwd.go')
-rw-r--r--libgo/go/os/getwd.go25
1 files changed, 23 insertions, 2 deletions
diff --git a/libgo/go/os/getwd.go b/libgo/go/os/getwd.go
index 81d8fed..0235c5d 100644
--- a/libgo/go/os/getwd.go
+++ b/libgo/go/os/getwd.go
@@ -5,9 +5,15 @@
package os
import (
+ "sync"
"syscall"
)
+var getwdCache struct {
+ sync.Mutex
+ dir string
+}
+
// Getwd returns a rooted path name corresponding to the
// current directory. If the current directory can be
// reached via multiple paths (due to symbolic links),
@@ -35,6 +41,17 @@ func Getwd() (pwd string, err error) {
}
}
+ // Apply same kludge but to cached dir instead of $PWD.
+ getwdCache.Lock()
+ pwd = getwdCache.dir
+ getwdCache.Unlock()
+ if len(pwd) > 0 {
+ d, err := Stat(pwd)
+ if err == nil && SameFile(dot, d) {
+ return pwd, nil
+ }
+ }
+
// Root is a special case because it has no parent
// and ends in a slash.
root, err := Stat("/")
@@ -73,8 +90,6 @@ func Getwd() (pwd string, err error) {
}
}
}
- fd.Close()
- return "", ErrNotExist
Found:
pd, err := fd.Stat()
@@ -88,5 +103,11 @@ func Getwd() (pwd string, err error) {
// Set up for next round.
dot = pd
}
+
+ // Save answer as hint to avoid the expensive path next time.
+ getwdCache.Lock()
+ getwdCache.dir = pwd
+ getwdCache.Unlock()
+
return pwd, nil
}