OLD | NEW |
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 // The os package provides a platform-independent interface to operating | 5 // The os package provides a platform-independent interface to operating |
6 // system functionality. The design is Unix-like. | 6 // system functionality. The design is Unix-like. |
7 package os | 7 package os |
8 | 8 |
9 import ( | 9 import ( |
10 "runtime" | 10 "runtime" |
11 "syscall" | 11 "syscall" |
12 ) | 12 ) |
13 | 13 |
14 // Auxiliary information if the File describes a directory | |
15 type dirInfo struct { | |
16 buf []byte // buffer for directory I/O | |
17 nbuf int // length of buf; return value from Getdirentries | |
18 bufp int // location of next record in buf. | |
19 } | |
20 | |
21 // File represents an open file descriptor. | 14 // File represents an open file descriptor. |
22 type File struct { | 15 type File struct { |
23 fd int | 16 fd int |
24 name string | 17 name string |
25 dirinfo *dirInfo // nil unless directory being read | 18 dirinfo *dirInfo // nil unless directory being read |
26 nepipe int // number of consecutive EPIPE in Write | 19 nepipe int // number of consecutive EPIPE in Write |
27 } | 20 } |
28 | 21 |
29 // Fd returns the integer Unix file descriptor referencing the open file. | 22 // Fd returns the integer Unix file descriptor referencing the open file. |
30 func (file *File) Fd() int { return file.fd } | 23 func (file *File) Fd() int { return file.fd } |
(...skipping 30 matching lines...) Expand all Loading... |
61 O_CREAT = syscall.O_CREAT // create a new file if none exists. | 54 O_CREAT = syscall.O_CREAT // create a new file if none exists. |
62 O_EXCL = syscall.O_EXCL // used with O_CREAT, file must not exis
t | 55 O_EXCL = syscall.O_EXCL // used with O_CREAT, file must not exis
t |
63 O_NOCTTY = syscall.O_NOCTTY // do not make file the controlling tty. | 56 O_NOCTTY = syscall.O_NOCTTY // do not make file the controlling tty. |
64 O_NONBLOCK = syscall.O_NONBLOCK // open in non-blocking mode. | 57 O_NONBLOCK = syscall.O_NONBLOCK // open in non-blocking mode. |
65 O_NDELAY = O_NONBLOCK // synonym for O_NONBLOCK | 58 O_NDELAY = O_NONBLOCK // synonym for O_NONBLOCK |
66 O_SYNC = syscall.O_SYNC // open for synchronous I/O. | 59 O_SYNC = syscall.O_SYNC // open for synchronous I/O. |
67 O_TRUNC = syscall.O_TRUNC // if possible, truncate file when opene
d. | 60 O_TRUNC = syscall.O_TRUNC // if possible, truncate file when opene
d. |
68 O_CREATE = O_CREAT // create a new file if none exists. | 61 O_CREATE = O_CREAT // create a new file if none exists. |
69 ) | 62 ) |
70 | 63 |
71 // Open opens the named file with specified flag (O_RDONLY etc.) and perm, (0666
etc.) | |
72 // if applicable. If successful, methods on the returned File can be used for I
/O. | |
73 // It returns the File and an Error, if any. | |
74 func Open(name string, flag int, perm int) (file *File, err Error) { | |
75 r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, perm) | |
76 if e != 0 { | |
77 return nil, &PathError{"open", name, Errno(e)} | |
78 } | |
79 | |
80 // There's a race here with fork/exec, which we are | |
81 // content to live with. See ../syscall/exec.go | |
82 if syscall.O_CLOEXEC == 0 { // O_CLOEXEC not supported | |
83 syscall.CloseOnExec(r) | |
84 } | |
85 | |
86 return NewFile(r, name), nil | |
87 } | |
88 | |
89 // Close closes the File, rendering it unusable for I/O. | |
90 // It returns an Error, if any. | |
91 func (file *File) Close() Error { | |
92 if file == nil || file.fd < 0 { | |
93 return EINVAL | |
94 } | |
95 var err Error | |
96 if e := syscall.Close(file.fd); e != 0 { | |
97 err = &PathError{"close", file.name, Errno(e)} | |
98 } | |
99 file.fd = -1 // so it can't be closed again | |
100 | |
101 // no need for a finalizer anymore | |
102 runtime.SetFinalizer(file, nil) | |
103 return err | |
104 } | |
105 | |
106 type eofError int | 64 type eofError int |
107 | 65 |
108 func (eofError) String() string { return "EOF" } | 66 func (eofError) String() string { return "EOF" } |
109 | 67 |
110 // EOF is the Error returned by Read when no more input is available. | 68 // EOF is the Error returned by Read when no more input is available. |
111 // Functions should return EOF only to signal a graceful end of input. | 69 // Functions should return EOF only to signal a graceful end of input. |
112 // If the EOF occurs unexpectedly in a structured data stream, | 70 // If the EOF occurs unexpectedly in a structured data stream, |
113 // the appropriate error is either io.ErrUnexpectedEOF or some other error | 71 // the appropriate error is either io.ErrUnexpectedEOF or some other error |
114 // giving more detail. | 72 // giving more detail. |
115 var EOF Error = eofError(0) | 73 var EOF Error = eofError(0) |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 // describes the symbolic link. Lstat makes no attempt to follow the link. | 253 // describes the symbolic link. Lstat makes no attempt to follow the link. |
296 func Lstat(name string) (fi *FileInfo, err Error) { | 254 func Lstat(name string) (fi *FileInfo, err Error) { |
297 var stat syscall.Stat_t | 255 var stat syscall.Stat_t |
298 e := syscall.Lstat(name, &stat) | 256 e := syscall.Lstat(name, &stat) |
299 if e != 0 { | 257 if e != 0 { |
300 return nil, &PathError{"lstat", name, Errno(e)} | 258 return nil, &PathError{"lstat", name, Errno(e)} |
301 } | 259 } |
302 return fileInfoFromStat(name, new(FileInfo), &stat, &stat), nil | 260 return fileInfoFromStat(name, new(FileInfo), &stat, &stat), nil |
303 } | 261 } |
304 | 262 |
305 // Readdir reads the contents of the directory associated with file and | |
306 // returns an array of up to count FileInfo structures, as would be returned | |
307 // by Stat, in directory order. Subsequent calls on the same file will yield | |
308 // further FileInfos. | |
309 // A negative count means to read until EOF. | |
310 // Readdir returns the array and an Error, if any. | |
311 func (file *File) Readdir(count int) (fi []FileInfo, err Error) { | |
312 dirname := file.name | |
313 if dirname == "" { | |
314 dirname = "." | |
315 } | |
316 dirname += "/" | |
317 names, err1 := file.Readdirnames(count) | |
318 if err1 != nil { | |
319 return nil, err1 | |
320 } | |
321 fi = make([]FileInfo, len(names)) | |
322 for i, filename := range names { | |
323 fip, err := Lstat(dirname + filename) | |
324 if fip == nil || err != nil { | |
325 fi[i].Name = filename // rest is already zeroed out | |
326 } else { | |
327 fi[i] = *fip | |
328 } | |
329 } | |
330 return | |
331 } | |
332 | |
333 // Chdir changes the current working directory to the named directory. | 263 // Chdir changes the current working directory to the named directory. |
334 func Chdir(dir string) Error { | 264 func Chdir(dir string) Error { |
335 if e := syscall.Chdir(dir); e != 0 { | 265 if e := syscall.Chdir(dir); e != 0 { |
336 return &PathError{"chdir", dir, Errno(e)} | 266 return &PathError{"chdir", dir, Errno(e)} |
337 } | 267 } |
338 return nil | 268 return nil |
339 } | 269 } |
340 | 270 |
341 // Chdir changes the current working directory to the file, | 271 // Chdir changes the current working directory to the file, |
342 // which must be a directory. | 272 // which must be a directory. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 } | 417 } |
488 | 418 |
489 // Truncate changes the size of the file. | 419 // Truncate changes the size of the file. |
490 // It does not change the I/O offset. | 420 // It does not change the I/O offset. |
491 func (f *File) Truncate(size int64) Error { | 421 func (f *File) Truncate(size int64) Error { |
492 if e := syscall.Ftruncate(f.fd, size); e != 0 { | 422 if e := syscall.Ftruncate(f.fd, size); e != 0 { |
493 return &PathError{"truncate", f.name, Errno(e)} | 423 return &PathError{"truncate", f.name, Errno(e)} |
494 } | 424 } |
495 return nil | 425 return nil |
496 } | 426 } |
OLD | NEW |