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.
7 // MkdirAll creates a directory named path,
8 // along with any necessary parents, and returns nil,
9 // or else returns an error.
10 // The permission bits perm are used for all
11 // directories that MkdirAll creates.
12 // If path is already a directory, MkdirAll does nothing
14 func MkdirAll(path string, perm uint32) Error {
15 // If path exists, stop with success or error.
16 dir, err := Stat(path)
18 if dir.IsDirectory() {
21 return &PathError{"mkdir", path, ENOTDIR}
24 // Doesn't already exist; make sure parent does.
26 for i > 0 && IsPathSeparator(path[i-1]) { // Skip trailing path separator.
31 for j > 0 && !IsPathSeparator(path[j-1]) { // Scan backward over element.
37 err = MkdirAll(path[0:j-1], perm)
43 // Now parent exists, try to create.
44 err = Mkdir(path, perm)
46 // Handle arguments like "foo/." by
47 // double-checking that directory doesn't exist.
48 dir, err1 := Lstat(path)
49 if err1 == nil && dir.IsDirectory() {
57 // RemoveAll removes path and any children it contains.
58 // It removes everything it can but returns the first error
59 // it encounters. If the path does not exist, RemoveAll
60 // returns nil (no error).
61 func RemoveAll(path string) Error {
62 // Simple case: if Remove works, we're done.
68 // Otherwise, is this a directory we need to recurse into?
69 dir, serr := Lstat(path)
71 if serr, ok := serr.(*PathError); ok && (serr.Error == ENOENT || serr.Error == ENOTDIR) {
76 if !dir.IsDirectory() {
77 // Not a directory; return the error from Remove.
87 // Remove contents & return first error.
90 names, err1 := fd.Readdirnames(100)
91 for _, name := range names {
92 err1 := RemoveAll(path + string(PathSeparator) + name)
100 // If Readdirnames returned an error, use it.
109 // Close directory, because windows won't remove opened directory.