Commit 0e257755 authored by Peter Mundy's avatar Peter Mundy Committed by Russ Cox

io/ioutil.TempFile for Windows

Fixes #834.

R=rsc, brainman
CC=golang-dev
https://golang.org/cl/1686047
parent 7c1be45f
...@@ -33,18 +33,15 @@ func nextSuffix() string { ...@@ -33,18 +33,15 @@ func nextSuffix() string {
// TempFile creates a new temporary file in the directory dir // TempFile creates a new temporary file in the directory dir
// with a name beginning with prefix, opens the file for reading // with a name beginning with prefix, opens the file for reading
// and writing, and returns the resulting *os.File. // and writing, and returns the resulting *os.File.
// If dir is the empty string, TempFile uses the value of the // If dir is the empty string, TempFile uses the default directory
// environment variable $TMPDIR or, if that is empty,/tmp. // for temporary files (see os.TempDir).
// Multiple programs calling TempFile simultaneously // Multiple programs calling TempFile simultaneously
// will not choose the same file. The caller can use f.Name() // will not choose the same file. The caller can use f.Name()
// to find the name of the file. It is the caller's responsibility to // to find the name of the file. It is the caller's responsibility to
// remove the file when no longer needed. // remove the file when no longer needed.
func TempFile(dir, prefix string) (f *os.File, err os.Error) { func TempFile(dir, prefix string) (f *os.File, err os.Error) {
if dir == "" { if dir == "" {
dir = os.Getenv("TMPDIR") dir = os.TempDir()
if dir == "" {
dir = "/tmp"
}
} }
nconflict := 0 nconflict := 0
......
...@@ -7,6 +7,7 @@ package ioutil_test ...@@ -7,6 +7,7 @@ package ioutil_test
import ( import (
. "io/ioutil" . "io/ioutil"
"os" "os"
"regexp"
"testing" "testing"
) )
...@@ -16,14 +17,17 @@ func TestTempFile(t *testing.T) { ...@@ -16,14 +17,17 @@ func TestTempFile(t *testing.T) {
t.Errorf("TempFile(`/_not_exists_`, `foo`) = %v, %v", f, err) t.Errorf("TempFile(`/_not_exists_`, `foo`) = %v, %v", f, err)
} }
f, err = TempFile("/tmp", "ioutil_test") dir := os.TempDir()
f, err = TempFile(dir, "ioutil_test")
if f == nil || err != nil { if f == nil || err != nil {
t.Errorf("TempFile(`/tmp`, `ioutil_test`) = %v, %v", f, err) t.Errorf("TempFile(dir, `ioutil_test`) = %v, %v", f, err)
} }
re := testing.MustCompile("^/tmp/ioutil_test[0-9]+$") if f != nil {
if !re.MatchString(f.Name()) { re := testing.MustCompile("^" + regexp.QuoteMeta(dir) + "/ioutil_test[0-9]+$")
t.Fatalf("TempFile(`/tmp`, `ioutil_test`) created bad name %s", f.Name()) if !re.MatchString(f.Name()) {
t.Errorf("TempFile(`"+dir+"`, `ioutil_test`) created bad name %s", f.Name())
}
os.Remove(f.Name())
} }
os.Remove(f.Name())
f.Close() f.Close()
} }
...@@ -19,22 +19,27 @@ GOFILES=\ ...@@ -19,22 +19,27 @@ GOFILES=\
types.go\ types.go\
GOFILES_freebsd=\ GOFILES_freebsd=\
env_unix.go\
file_unix.go\ file_unix.go\
sys_bsd.go\ sys_bsd.go\
GOFILES_darwin=\ GOFILES_darwin=\
env_unix.go\
file_unix.go\ file_unix.go\
sys_bsd.go\ sys_bsd.go\
GOFILES_linux=\ GOFILES_linux=\
env_unix.go\
file_unix.go\ file_unix.go\
sys_linux.go\ sys_linux.go\
GOFILES_nacl=\ GOFILES_nacl=\
env_unix.go\
file_unix.go\ file_unix.go\
sys_nacl.go\ sys_nacl.go\
GOFILES_windows=\ GOFILES_windows=\
env_windows.go\
file_windows.go\ file_windows.go\
sys_windows.go\ sys_windows.go\
......
// Copyright 2010 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.
// Unix environment variables.
package os
// TempDir returns the default directory to use for temporary files.
// On Unix-like systems, it uses the environment variable $TMPDIR
// or, if that is empty, /tmp.
// On Windows systems, it uses the Windows GetTempPath API.
func TempDir() string {
dir := Getenv("TMPDIR")
if dir == "" {
dir = "/tmp"
}
return dir
}
// Copyright 2010 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.
// Windows environment variables.
package os
import (
"syscall"
"utf16"
)
func TempDir() string {
const pathSep = '\\'
dirw := make([]uint16, syscall.MAX_PATH)
n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
if n > uint32(len(dirw)) {
dirw = make([]uint16, n)
n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
if n > uint32(len(dirw)) {
n = 0
}
}
if n > 0 && dirw[n-1] == pathSep {
n--
}
return string(utf16.Decode(dirw[0:n]))
}
...@@ -131,6 +131,7 @@ func getSysProcAddr(m uint32, pname string) uintptr { ...@@ -131,6 +131,7 @@ func getSysProcAddr(m uint32, pname string) uintptr {
//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, errno int) [failretval=0xffffffff] //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, errno int) [failretval=0xffffffff]
//sys CreateIoCompletionPort(filehandle int32, cphandle int32, key uint32, threadcnt uint32) (handle int32, errno int) //sys CreateIoCompletionPort(filehandle int32, cphandle int32, key uint32, threadcnt uint32) (handle int32, errno int)
//sys GetQueuedCompletionStatus(cphandle int32, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (ok bool, errno int) //sys GetQueuedCompletionStatus(cphandle int32, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (ok bool, errno int)
//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, errno int) = GetTempPathW
// syscall interface implementation for other packages // syscall interface implementation for other packages
......
...@@ -40,6 +40,7 @@ var ( ...@@ -40,6 +40,7 @@ var (
procGetTimeZoneInformation = getSysProcAddr(modkernel32, "GetTimeZoneInformation") procGetTimeZoneInformation = getSysProcAddr(modkernel32, "GetTimeZoneInformation")
procCreateIoCompletionPort = getSysProcAddr(modkernel32, "CreateIoCompletionPort") procCreateIoCompletionPort = getSysProcAddr(modkernel32, "CreateIoCompletionPort")
procGetQueuedCompletionStatus = getSysProcAddr(modkernel32, "GetQueuedCompletionStatus") procGetQueuedCompletionStatus = getSysProcAddr(modkernel32, "GetQueuedCompletionStatus")
procGetTempPathW = getSysProcAddr(modkernel32, "GetTempPathW")
procWSAStartup = getSysProcAddr(modwsock32, "WSAStartup") procWSAStartup = getSysProcAddr(modwsock32, "WSAStartup")
procWSACleanup = getSysProcAddr(modwsock32, "WSACleanup") procWSACleanup = getSysProcAddr(modwsock32, "WSACleanup")
procsocket = getSysProcAddr(modwsock32, "socket") procsocket = getSysProcAddr(modwsock32, "socket")
...@@ -375,6 +376,17 @@ func GetQueuedCompletionStatus(cphandle int32, qty *uint32, key *uint32, overlap ...@@ -375,6 +376,17 @@ func GetQueuedCompletionStatus(cphandle int32, qty *uint32, key *uint32, overlap
return return
} }
func GetTempPath(buflen uint32, buf *uint16) (n uint32, errno int) {
r0, _, e1 := Syscall(procGetTempPathW, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
n = uint32(r0)
if n == 0 {
errno = int(e1)
} else {
errno = 0
}
return
}
func WSAStartup(verreq uint32, data *WSAData) (sockerrno int) { func WSAStartup(verreq uint32, data *WSAData) (sockerrno int) {
r0, _, _ := Syscall(procWSAStartup, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) r0, _, _ := Syscall(procWSAStartup, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
sockerrno = int(r0) sockerrno = int(r0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment