Daily bump.
[official-gcc.git] / libgo / go / os / path.go
blob84a3be3348f1d82e28790a4d005c857fce938ee0
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.
5 package os
7 import (
8 "io"
9 "syscall"
12 // MkdirAll creates a directory named path,
13 // along with any necessary parents, and returns nil,
14 // or else returns an error.
15 // The permission bits perm are used for all
16 // directories that MkdirAll creates.
17 // If path is already a directory, MkdirAll does nothing
18 // and returns nil.
19 func MkdirAll(path string, perm FileMode) error {
20 // Fast path: if we can tell whether path is a directory or file, stop with success or error.
21 dir, err := Stat(path)
22 if err == nil {
23 if dir.IsDir() {
24 return nil
26 return &PathError{"mkdir", path, syscall.ENOTDIR}
29 // Slow path: make sure parent exists and then call Mkdir for path.
30 i := len(path)
31 for i > 0 && IsPathSeparator(path[i-1]) { // Skip trailing path separator.
32 i--
35 j := i
36 for j > 0 && !IsPathSeparator(path[j-1]) { // Scan backward over element.
37 j--
40 if j > 1 {
41 // Create parent
42 err = MkdirAll(path[0:j-1], perm)
43 if err != nil {
44 return err
48 // Parent now exists; invoke Mkdir and use its result.
49 err = Mkdir(path, perm)
50 if err != nil {
51 // Handle arguments like "foo/." by
52 // double-checking that directory doesn't exist.
53 dir, err1 := Lstat(path)
54 if err1 == nil && dir.IsDir() {
55 return nil
57 return err
59 return nil
62 // RemoveAll removes path and any children it contains.
63 // It removes everything it can but returns the first error
64 // it encounters. If the path does not exist, RemoveAll
65 // returns nil (no error).
66 func RemoveAll(path string) error {
67 // Simple case: if Remove works, we're done.
68 err := Remove(path)
69 if err == nil || IsNotExist(err) {
70 return nil
73 // Otherwise, is this a directory we need to recurse into?
74 dir, serr := Lstat(path)
75 if serr != nil {
76 if serr, ok := serr.(*PathError); ok && (IsNotExist(serr.Err) || serr.Err == syscall.ENOTDIR) {
77 return nil
79 return serr
81 if !dir.IsDir() {
82 // Not a directory; return the error from Remove.
83 return err
86 // Directory.
87 fd, err := Open(path)
88 if err != nil {
89 if IsNotExist(err) {
90 // Race. It was deleted between the Lstat and Open.
91 // Return nil per RemoveAll's docs.
92 return nil
94 return err
97 // Remove contents & return first error.
98 err = nil
99 for {
100 names, err1 := fd.Readdirnames(100)
101 for _, name := range names {
102 err1 := RemoveAll(path + string(PathSeparator) + name)
103 if err == nil {
104 err = err1
107 if err1 == io.EOF {
108 break
110 // If Readdirnames returned an error, use it.
111 if err == nil {
112 err = err1
114 if len(names) == 0 {
115 break
119 // Close directory, because windows won't remove opened directory.
120 fd.Close()
122 // Remove directory.
123 err1 := Remove(path)
124 if err1 == nil || IsNotExist(err1) {
125 return nil
127 if err == nil {
128 err = err1
130 return err