From 4152b4345724dae4b058d48a23d29ac8f8bda453 Mon Sep 17 00:00:00 2001
From: Brad Fitzpatrick
Date: Fri, 10 Feb 2012 14:16:15 +1100
Subject: [PATCH] os: delete Exec, NewFile takes uintptr, rename ShellExpand,
doc fixes
Delete O_NDELAY, O_NONBLOCK, O_NOCTTY, O_ASYNC.
Clean up some docs.
Rename ShellExpand -> ExpandEnv.
Make NewFile take a uintptr; change File.Fd to return one.
(for API compatibility between Unix and Windows)
Fixes #2947
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5655045
---
doc/go1.html | 17 +++++++++++++----
doc/go1.tmpl | 17 +++++++++++++----
src/pkg/net/fd.go | 10 +++++-----
src/pkg/net/file.go | 2 +-
src/pkg/net/newpollserver.go | 6 +++---
src/pkg/net/sendfile_linux.go | 2 +-
src/pkg/os/env.go | 8 ++++----
src/pkg/os/error_posix.go | 1 -
src/pkg/os/exec/exec_test.go | 2 +-
src/pkg/os/exec_plan9.go | 14 --------------
src/pkg/os/exec_posix.go | 21 +--------------------
src/pkg/os/file.go | 26 +++++++++++---------------
src/pkg/os/file_unix.go | 21 +++++++++------------
src/pkg/os/file_windows.go | 13 +++++++------
src/pkg/os/stat_windows.go | 4 ----
15 files changed, 69 insertions(+), 95 deletions(-)
diff --git a/doc/go1.html b/doc/go1.html
index 664d3a9dd01..0fc7db47c5a 100644
--- a/doc/go1.html
+++ b/doc/go1.html
@@ -1353,10 +1353,19 @@ The semantic change makes it difficult for the fix tool to update automatically.
the Time
type from the
time
package.
-
-Updating:
-Code that uses os.Time
will fail to compile and must be updated by hand.
-
+The Exec
function has been removed; callers should use
+Exec
from the syscall
package, where available.
+
+The ShellExpand
function has been renamed to ExpandEnv
.
+
+The NewFile
function
+now takes a uintptr
fd, instead of an int
.
+The Fd
method on files now
+also returns a uintptr
.
+
+Updating: Code will fail to compile and must be updated
+by hand.
The os.FileInfo type
diff --git a/doc/go1.tmpl b/doc/go1.tmpl
index da72c6a4a86..4a0a2833558 100644
--- a/doc/go1.tmpl
+++ b/doc/go1.tmpl
@@ -1256,10 +1256,19 @@ The semantic change makes it difficult for the fix tool to update automatically.
the Time
type from the
time
package.
-
-Updating:
-Code that uses os.Time
will fail to compile and must be updated by hand.
-
+The Exec
function has been removed; callers should use
+Exec
from the syscall
package, where available.
+
+The ShellExpand
function has been renamed to ExpandEnv
.
+
+The NewFile
function
+now takes a uintptr
fd, instead of an int
.
+The Fd
method on files now
+also returns a uintptr
.
+
+Updating: Code will fail to compile and must be updated
+by hand.
The os.FileInfo type
diff --git a/src/pkg/net/fd.go b/src/pkg/net/fd.go
index 2352d22e115..607a6c115ac 100644
--- a/src/pkg/net/fd.go
+++ b/src/pkg/net/fd.go
@@ -228,7 +228,7 @@ func (s *pollServer) Run() {
s.CheckDeadlines()
continue
}
- if fd == s.pr.Fd() {
+ if fd == int(s.pr.Fd()) {
// Drain our wakeup pipe (we could loop here,
// but it's unlikely that there are more than
// len(scratch) wakeup calls).
@@ -295,7 +295,7 @@ func (fd *netFD) setAddr(laddr, raddr Addr) {
if raddr != nil {
rs = raddr.String()
}
- fd.sysfile = os.NewFile(fd.sysfd, fd.net+":"+ls+"->"+rs)
+ fd.sysfile = os.NewFile(uintptr(fd.sysfd), fd.net+":"+ls+"->"+rs)
}
func (fd *netFD) connect(ra syscall.Sockaddr) error {
@@ -382,7 +382,7 @@ func (fd *netFD) Read(p []byte) (n int, err error) {
return 0, os.EINVAL
}
for {
- n, err = syscall.Read(fd.sysfile.Fd(), p)
+ n, err = syscall.Read(int(fd.sysfile.Fd()), p)
if err == syscall.EAGAIN {
if fd.rdeadline >= 0 {
pollserver.WaitRead(fd)
@@ -476,7 +476,7 @@ func (fd *netFD) Write(p []byte) (int, error) {
nn := 0
for {
var n int
- n, err = syscall.Write(fd.sysfile.Fd(), p[nn:])
+ n, err = syscall.Write(int(fd.sysfile.Fd()), p[nn:])
if n > 0 {
nn += n
}
@@ -615,7 +615,7 @@ func (fd *netFD) dup() (f *os.File, err error) {
return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
}
- return os.NewFile(ns, fd.sysfile.Name()), nil
+ return os.NewFile(uintptr(ns), fd.sysfile.Name()), nil
}
func closesocket(s int) error {
diff --git a/src/pkg/net/file.go b/src/pkg/net/file.go
index 901b8565995..f9546dc930d 100644
--- a/src/pkg/net/file.go
+++ b/src/pkg/net/file.go
@@ -12,7 +12,7 @@ import (
)
func newFileFD(f *os.File) (*netFD, error) {
- fd, err := syscall.Dup(f.Fd())
+ fd, err := syscall.Dup(int(f.Fd()))
if err != nil {
return nil, os.NewSyscallError("dup", err)
}
diff --git a/src/pkg/net/newpollserver.go b/src/pkg/net/newpollserver.go
index 06bc24cd8a2..d34bb511f7f 100644
--- a/src/pkg/net/newpollserver.go
+++ b/src/pkg/net/newpollserver.go
@@ -18,16 +18,16 @@ func newPollServer() (s *pollServer, err error) {
if s.pr, s.pw, err = os.Pipe(); err != nil {
return nil, err
}
- if err = syscall.SetNonblock(s.pr.Fd(), true); err != nil {
+ if err = syscall.SetNonblock(int(s.pr.Fd()), true); err != nil {
goto Errno
}
- if err = syscall.SetNonblock(s.pw.Fd(), true); err != nil {
+ if err = syscall.SetNonblock(int(s.pw.Fd()), true); err != nil {
goto Errno
}
if s.poll, err = newpollster(); err != nil {
goto Error
}
- if _, err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil {
+ if _, err = s.poll.AddFD(int(s.pr.Fd()), 'r', true); err != nil {
s.poll.Close()
goto Error
}
diff --git a/src/pkg/net/sendfile_linux.go b/src/pkg/net/sendfile_linux.go
index 7f51519b2ed..ab3a3811fe2 100644
--- a/src/pkg/net/sendfile_linux.go
+++ b/src/pkg/net/sendfile_linux.go
@@ -42,7 +42,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
defer c.decref()
dst := c.sysfd
- src := f.Fd()
+ src := int(f.Fd())
for remain > 0 {
n := maxSendfileSize
if int64(n) > remain {
diff --git a/src/pkg/os/env.go b/src/pkg/os/env.go
index 7e3f52502e5..59350510ccf 100644
--- a/src/pkg/os/env.go
+++ b/src/pkg/os/env.go
@@ -29,10 +29,10 @@ func Expand(s string, mapping func(string) string) string {
return string(buf) + s[i:]
}
-// ShellExpand replaces ${var} or $var in the string according to the values
-// of the operating system's environment variables. References to undefined
+// ExpandEnv replaces ${var} or $var in the string according to the values
+// of the current environment variables. References to undefined
// variables are replaced by the empty string.
-func ShellExpand(s string) string {
+func ExpandEnv(s string) string {
return Expand(s, Getenv)
}
@@ -115,7 +115,7 @@ func Clearenv() {
syscall.Clearenv()
}
-// Environ returns an array of strings representing the environment,
+// Environ returns a copy of strings representing the environment,
// in the form "key=value".
func Environ() []string {
return syscall.Environ()
diff --git a/src/pkg/os/error_posix.go b/src/pkg/os/error_posix.go
index 1a08627256a..7fdf3e10f07 100644
--- a/src/pkg/os/error_posix.go
+++ b/src/pkg/os/error_posix.go
@@ -15,7 +15,6 @@ var (
ESRCH error = syscall.ESRCH
EINTR error = syscall.EINTR
EIO error = syscall.EIO
- ENXIO error = syscall.ENXIO
E2BIG error = syscall.E2BIG
ENOEXEC error = syscall.ENOEXEC
EBADF error = syscall.EBADF
diff --git a/src/pkg/os/exec/exec_test.go b/src/pkg/os/exec/exec_test.go
index d00d12008f7..2e4bef5119f 100644
--- a/src/pkg/os/exec/exec_test.go
+++ b/src/pkg/os/exec/exec_test.go
@@ -153,7 +153,7 @@ func TestExtraFiles(t *testing.T) {
// Ensure that file descriptors have not already been leaked into
// our environment.
- for fd := os.Stderr.Fd() + 1; fd <= 101; fd++ {
+ for fd := int(os.Stderr.Fd()) + 1; fd <= 101; fd++ {
err := syscall.Close(fd)
if err == nil {
t.Logf("Something already leaked - closed fd %d", fd)
diff --git a/src/pkg/os/exec_plan9.go b/src/pkg/os/exec_plan9.go
index 1515c4a2304..08f16b86d54 100644
--- a/src/pkg/os/exec_plan9.go
+++ b/src/pkg/os/exec_plan9.go
@@ -72,20 +72,6 @@ func (p *Process) Kill() error {
return e
}
-// Exec replaces the current process with an execution of the
-// named binary, with arguments argv and environment envv.
-// If successful, Exec never returns. If it fails, it returns an error.
-// ForkExec is almost always a better way to execute a program.
-// If there is an error, it will be of type *PathError.
-func Exec(name string, argv []string, envv []string) error {
- e := syscall.Exec(name, argv, envv)
- if e != nil {
- return &PathError{"exec", name, e}
- }
-
- return nil
-}
-
// Waitmsg stores the information about an exited process as reported by Wait.
type Waitmsg struct {
syscall.Waitmsg
diff --git a/src/pkg/os/exec_posix.go b/src/pkg/os/exec_posix.go
index 1f2720389e1..df283f1c024 100644
--- a/src/pkg/os/exec_posix.go
+++ b/src/pkg/os/exec_posix.go
@@ -38,7 +38,7 @@ func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e
sysattr.Env = Environ()
}
for _, f := range attr.Files {
- sysattr.Files = append(sysattr.Files, f.Fd())
+ sysattr.Files = append(sysattr.Files, int(f.Fd()))
}
pid, h, e := syscall.StartProcess(name, argv, sysattr)
@@ -53,25 +53,6 @@ func (p *Process) Kill() error {
return p.Signal(UnixSignal(syscall.SIGKILL))
}
-// Exec replaces the current process with an execution of the
-// named binary, with arguments argv and environment envv.
-// If successful, Exec never returns. If it fails, it returns an error.
-//
-// To run a child process, see StartProcess (for a low-level interface)
-// or the os/exec package (for higher-level interfaces).
-//
-// If there is an error, it will be of type *PathError.
-func Exec(name string, argv []string, envv []string) error {
- if envv == nil {
- envv = Environ()
- }
- e := syscall.Exec(name, argv, envv)
- if e != nil {
- return &PathError{"exec", name, e}
- }
- return nil
-}
-
// TODO(rsc): Should os implement its own syscall.WaitStatus
// wrapper with the methods, or is exposing the underlying one enough?
//
diff --git a/src/pkg/os/file.go b/src/pkg/os/file.go
index 90df361c484..85f151e2840 100644
--- a/src/pkg/os/file.go
+++ b/src/pkg/os/file.go
@@ -25,26 +25,22 @@ func (f *File) Name() string { return f.name }
// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
// standard output, and standard error file descriptors.
var (
- Stdin = NewFile(syscall.Stdin, "/dev/stdin")
- Stdout = NewFile(syscall.Stdout, "/dev/stdout")
- Stderr = NewFile(syscall.Stderr, "/dev/stderr")
+ Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
+ Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
+ Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)
// Flags to Open wrapping those of the underlying system. Not all flags
// may be implemented on a given system.
const (
- O_RDONLY int = syscall.O_RDONLY // open the file read-only.
- O_WRONLY int = syscall.O_WRONLY // open the file write-only.
- O_RDWR int = syscall.O_RDWR // open the file read-write.
- O_APPEND int = syscall.O_APPEND // append data to the file when writing.
- O_ASYNC int = syscall.O_ASYNC // generate a signal when I/O is available.
- O_CREATE int = syscall.O_CREAT // create a new file if none exists.
- O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
- O_NOCTTY int = syscall.O_NOCTTY // do not make file the controlling tty.
- O_NONBLOCK int = syscall.O_NONBLOCK // open in non-blocking mode.
- O_NDELAY int = O_NONBLOCK // synonym for O_NONBLOCK
- O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
- O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.
+ O_RDONLY int = syscall.O_RDONLY // open the file read-only.
+ O_WRONLY int = syscall.O_WRONLY // open the file write-only.
+ O_RDWR int = syscall.O_RDWR // open the file read-write.
+ O_APPEND int = syscall.O_APPEND // append data to the file when writing.
+ O_CREATE int = syscall.O_CREAT // create a new file if none exists.
+ O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
+ O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
+ O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.
)
// Seek whence values.
diff --git a/src/pkg/os/file_unix.go b/src/pkg/os/file_unix.go
index 6672f280d84..0a422f4e889 100644
--- a/src/pkg/os/file_unix.go
+++ b/src/pkg/os/file_unix.go
@@ -28,19 +28,20 @@ type file struct {
}
// Fd returns the integer Unix file descriptor referencing the open file.
-func (f *File) Fd() int {
+func (f *File) Fd() uintptr {
if f == nil {
- return -1
+ return ^(uintptr(0))
}
- return f.fd
+ return uintptr(f.fd)
}
// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd int, name string) *File {
- if fd < 0 {
+func NewFile(fd uintptr, name string) *File {
+ fdi := int(fd)
+ if fdi < 0 {
return nil
}
- f := &File{&file{fd: fd, name: name}}
+ f := &File{&file{fd: fdi, name: name}}
runtime.SetFinalizer(f.file, (*file).close)
return f
}
@@ -78,7 +79,7 @@ func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
syscall.CloseOnExec(r)
}
- return NewFile(r, name), nil
+ return NewFile(uintptr(r), name), nil
}
// Close closes the File, rendering it unusable for I/O.
@@ -114,10 +115,6 @@ func (f *File) Stat() (fi FileInfo, err error) {
}
// Stat returns a FileInfo describing the named file.
-// If name names a valid symbolic link, the returned FileInfo describes
-// the file pointed at by the link and has fi.FollowedSymlink set to true.
-// If name names an invalid symbolic link, the returned FileInfo describes
-// the link itself and has fi.FollowedSymlink set to false.
// If there is an error, it will be of type *PathError.
func Stat(name string) (fi FileInfo, err error) {
var stat syscall.Stat_t
@@ -268,7 +265,7 @@ func Pipe() (r *File, w *File, err error) {
syscall.CloseOnExec(p[1])
syscall.ForkLock.RUnlock()
- return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
+ return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
}
// TempDir returns the default directory to use for temporary files.
diff --git a/src/pkg/os/file_windows.go b/src/pkg/os/file_windows.go
index 0b721c6afa2..7f263c80cd1 100644
--- a/src/pkg/os/file_windows.go
+++ b/src/pkg/os/file_windows.go
@@ -30,19 +30,20 @@ type file struct {
}
// Fd returns the Windows handle referencing the open file.
-func (file *File) Fd() syscall.Handle {
+func (file *File) Fd() uintptr {
if file == nil {
- return syscall.InvalidHandle
+ return uintptr(syscall.InvalidHandle)
}
- return file.fd
+ return uintptr(file.fd)
}
// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd syscall.Handle, name string) *File {
- if fd == syscall.InvalidHandle {
+func NewFile(fd uintptr, name string) *File {
+ h := syscall.Handle(fd)
+ if h == syscall.InvalidHandle {
return nil
}
- f := &File{&file{fd: fd, name: name}}
+ f := &File{&file{fd: h, name: name}}
runtime.SetFinalizer(f.file, (*file).close)
return f
}
diff --git a/src/pkg/os/stat_windows.go b/src/pkg/os/stat_windows.go
index 24db15960d5..c8bfc3f6d49 100644
--- a/src/pkg/os/stat_windows.go
+++ b/src/pkg/os/stat_windows.go
@@ -29,10 +29,6 @@ func (file *File) Stat() (fi FileInfo, err error) {
}
// Stat returns a FileInfo structure describing the named file.
-// If name names a valid symbolic link, the returned FileInfo describes
-// the file pointed at by the link and has fi.FollowedSymlink set to true.
-// If name names an invalid symbolic link, the returned FileInfo describes
-// the link itself and has fi.FollowedSymlink set to false.
// If there is an error, it will be of type *PathError.
func Stat(name string) (fi FileInfo, err error) {
if len(name) == 0 {