diff --git a/src/os/file.go b/src/os/file.go index b52d8c54..45c14be6 100644 --- a/src/os/file.go +++ b/src/os/file.go @@ -1,3 +1,7 @@ +// Portions copyright 2009 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 os implements a subset of the Go "os" package. See // https://godoc.org/os for details. // @@ -260,7 +264,14 @@ func Readlink(name string) (string, error) { return name, nil } -// TempDir is a stub (for now), always returning the string "/tmp" +// TempDir returns the default directory to use for temporary files. +// +// On Unix systems, it returns $TMPDIR if non-empty, else /tmp. +// On Windows, it uses GetTempPath, returning the first non-empty +// value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory. +// +// The directory is neither guaranteed to exist nor have accessible +// permissions. func TempDir() string { - return "/tmp" + return tempDir() } diff --git a/src/os/file_anyos_test.go b/src/os/file_anyos_test.go new file mode 100644 index 00000000..3c2b2457 --- /dev/null +++ b/src/os/file_anyos_test.go @@ -0,0 +1,25 @@ +package os_test + +import ( + . "os" + "testing" +) + +// TestTempDir assumes that the test environment has a filesystem with a working temp dir. +func TestTempDir(t *testing.T) { + name := TempDir() + "/_os_test_TestTempDir" + Remove(name) + f, err := OpenFile(name, O_RDWR|O_CREATE, 0644) + if err != nil { + t.Errorf("OpenFile %s: %s", name, err) + return + } + err = f.Close() + if err != nil { + t.Errorf("Close %s: %s", name, err) + } + err = Remove(name) + if err != nil { + t.Errorf("Remove %s: %s", name, err) + } +} diff --git a/src/os/file_other.go b/src/os/file_other.go index e8657ec9..7e5646f5 100644 --- a/src/os/file_other.go +++ b/src/os/file_other.go @@ -56,3 +56,7 @@ func putchar(c byte) func Pipe() (r *File, w *File, err error) { return nil, nil, ErrNotImplemented } + +func tempDir() string { + return "/tmp" +} diff --git a/src/os/file_unix.go b/src/os/file_unix.go index b694c6b4..d52df132 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -1,5 +1,9 @@ // +build darwin linux,!baremetal +// Portions copyright 2009 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 os import ( @@ -26,6 +30,14 @@ func Pipe() (r *File, w *File, err error) { return } +func tempDir() string { + dir := Getenv("TMPDIR") + if dir == "" { + dir = "/tmp" + } + return dir +} + // ReadAt reads up to len(b) bytes from the File starting at the given absolute offset. // It returns the number of bytes read and any error encountered, possibly io.EOF. // At end of file, Pread returns 0, io.EOF. diff --git a/src/os/file_windows.go b/src/os/file_windows.go index e3593707..85d6fe9a 100644 --- a/src/os/file_windows.go +++ b/src/os/file_windows.go @@ -1,8 +1,16 @@ +//go:build windows // +build windows +// Portions copyright 2009 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 os -import "syscall" +import ( + "syscall" + "unicode/utf16" +) type syscallFd = syscall.Handle @@ -23,6 +31,24 @@ func Pipe() (r *File, w *File, err error) { return } +func tempDir() string { + n := uint32(syscall.MAX_PATH) + for { + b := make([]uint16, n) + n, _ = syscall.GetTempPath(uint32(len(b)), &b[0]) + if n > uint32(len(b)) { + continue + } + if n == 3 && b[1] == ':' && b[2] == '\\' { + // Do nothing for path, like C:\. + } else if n > 0 && b[n-1] == '\\' { + // Otherwise remove terminating \. + n-- + } + return string(utf16.Decode(b[:n])) + } +} + // ReadAt reads up to len(b) bytes from the File starting at the given absolute offset. // It returns the number of bytes read and any error encountered, possibly io.EOF. // At end of file, Pread returns 0, io.EOF.