os: implement and test os.MkdirTemp

This commit is contained in:
Dan Kegel
2021-12-12 13:56:52 -08:00
committed by Ron Evans
parent 0420842f4d
commit 971da0bc09
3 changed files with 156 additions and 7 deletions
+40
View File
@@ -95,6 +95,46 @@ func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
return prefix, suffix, nil
}
// MkdirTemp creates a new temporary directory in the directory dir
// and returns the pathname of the new directory.
// The new directory's name is generated by adding a random string to the end of pattern.
// If pattern includes a "*", the random string replaces the last "*" instead.
// If dir is the empty string, MkdirTemp uses the default directory for temporary files, as returned by TempDir.
// Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory.
// It is the caller's responsibility to remove the directory when it is no longer needed.
func MkdirTemp(dir, pattern string) (string, error) {
if dir == "" {
dir = TempDir()
}
prefix, suffix, err := prefixAndSuffix(pattern)
if err != nil {
return "", &PathError{Op: "mkdirtemp", Path: pattern, Err: err}
}
prefix = joinPath(dir, prefix)
try := 0
for {
name := prefix + nextRandom() + suffix
err := Mkdir(name, 0700)
if err == nil {
return name, nil
}
if IsExist(err) {
if try++; try < 10000 {
continue
}
return "", &PathError{Op: "mkdirtemp", Path: dir + string(PathSeparator) + prefix + "*" + suffix, Err: ErrExist}
}
if IsNotExist(err) {
if _, err := Stat(dir); IsNotExist(err) {
return "", err
}
}
return "", err
}
}
func joinPath(dir, name string) string {
if len(dir) > 0 && IsPathSeparator(dir[len(dir)-1]) {
return dir + name