OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.git] / libgo / go / os / path.go
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.
4
5 package os
6
7
8 // MkdirAll creates a directory named path,
9 // along with any necessary parents, and returns nil,
10 // or else returns an error.
11 // The permission bits perm are used for all
12 // directories that MkdirAll creates.
13 // If path is already a directory, MkdirAll does nothing
14 // and returns nil.
15 func MkdirAll(path string, perm uint32) Error {
16         // If path exists, stop with success or error.
17         dir, err := Lstat(path)
18         if err == nil {
19                 if dir.IsDirectory() {
20                         return nil
21                 }
22                 return &PathError{"mkdir", path, ENOTDIR}
23         }
24
25         // Doesn't already exist; make sure parent does.
26         i := len(path)
27         for i > 0 && path[i-1] == '/' { // Skip trailing slashes.
28                 i--
29         }
30
31         j := i
32         for j > 0 && path[j-1] != '/' { // Scan backward over element.
33                 j--
34         }
35
36         if j > 0 {
37                 // Create parent
38                 err = MkdirAll(path[0:j-1], perm)
39                 if err != nil {
40                         return err
41                 }
42         }
43
44         // Now parent exists, try to create.
45         err = Mkdir(path, perm)
46         if err != nil {
47                 // Handle arguments like "foo/." by
48                 // double-checking that directory doesn't exist.
49                 dir, err1 := Lstat(path)
50                 if err1 == nil && dir.IsDirectory() {
51                         return nil
52                 }
53                 return err
54         }
55         return nil
56 }
57
58 // RemoveAll removes path and any children it contains.
59 // It removes everything it can but returns the first error
60 // it encounters.  If the path does not exist, RemoveAll
61 // returns nil (no error).
62 func RemoveAll(path string) Error {
63         // Simple case: if Remove works, we're done.
64         err := Remove(path)
65         if err == nil {
66                 return nil
67         }
68
69         // Otherwise, is this a directory we need to recurse into?
70         dir, serr := Lstat(path)
71         if serr != nil {
72                 if serr, ok := serr.(*PathError); ok && serr.Error == ENOENT {
73                         return nil
74                 }
75                 return serr
76         }
77         if !dir.IsDirectory() {
78                 // Not a directory; return the error from Remove.
79                 return err
80         }
81
82         // Directory.
83         fd, err := Open(path, O_RDONLY, 0)
84         if err != nil {
85                 return err
86         }
87
88         // Remove contents & return first error.
89         err = nil
90         for {
91                 names, err1 := fd.Readdirnames(100)
92                 for _, name := range names {
93                         err1 := RemoveAll(path + "/" + name)
94                         if err == nil {
95                                 err = err1
96                         }
97                 }
98                 // If Readdirnames returned an error, use it.
99                 if err == nil {
100                         err = err1
101                 }
102                 if len(names) == 0 {
103                         break
104                 }
105         }
106
107         // Close directory, because windows won't remove opened directory.
108         fd.Close()
109
110         // Remove directory.
111         err1 := Remove(path)
112         if err == nil {
113                 err = err1
114         }
115         return err
116 }