os: TempDir(): obey TMPDIR on unix, TMP on win, etc

Uses upstream go code, lightly adjusted.

Adds smoke test.
Этот коммит содержится в:
Dan Kegel 2021-11-21 17:28:40 -08:00 коммит произвёл Ron Evans
родитель e354a3523b
коммит 6b0f2cd697
5 изменённых файлов: 81 добавлений и 3 удалений

Просмотреть файл

@ -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()
}

25
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)
}
}

Просмотреть файл

@ -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"
}

Просмотреть файл

@ -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.

Просмотреть файл

@ -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.