...

Source file 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{"mkdir", path, syscall.ENOTDIR}
    26		}
    27	
    28		// Slow path: make sure parent exists and then call Mkdir for path.
    29		i := len(path)
    30		for i > 0 && IsPathSeparator(path[i-1]) { // Skip trailing path separator.
    31			i--
    32		}
    33	
    34		j := i
    35		for j > 0 && !IsPathSeparator(path[j-1]) { // Scan backward over element.
    36			j--
    37		}
    38	
    39		if j > 1 {
    40			// Create parent.
    41			err = MkdirAll(fixRootDirectory(path[:j-1]), perm)
    42			if err != nil {
    43				return err
    44			}
    45		}
    46	
    47		// Parent now exists; invoke Mkdir and use its result.
    48		err = Mkdir(path, perm)
    49		if err != nil {
    50			// Handle arguments like "foo/." by
    51			// double-checking that directory doesn't exist.
    52			dir, err1 := Lstat(path)
    53			if err1 == nil && dir.IsDir() {
    54				return nil
    55			}
    56			return err
    57		}
    58		return nil
    59	}
    60	
    61	// removeAllTestHook is a hook for testing.
    62	var removeAllTestHook = func(err error) error { return err }
    63	
    64	// RemoveAll removes path and any children it contains.
    65	// It removes everything it can but returns the first error
    66	// it encounters. If the path does not exist, RemoveAll
    67	// returns nil (no error).
    68	// If there is an error, it will be of type *PathError.
    69	func RemoveAll(path string) error {
    70		return removeAll(path)
    71	}
    72	
    73	// endsWithDot reports whether the final component of path is ".".
    74	func endsWithDot(path string) bool {
    75		if path == "." {
    76			return true
    77		}
    78		if len(path) >= 2 && path[len(path)-1] == '.' && IsPathSeparator(path[len(path)-2]) {
    79			return true
    80		}
    81		return false
    82	}
    83	

View as plain text