LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build darwin freebsd linux netbsd openbsd | 5 // +build darwin freebsd linux netbsd openbsd |
6 | 6 |
7 package os | 7 package os |
8 | 8 |
9 import ( | 9 import ( |
10 "runtime" | 10 "runtime" |
(...skipping 10 matching lines...) Expand all Loading... |
21 // can overwrite this data, which could cause the finalizer | 21 // can overwrite this data, which could cause the finalizer |
22 // to close the wrong file descriptor. | 22 // to close the wrong file descriptor. |
23 type file struct { | 23 type file struct { |
24 fd int | 24 fd int |
25 name string | 25 name string |
26 dirinfo *dirInfo // nil unless directory being read | 26 dirinfo *dirInfo // nil unless directory being read |
27 nepipe int // number of consecutive EPIPE in Write | 27 nepipe int // number of consecutive EPIPE in Write |
28 } | 28 } |
29 | 29 |
30 // Fd returns the integer Unix file descriptor referencing the open file. | 30 // Fd returns the integer Unix file descriptor referencing the open file. |
31 func (f *File) Fd() int { | 31 func (f *File) Fd() uintptr { |
32 if f == nil { | 32 if f == nil { |
33 » » return -1 | 33 » » return ^(uintptr(0)) |
34 » } | 34 » } |
35 » return f.fd | 35 » return uintptr(f.fd) |
36 } | 36 } |
37 | 37 |
38 // NewFile returns a new File with the given file descriptor and name. | 38 // NewFile returns a new File with the given file descriptor and name. |
39 func NewFile(fd int, name string) *File { | 39 func NewFile(fd uintptr, name string) *File { |
40 » if fd < 0 { | 40 » fdi := int(fd) |
| 41 » if fdi < 0 { |
41 return nil | 42 return nil |
42 } | 43 } |
43 » f := &File{&file{fd: fd, name: name}} | 44 » f := &File{&file{fd: fdi, name: name}} |
44 runtime.SetFinalizer(f.file, (*file).close) | 45 runtime.SetFinalizer(f.file, (*file).close) |
45 return f | 46 return f |
46 } | 47 } |
47 | 48 |
48 // Auxiliary information if the File describes a directory | 49 // Auxiliary information if the File describes a directory |
49 type dirInfo struct { | 50 type dirInfo struct { |
50 buf []byte // buffer for directory I/O | 51 buf []byte // buffer for directory I/O |
51 nbuf int // length of buf; return value from Getdirentries | 52 nbuf int // length of buf; return value from Getdirentries |
52 bufp int // location of next record in buf. | 53 bufp int // location of next record in buf. |
53 } | 54 } |
(...skipping 17 matching lines...) Expand all Loading... |
71 // content to live with. See ../syscall/exec_unix.go. | 72 // content to live with. See ../syscall/exec_unix.go. |
72 // On OS X 10.6, the O_CLOEXEC flag is not respected. | 73 // On OS X 10.6, the O_CLOEXEC flag is not respected. |
73 // On OS X 10.7, the O_CLOEXEC flag works. | 74 // On OS X 10.7, the O_CLOEXEC flag works. |
74 // Without a cheap & reliable way to detect 10.6 vs 10.7 at | 75 // Without a cheap & reliable way to detect 10.6 vs 10.7 at |
75 // runtime, we just always call syscall.CloseOnExec on Darwin. | 76 // runtime, we just always call syscall.CloseOnExec on Darwin. |
76 // Once >=10.7 is prevalent, this extra call can removed. | 77 // Once >=10.7 is prevalent, this extra call can removed. |
77 if syscall.O_CLOEXEC == 0 || runtime.GOOS == "darwin" { // O_CLOEXEC not
supported | 78 if syscall.O_CLOEXEC == 0 || runtime.GOOS == "darwin" { // O_CLOEXEC not
supported |
78 syscall.CloseOnExec(r) | 79 syscall.CloseOnExec(r) |
79 } | 80 } |
80 | 81 |
81 » return NewFile(r, name), nil | 82 » return NewFile(uintptr(r), name), nil |
82 } | 83 } |
83 | 84 |
84 // Close closes the File, rendering it unusable for I/O. | 85 // Close closes the File, rendering it unusable for I/O. |
85 // It returns an error, if any. | 86 // It returns an error, if any. |
86 func (f *File) Close() error { | 87 func (f *File) Close() error { |
87 return f.file.close() | 88 return f.file.close() |
88 } | 89 } |
89 | 90 |
90 func (file *file) close() error { | 91 func (file *file) close() error { |
91 if file == nil || file.fd < 0 { | 92 if file == nil || file.fd < 0 { |
(...skipping 15 matching lines...) Expand all Loading... |
107 func (f *File) Stat() (fi FileInfo, err error) { | 108 func (f *File) Stat() (fi FileInfo, err error) { |
108 var stat syscall.Stat_t | 109 var stat syscall.Stat_t |
109 err = syscall.Fstat(f.fd, &stat) | 110 err = syscall.Fstat(f.fd, &stat) |
110 if err != nil { | 111 if err != nil { |
111 return nil, &PathError{"stat", f.name, err} | 112 return nil, &PathError{"stat", f.name, err} |
112 } | 113 } |
113 return fileInfoFromStat(&stat, f.name), nil | 114 return fileInfoFromStat(&stat, f.name), nil |
114 } | 115 } |
115 | 116 |
116 // Stat returns a FileInfo describing the named file. | 117 // 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. | |
121 // If there is an error, it will be of type *PathError. | 118 // If there is an error, it will be of type *PathError. |
122 func Stat(name string) (fi FileInfo, err error) { | 119 func Stat(name string) (fi FileInfo, err error) { |
123 var stat syscall.Stat_t | 120 var stat syscall.Stat_t |
124 err = syscall.Stat(name, &stat) | 121 err = syscall.Stat(name, &stat) |
125 if err != nil { | 122 if err != nil { |
126 return nil, &PathError{"stat", name, err} | 123 return nil, &PathError{"stat", name, err} |
127 } | 124 } |
128 return fileInfoFromStat(&stat, name), nil | 125 return fileInfoFromStat(&stat, name), nil |
129 } | 126 } |
130 | 127 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 syscall.ForkLock.RLock() | 258 syscall.ForkLock.RLock() |
262 e := syscall.Pipe(p[0:]) | 259 e := syscall.Pipe(p[0:]) |
263 if e != nil { | 260 if e != nil { |
264 syscall.ForkLock.RUnlock() | 261 syscall.ForkLock.RUnlock() |
265 return nil, nil, NewSyscallError("pipe", e) | 262 return nil, nil, NewSyscallError("pipe", e) |
266 } | 263 } |
267 syscall.CloseOnExec(p[0]) | 264 syscall.CloseOnExec(p[0]) |
268 syscall.CloseOnExec(p[1]) | 265 syscall.CloseOnExec(p[1]) |
269 syscall.ForkLock.RUnlock() | 266 syscall.ForkLock.RUnlock() |
270 | 267 |
271 » return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil | 268 » return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil |
272 } | 269 } |
273 | 270 |
274 // TempDir returns the default directory to use for temporary files. | 271 // TempDir returns the default directory to use for temporary files. |
275 func TempDir() string { | 272 func TempDir() string { |
276 dir := Getenv("TMPDIR") | 273 dir := Getenv("TMPDIR") |
277 if dir == "" { | 274 if dir == "" { |
278 dir = "/tmp" | 275 dir = "/tmp" |
279 } | 276 } |
280 return dir | 277 return dir |
281 } | 278 } |
LEFT | RIGHT |