1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
11 // Getwd returns a rooted path name corresponding to the
12 // current directory. If the current directory can be
13 // reached via multiple paths (due to symbolic links),
14 // Getwd may return any one of them.
15 func Getwd() (pwd string, err error) {
16 // If the operating system provides a Getwd call, use it.
17 if syscall.ImplementsGetwd {
18 s, e := syscall.Getwd()
19 return s, NewSyscallError("getwd", e)
22 // Otherwise, we're trying to find our way back to ".".
28 // Clumsy but widespread kludge:
29 // if $PWD is set and matches ".", use it.
31 if len(pwd) > 0 && pwd[0] == '/' {
33 if err == nil && SameFile(dot, d) {
38 // Root is a special case because it has no parent
39 // and ends in a slash.
40 root, err := Stat("/")
42 // Can't stat root - no hope.
45 if SameFile(root, dot) {
49 // General algorithm: find name in parent
50 // and then find name of parent. Each iteration
51 // adds /name to the beginning of pwd.
53 for parent := ".."; ; parent = "../" + parent {
54 if len(parent) >= 1024 { // Sanity check
55 return "", syscall.ENAMETOOLONG
57 fd, err := Open(parent)
63 names, err := fd.Readdirnames(100)
68 for _, name := range names {
69 d, _ := Lstat(parent + "/" + name)
71 pwd = "/" + name + pwd
77 return "", ErrNotExist
85 if SameFile(pd, root) {
88 // Set up for next round.