]> Cypherpunks.ru repositories - gostls13.git/blob - src/os/path.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / 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 import (
8         "syscall"
9 )
10
11 // MkdirAll creates a directory named path,
12 // along with any necessary parents, and returns nil,
13 // or else returns an error.
14 // The permission bits perm (before umask) are used for all
15 // directories that MkdirAll creates.
16 // If path is already a directory, MkdirAll does nothing
17 // and returns nil.
18 func MkdirAll(path string, perm FileMode) error {
19         // Fast path: if we can tell whether path is a directory or file, stop with success or error.
20         dir, err := Stat(path)
21         if err == nil {
22                 if dir.IsDir() {
23                         return nil
24                 }
25                 return &PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR}
26         }
27
28         // Slow path: make sure parent exists and then call Mkdir for path.
29
30         // Extract the parent folder from path by first removing any trailing
31         // path separator and then scanning backward until finding a path
32         // separator or reaching the beginning of the string.
33         i := len(path) - 1
34         for i >= 0 && IsPathSeparator(path[i]) {
35                 i--
36         }
37         for i >= 0 && !IsPathSeparator(path[i]) {
38                 i--
39         }
40         if i < 0 {
41                 i = 0
42         }
43
44         // If there is a parent directory, and it is not the volume name,
45         // recurse to ensure parent directory exists.
46         if parent := path[:i]; len(parent) > len(volumeName(path)) {
47                 err = MkdirAll(parent, perm)
48                 if err != nil {
49                         return err
50                 }
51         }
52
53         // Parent now exists; invoke Mkdir and use its result.
54         err = Mkdir(path, perm)
55         if err != nil {
56                 // Handle arguments like "foo/." by
57                 // double-checking that directory doesn't exist.
58                 dir, err1 := Lstat(path)
59                 if err1 == nil && dir.IsDir() {
60                         return nil
61                 }
62                 return err
63         }
64         return nil
65 }
66
67 // RemoveAll removes path and any children it contains.
68 // It removes everything it can but returns the first error
69 // it encounters. If the path does not exist, RemoveAll
70 // returns nil (no error).
71 // If there is an error, it will be of type *PathError.
72 func RemoveAll(path string) error {
73         return removeAll(path)
74 }
75
76 // endsWithDot reports whether the final component of path is ".".
77 func endsWithDot(path string) bool {
78         if path == "." {
79                 return true
80         }
81         if len(path) >= 2 && path[len(path)-1] == '.' && IsPathSeparator(path[len(path)-2]) {
82                 return true
83         }
84         return false
85 }