Skip to content

Commit 4152b43

Browse files
committed
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
1 parent 6c0aa2f commit 4152b43

15 files changed

+69
-95
lines changed

doc/go1.html

+13-4
Original file line numberDiff line numberDiff line change
@@ -1353,10 +1353,19 @@ <h3 id="os">The os package</h3>
13531353
the <a href="/pkg/time/#Time"><code>Time</code></a> type from the
13541354
<code>time</code> package.</p>
13551355

1356-
<p>
1357-
<em>Updating</em>:
1358-
Code that uses <code>os.Time</code> will fail to compile and must be updated by hand.
1359-
</p>
1356+
<p>The <code>Exec</code> function has been removed; callers should use
1357+
<code>Exec</code> from the <code>syscall</code> package, where available.</p>
1358+
1359+
<p>The <code>ShellExpand</code> function has been renamed to <a
1360+
href="/pkg/os/#ExpandEnv"><code>ExpandEnv</code></a>.</p>
1361+
1362+
<p>The <a href="/pkg/os/#NewFile"><code>NewFile</code></a> function
1363+
now takes a <code>uintptr</code> fd, instead of an <code>int</code>.
1364+
The <a href="/pkg/os/#File.Fd"><code>Fd</code></a> method on files now
1365+
also returns a <code>uintptr</code>.</p>
1366+
1367+
<p><em>Updating</em>: Code will fail to compile and must be updated
1368+
by hand. </p>
13601369

13611370
<h4 id="os_fileinfo">The os.FileInfo type</h4>
13621371

doc/go1.tmpl

+13-4
Original file line numberDiff line numberDiff line change
@@ -1256,10 +1256,19 @@ The semantic change makes it difficult for the fix tool to update automatically.
12561256
the <a href="/pkg/time/#Time"><code>Time</code></a> type from the
12571257
<code>time</code> package.</p>
12581258

1259-
<p>
1260-
<em>Updating</em>:
1261-
Code that uses <code>os.Time</code> will fail to compile and must be updated by hand.
1262-
</p>
1259+
<p>The <code>Exec</code> function has been removed; callers should use
1260+
<code>Exec</code> from the <code>syscall</code> package, where available.</p>
1261+
1262+
<p>The <code>ShellExpand</code> function has been renamed to <a
1263+
href="/pkg/os/#ExpandEnv"><code>ExpandEnv</code></a>.</p>
1264+
1265+
<p>The <a href="/pkg/os/#NewFile"><code>NewFile</code></a> function
1266+
now takes a <code>uintptr</code> fd, instead of an <code>int</code>.
1267+
The <a href="/pkg/os/#File.Fd"><code>Fd</code></a> method on files now
1268+
also returns a <code>uintptr</code>.</p>
1269+
1270+
<p><em>Updating</em>: Code will fail to compile and must be updated
1271+
by hand. </p>
12631272

12641273
<h4 id="os_fileinfo">The os.FileInfo type</h4>
12651274

