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