diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-01-21 16:59:29 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-02-24 15:12:08 +0000 |
commit | 07c658316b411a4b0e71a3a7e78b970b091795ab (patch) | |
tree | 96c1418603b82b888138ec4511b51091ad0866e1 | |
parent | 04edf418d285df410745118aae756f9e0a9a00f5 (diff) | |
download | go-07c658316b411a4b0e71a3a7e78b970b091795ab.tar.gz go-07c658316b411a4b0e71a3a7e78b970b091795ab.zip |
io/ioutil: forward TempFile and TempDir to os package
For #42026
Fixes #44311
Change-Id: I3dabcf902d155f95800b4adf1d7578906a194ce6
Reviewed-on: https://go-review.googlesource.com/c/go/+/285378
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
-rw-r--r-- | src/io/ioutil/export_test.go | 7 | ||||
-rw-r--r-- | src/io/ioutil/tempfile.go | 108 | ||||
-rw-r--r-- | src/io/ioutil/tempfile_test.go | 13 |
3 files changed, 13 insertions, 115 deletions
diff --git a/src/io/ioutil/export_test.go b/src/io/ioutil/export_test.go deleted file mode 100644 index dff55f07e2..0000000000 --- a/src/io/ioutil/export_test.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ioutil - -var ErrPatternHasSeparator = errPatternHasSeparator diff --git a/src/io/ioutil/tempfile.go b/src/io/ioutil/tempfile.go index af7c6fd7c1..4b272e5a5d 100644 --- a/src/io/ioutil/tempfile.go +++ b/src/io/ioutil/tempfile.go @@ -5,38 +5,9 @@ package ioutil import ( - "errors" "os" - "path/filepath" - "strconv" - "strings" - "sync" - "time" ) -// Random number state. -// We generate random temporary file names so that there's a good -// chance the file doesn't exist yet - keeps the number of tries in -// TempFile to a minimum. -var rand uint32 -var randmu sync.Mutex - -func reseed() uint32 { - return uint32(time.Now().UnixNano() + int64(os.Getpid())) -} - -func nextRandom() string { - randmu.Lock() - r := rand - if r == 0 { - r = reseed() - } - r = r*1664525 + 1013904223 // constants from Numerical Recipes - rand = r - randmu.Unlock() - return strconv.Itoa(int(1e9 + r%1e9))[1:] -} - // TempFile creates a new temporary file in the directory dir, // opens the file for reading and writing, and returns the resulting *os.File. // The filename is generated by taking pattern and adding a random @@ -48,48 +19,10 @@ func nextRandom() string { // will not choose the same file. The caller can use f.Name() // to find the pathname of the file. It is the caller's responsibility // to remove the file when no longer needed. +// +// As of Go 1.16, this function simply calls os.CreateTemp. func TempFile(dir, pattern string) (f *os.File, err error) { - if dir == "" { - dir = os.TempDir() - } - - prefix, suffix, err := prefixAndSuffix(pattern) - if err != nil { - return - } - - nconflict := 0 - for i := 0; i < 10000; i++ { - name := filepath.Join(dir, prefix+nextRandom()+suffix) - f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) - if os.IsExist(err) { - if nconflict++; nconflict > 10 { - randmu.Lock() - rand = reseed() - randmu.Unlock() - } - continue - } - break - } - return -} - -var errPatternHasSeparator = errors.New("pattern contains path separator") - -// prefixAndSuffix splits pattern by the last wildcard "*", if applicable, -// returning prefix as the part before "*" and suffix as the part after "*". -func prefixAndSuffix(pattern string) (prefix, suffix string, err error) { - if strings.ContainsRune(pattern, os.PathSeparator) { - err = errPatternHasSeparator - return - } - if pos := strings.LastIndex(pattern, "*"); pos != -1 { - prefix, suffix = pattern[:pos], pattern[pos+1:] - } else { - prefix = pattern - } - return + return os.CreateTemp(dir, pattern) } // TempDir creates a new temporary directory in the directory dir. @@ -101,37 +34,8 @@ func prefixAndSuffix(pattern string) (prefix, suffix string, err error) { // Multiple programs calling TempDir simultaneously // will not choose the same directory. It is the caller's responsibility // to remove the directory when no longer needed. +// +// As of Go 1.16, this function simply calls os.MkdirTemp. func TempDir(dir, pattern string) (name string, err error) { - if dir == "" { - dir = os.TempDir() - } - - prefix, suffix, err := prefixAndSuffix(pattern) - if err != nil { - return - } - - nconflict := 0 - for i := 0; i < 10000; i++ { - try := filepath.Join(dir, prefix+nextRandom()+suffix) - err = os.Mkdir(try, 0700) - if os.IsExist(err) { - if nconflict++; nconflict > 10 { - randmu.Lock() - rand = reseed() - randmu.Unlock() - } - continue - } - if os.IsNotExist(err) { - if _, err := os.Stat(dir); os.IsNotExist(err) { - return "", err - } - } - if err == nil { - name = try - } - break - } - return + return os.MkdirTemp(dir, pattern) } diff --git a/src/io/ioutil/tempfile_test.go b/src/io/ioutil/tempfile_test.go index 440c7cffc6..5cef18c33b 100644 --- a/src/io/ioutil/tempfile_test.go +++ b/src/io/ioutil/tempfile_test.go @@ -50,6 +50,9 @@ func TestTempFile_pattern(t *testing.T) { } } +// This string is from os.errPatternHasSeparator. +const patternHasSeparator = "pattern contains path separator" + func TestTempFile_BadPattern(t *testing.T) { tmpDir, err := TempDir("", t.Name()) if err != nil { @@ -81,9 +84,8 @@ func TestTempFile_BadPattern(t *testing.T) { if tt.wantErr { if err == nil { t.Errorf("Expected an error for pattern %q", tt.pattern) - } - if g, w := err, ErrPatternHasSeparator; g != w { - t.Errorf("Error mismatch: got %#v, want %#v for pattern %q", g, w, tt.pattern) + } else if !strings.Contains(err.Error(), patternHasSeparator) { + t.Errorf("Error mismatch: got %#v, want %q for pattern %q", err, patternHasSeparator, tt.pattern) } } else if err != nil { t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern) @@ -183,9 +185,8 @@ func TestTempDir_BadPattern(t *testing.T) { if tt.wantErr { if err == nil { t.Errorf("Expected an error for pattern %q", tt.pattern) - } - if g, w := err, ErrPatternHasSeparator; g != w { - t.Errorf("Error mismatch: got %#v, want %#v for pattern %q", g, w, tt.pattern) + } else if !strings.Contains(err.Error(), patternHasSeparator) { + t.Errorf("Error mismatch: got %#v, want %q for pattern %q", err, patternHasSeparator, tt.pattern) } } else if err != nil { t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern) |