src/pkg/net/fd.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ func (s *pollServer) Run() {
228228
s.CheckDeadlines()
229229
continue
230230
}
231-
if fd == s.pr.Fd() {
231+
if fd == int(s.pr.Fd()) {
232232
// Drain our wakeup pipe (we could loop here,
233233
// but it's unlikely that there are more than
234234
// len(scratch) wakeup calls).
@@ -295,7 +295,7 @@ func (fd *netFD) setAddr(laddr, raddr Addr) {
295295
if raddr != nil {
296296
rs = raddr.String()
297297
}
298-
fd.sysfile = os.NewFile(fd.sysfd, fd.net+":"+ls+"->"+rs)
298+
fd.sysfile = os.NewFile(uintptr(fd.sysfd), fd.net+":"+ls+"->"+rs)
299299
}
300300

301301
func (fd *netFD) connect(ra syscall.Sockaddr) error {
@@ -382,7 +382,7 @@ func (fd *netFD) Read(p []byte) (n int, err error) {
382382
return 0, os.EINVAL
383383
}
384384
for {
385-
n, err = syscall.Read(fd.sysfile.Fd(), p)
385+
n, err = syscall.Read(int(fd.sysfile.Fd()), p)
386386
if err == syscall.EAGAIN {
387387
if fd.rdeadline >= 0 {
388388
pollserver.WaitRead(fd)
@@ -476,7 +476,7 @@ func (fd *netFD) Write(p []byte) (int, error) {
476476
nn := 0
477477
for {
478478
var n int
479-
n, err = syscall.Write(fd.sysfile.Fd(), p[nn:])
479+
n, err = syscall.Write(int(fd.sysfile.Fd()), p[nn:])
480480
if n > 0 {
481481
nn += n
482482
}
@@ -615,7 +615,7 @@ func (fd *netFD) dup() (f *os.File, err error) {
615615
return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
616616
}
617617

618-
return os.NewFile(ns, fd.sysfile.Name()), nil
618+
return os.NewFile(uintptr(ns), fd.sysfile.Name()), nil
619619
}
620620

621621
func closesocket(s int) error {

src/pkg/net/file.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
)
1313

1414
func newFileFD(f *os.File) (*netFD, error) {
15-
fd, err := syscall.Dup(f.Fd())
15+
fd, err := syscall.Dup(int(f.Fd()))
1616
if err != nil {
1717
return nil, os.NewSyscallError("dup", err)
1818
}

src/pkg/net/newpollserver.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ func newPollServer() (s *pollServer, err error) {
1818
if s.pr, s.pw, err = os.Pipe(); err != nil {
1919
return nil, err
2020
}
21-
if err = syscall.SetNonblock(s.pr.Fd(), true); err != nil {
21+
if err = syscall.SetNonblock(int(s.pr.Fd()), true); err != nil {
2222
goto Errno
2323
}
24-
if err = syscall.SetNonblock(s.pw.Fd(), true); err != nil {
24+
if err = syscall.SetNonblock(int(s.pw.Fd()), true); err != nil {
2525
goto Errno
2626
}
2727
if s.poll, err = newpollster(); err != nil {
2828
goto Error
2929
}
30-
if _, err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil {
30+
if _, err = s.poll.AddFD(int(s.pr.Fd()), 'r', true); err != nil {
3131
s.poll.Close()
3232
goto Error
3333
}

src/pkg/net/sendfile_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
4242
defer c.decref()
4343

4444
dst := c.sysfd
45-
src := f.Fd()
45+
src := int(f.Fd())
4646
for remain > 0 {
4747
n := maxSendfileSize
4848
if int64(n) > remain {

src/pkg/os/env.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ func Expand(s string, mapping func(string) string) string {
2929
return string(buf) + s[i:]
3030
}
3131

32-
// ShellExpand replaces ${var} or $var in the string according to the values
33-
// of the operating system's environment variables. References to undefined
32+
// ExpandEnv replaces ${var} or $var in the string according to the values
33+
// of the current environment variables. References to undefined
3434
// variables are replaced by the empty string.
35-
func ShellExpand(s string) string {
35+
func ExpandEnv(s string) string {
3636
return Expand(s, Getenv)
3737
}
3838

@@ -115,7 +115,7 @@ func Clearenv() {
115115
syscall.Clearenv()
116116
}
117117

118-
// Environ returns an array of strings representing the environment,
118+
// Environ returns a copy of strings representing the environment,
119119
// in the form "key=value".
120120
func Environ() []string {
121121
return syscall.Environ()

src/pkg/os/error_posix.go

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ var (
1515
ESRCH error = syscall.ESRCH
1616
EINTR error = syscall.EINTR
1717
EIO error = syscall.EIO
18-
ENXIO error = syscall.ENXIO
1918
E2BIG error = syscall.E2BIG
2019
ENOEXEC error = syscall.ENOEXEC
2120
EBADF error = syscall.EBADF

src/pkg/os/exec/exec_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func TestExtraFiles(t *testing.T) {
153153

154154
// Ensure that file descriptors have not already been leaked into
155155
// our environment.
156-
for fd := os.Stderr.Fd() + 1; fd <= 101; fd++ {
156+
for fd := int(os.Stderr.Fd()) + 1; fd <= 101; fd++ {
157157
err := syscall.Close(fd)
158158
if err == nil {
159159
t.Logf("Something already leaked - closed fd %d", fd)

src/pkg/os/exec_plan9.go

-14
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,6 @@ func (p *Process) Kill() error {
7272
return e
7373
}
7474

75-
// Exec replaces the current process with an execution of the
76-
// named binary, with arguments argv and environment envv.
77-
// If successful, Exec never returns. If it fails, it returns an error.
78-
// ForkExec is almost always a better way to execute a program.
79-
// If there is an error, it will be of type *PathError.
80-
func Exec(name string, argv []string, envv []string) error {
81-
e := syscall.Exec(name, argv, envv)
82-
if e != nil {
83-
return &PathError{"exec", name, e}
84-
}
85-
86-
return nil
87-
}
88-
8975
// Waitmsg stores the information about an exited process as reported by Wait.
9076
type Waitmsg struct {
9177
syscall.Waitmsg

src/pkg/os/exec_posix.go

+1-20
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e
3838
sysattr.Env = Environ()
3939
}
4040
for _, f := range attr.Files {
41-
sysattr.Files = append(sysattr.Files, f.Fd())
41+
sysattr.Files = append(sysattr.Files, int(f.Fd()))
4242
}
4343

4444
pid, h, e := syscall.StartProcess(name, argv, sysattr)
@@ -53,25 +53,6 @@ func (p *Process) Kill() error {
5353
return p.Signal(UnixSignal(syscall.SIGKILL))
5454
}
5555

56-
// Exec replaces the current process with an execution of the
57-
// named binary, with arguments argv and environment envv.
58-
// If successful, Exec never returns. If it fails, it returns an error.
59-
//
60-
// To run a child process, see StartProcess (for a low-level interface)
61-
// or the os/exec package (for higher-level interfaces).
62-
//
63-
// If there is an error, it will be of type *PathError.
64-
func Exec(name string, argv []string, envv []string) error {
65-
if envv == nil {
66-
envv = Environ()
67-
}
68-
e := syscall.Exec(name, argv, envv)
69-
if e != nil {
70-
return &PathError{"exec", name, e}
71-
}
72-
return nil
73-
}
74-
7556
// TODO(rsc): Should os implement its own syscall.WaitStatus
7657
// wrapper with the methods, or is exposing the underlying one enough?
7758
//

src/pkg/os/file.go

+11-15
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,22 @@ func (f *File) Name() string { return f.name }
2525
// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
2626
// standard output, and standard error file descriptors.
2727
var (
28-
Stdin = NewFile(syscall.Stdin, "/dev/stdin")
29-
Stdout = NewFile(syscall.Stdout, "/dev/stdout")
30-
Stderr = NewFile(syscall.Stderr, "/dev/stderr")
28+
Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
29+
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
30+
Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
3131
)
3232

3333
// Flags to Open wrapping those of the underlying system. Not all flags
3434
// may be implemented on a given system.
3535
const (
36-
O_RDONLY int = syscall.O_RDONLY // open the file read-only.
37-
O_WRONLY int = syscall.O_WRONLY // open the file write-only.
38-
O_RDWR int = syscall.O_RDWR // open the file read-write.
39-
O_APPEND int = syscall.O_APPEND // append data to the file when writing.
40-
O_ASYNC int = syscall.O_ASYNC // generate a signal when I/O is available.
41-
O_CREATE int = syscall.O_CREAT // create a new file if none exists.
42-
O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
43-
O_NOCTTY int = syscall.O_NOCTTY // do not make file the controlling tty.
44-
O_NONBLOCK int = syscall.O_NONBLOCK // open in non-blocking mode.
45-
O_NDELAY int = O_NONBLOCK // synonym for O_NONBLOCK
46-
O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
47-
O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.
36+
O_RDONLY int = syscall.O_RDONLY // open the file read-only.
37+
O_WRONLY int = syscall.O_WRONLY // open the file write-only.
38+
O_RDWR int = syscall.O_RDWR // open the file read-write.
39+
O_APPEND int = syscall.O_APPEND // append data to the file when writing.
40+
O_CREATE int = syscall.O_CREAT // create a new file if none exists.
41+
O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
42+
O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
43+
O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.
4844
)
4945

5046
// Seek whence values.

src/pkg/os/file_unix.go

+9-12
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,20 @@ type file struct {
2828
}
2929

3030
// Fd returns the integer Unix file descriptor referencing the open file.
31-
func (f *File) Fd() int {
31+
func (f *File) Fd() uintptr {
3232
if f == nil {
33-
return -1
33+
return ^(uintptr(0))
3434
}
35-
return f.fd
35+
return uintptr(f.fd)
3636
}
3737

3838
// NewFile returns a new File with the given file descriptor and name.
39-
func NewFile(fd int, name string) *File {
40-
if fd < 0 {
39+
func NewFile(fd uintptr, name string) *File {
40+
fdi := int(fd)
41+
if fdi < 0 {
4142
return nil
4243
}
43-
f := &File{&file{fd: fd, name: name}}
44+
f := &File{&file{fd: fdi, name: name}}
4445
runtime.SetFinalizer(f.file, (*file).close)
4546
return f
4647
}
@@ -78,7 +79,7 @@ func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
7879
syscall.CloseOnExec(r)
7980
}
8081

81-
return NewFile(r, name), nil
82+
return NewFile(uintptr(r), name), nil
8283
}
8384

8485
// Close closes the File, rendering it unusable for I/O.
@@ -114,10 +115,6 @@ func (f *File) Stat() (fi FileInfo, err error) {
114115
}
115116

116117
// Stat returns a FileInfo describing the named file.
117-
// If name names a valid symbolic link, the returned FileInfo describes
118-
// the file pointed at by the link and has fi.FollowedSymlink set to true.
119-
// If name names an invalid symbolic link, the returned FileInfo describes
120-
// the link itself and has fi.FollowedSymlink set to false.
121118
// If there is an error, it will be of type *PathError.
122119
func Stat(name string) (fi FileInfo, err error) {
123120
var stat syscall.Stat_t
@@ -268,7 +265,7 @@ func Pipe() (r *File, w *File, err error) {
268265
syscall.CloseOnExec(p[1])
269266
syscall.ForkLock.RUnlock()
270267

271-
return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
268+
return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
272269
}
273270

274271
// TempDir returns the default directory to use for temporary files.

src/pkg/os/file_windows.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,20 @@ type file struct {
3030
}
3131

3232
// Fd returns the Windows handle referencing the open file.
33-
func (file *File) Fd() syscall.Handle {
33+
func (file *File) Fd() uintptr {
3434
if file == nil {
35-
return syscall.InvalidHandle
35+
return uintptr(syscall.InvalidHandle)
3636
}
37-
return file.fd
37+
return uintptr(file.fd)
3838
}
3939

4040
// NewFile returns a new File with the given file descriptor and name.
41-
func NewFile(fd syscall.Handle, name string) *File {
42-
if fd == syscall.InvalidHandle {
41+
func NewFile(fd uintptr, name string) *File {
42+
h := syscall.Handle(fd)
43+
if h == syscall.InvalidHandle {
4344
return nil
4445
}
45-
f := &File{&file{fd: fd, name: name}}
46+
f := &File{&file{fd: h, name: name}}
4647
runtime.SetFinalizer(f.file, (*file).close)
4748
return f
4849
}

src/pkg/os/stat_windows.go

-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ func (file *File) Stat() (fi FileInfo, err error) {
2929
}
3030

3131
// Stat returns a FileInfo structure describing the named file.
32-
// If name names a valid symbolic link, the returned FileInfo describes
33-
// the file pointed at by the link and has fi.FollowedSymlink set to true.
34-
// If name names an invalid symbolic link, the returned FileInfo describes
35-
// the link itself and has fi.FollowedSymlink set to false.
3632
// If there is an error, it will be of type *PathError.
3733
func Stat(name string) (fi FileInfo, err error) {
3834
if len(name) == 0 {

0 commit comments

Comments
 (0)