OSDN Git Service

libgo: Update to current Go library.
[pf3gnuchains/gcc-fork.git] / libgo / go / os / file.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // The os package provides a platform-independent interface to operating
6 // system functionality.  The design is Unix-like.
7 package os
8
9 import (
10         "runtime"
11         "syscall"
12 )
13
14 // File represents an open file descriptor.
15 type File struct {
16         fd      int
17         name    string
18         dirinfo *dirInfo // nil unless directory being read
19         nepipe  int      // number of consecutive EPIPE in Write
20 }
21
22 // Fd returns the integer Unix file descriptor referencing the open file.
23 func (file *File) Fd() int { return file.fd }
24
25 // Name returns the name of the file as presented to Open.
26 func (file *File) Name() string { return file.name }
27
28 // NewFile returns a new File with the given file descriptor and name.
29 func NewFile(fd int, name string) *File {
30         if fd < 0 {
31                 return nil
32         }
33         f := &File{fd, name, nil, 0}
34         runtime.SetFinalizer(f, (*File).Close)
35         return f
36 }
37
38 // Stdin, Stdout, and Stderr are open Files pointing to the standard input,
39 // standard output, and standard error file descriptors.
40 var (
41         Stdin  = NewFile(syscall.Stdin, "/dev/stdin")
42         Stdout = NewFile(syscall.Stdout, "/dev/stdout")
43         Stderr = NewFile(syscall.Stderr, "/dev/stderr")
44 )
45
46 // Flags to Open wrapping those of the underlying system. Not all flags
47 // may be implemented on a given system.
48 const (
49         O_RDONLY   int = syscall.O_RDONLY   // open the file read-only.
50         O_WRONLY   int = syscall.O_WRONLY   // open the file write-only.
51         O_RDWR     int = syscall.O_RDWR     // open the file read-write.
52         O_APPEND   int = syscall.O_APPEND   // append data to the file when writing.
53         O_ASYNC    int = syscall.O_ASYNC    // generate a signal when I/O is available.
54         O_CREATE   int = syscall.O_CREAT    // create a new file if none exists.
55         O_EXCL     int = syscall.O_EXCL     // used with O_CREATE, file must not exist
56         O_NOCTTY   int = syscall.O_NOCTTY   // do not make file the controlling tty.
57         O_NONBLOCK int = syscall.O_NONBLOCK // open in non-blocking mode.
58         O_NDELAY   int = O_NONBLOCK         // synonym for O_NONBLOCK
59         O_SYNC     int = syscall.O_SYNC     // open for synchronous I/O.
60         O_TRUNC    int = syscall.O_TRUNC    // if possible, truncate file when opened.
61 )
62
63 // Seek whence values.
64 const (
65         SEEK_SET int = 0 // seek relative to the origin of the file
66         SEEK_CUR int = 1 // seek relative to the current offset
67         SEEK_END int = 2 // seek relative to the end
68 )
69
70 type eofError int
71
72 func (eofError) String() string { return "EOF" }
73
74 // EOF is the Error returned by Read when no more input is available.
75 // Functions should return EOF only to signal a graceful end of input.
76 // If the EOF occurs unexpectedly in a structured data stream,
77 // the appropriate error is either io.ErrUnexpectedEOF or some other error
78 // giving more detail.
79 var EOF Error = eofError(0)
80
81 // Read reads up to len(b) bytes from the File.
82 // It returns the number of bytes read and an Error, if any.
83 // EOF is signaled by a zero count with err set to EOF.
84 func (file *File) Read(b []byte) (n int, err Error) {
85         if file == nil {
86                 return 0, EINVAL
87         }
88         n, e := syscall.Read(file.fd, b)
89         if n < 0 {
90                 n = 0
91         }
92         if n == 0 && !iserror(e) {
93                 return 0, EOF
94         }
95         if iserror(e) {
96                 err = &PathError{"read", file.name, Errno(e)}
97         }
98         return n, err
99 }
100
101 // ReadAt reads len(b) bytes from the File starting at byte offset off.
102 // It returns the number of bytes read and the Error, if any.
103 // EOF is signaled by a zero count with err set to EOF.
104 // ReadAt always returns a non-nil Error when n != len(b).
105 func (file *File) ReadAt(b []byte, off int64) (n int, err Error) {
106         if file == nil {
107                 return 0, EINVAL
108         }
109         for len(b) > 0 {
110                 m, e := syscall.Pread(file.fd, b, off)
111                 if m == 0 && !iserror(e) {
112                         return n, EOF
113                 }
114                 if iserror(e) {
115                         err = &PathError{"read", file.name, Errno(e)}
116                         break
117                 }
118                 n += m
119                 b = b[m:]
120                 off += int64(m)
121         }
122         return
123 }
124
125 // Write writes len(b) bytes to the File.
126 // It returns the number of bytes written and an Error, if any.
127 // Write returns a non-nil Error when n != len(b).
128 func (file *File) Write(b []byte) (n int, err Error) {
129         if file == nil {
130                 return 0, EINVAL
131         }
132         n, e := syscall.Write(file.fd, b)
133         if n < 0 {
134                 n = 0
135         }
136
137         epipecheck(file, e)
138
139         if iserror(e) {
140                 err = &PathError{"write", file.name, Errno(e)}
141         }
142         return n, err
143 }
144
145 // WriteAt writes len(b) bytes to the File starting at byte offset off.
146 // It returns the number of bytes written and an Error, if any.
147 // WriteAt returns a non-nil Error when n != len(b).
148 func (file *File) WriteAt(b []byte, off int64) (n int, err Error) {
149         if file == nil {
150                 return 0, EINVAL
151         }
152         for len(b) > 0 {
153                 m, e := syscall.Pwrite(file.fd, b, off)
154                 if iserror(e) {
155                         err = &PathError{"write", file.name, Errno(e)}
156                         break
157                 }
158                 n += m
159                 b = b[m:]
160                 off += int64(m)
161         }
162         return
163 }
164
165 // Seek sets the offset for the next Read or Write on file to offset, interpreted
166 // according to whence: 0 means relative to the origin of the file, 1 means
167 // relative to the current offset, and 2 means relative to the end.
168 // It returns the new offset and an Error, if any.
169 func (file *File) Seek(offset int64, whence int) (ret int64, err Error) {
170         r, e := syscall.Seek(file.fd, offset, whence)
171         if !iserror(e) && file.dirinfo != nil && r != 0 {
172                 e = syscall.EISDIR
173         }
174         if iserror(e) {
175                 return 0, &PathError{"seek", file.name, Errno(e)}
176         }
177         return r, nil
178 }
179
180 // WriteString is like Write, but writes the contents of string s rather than
181 // an array of bytes.
182 func (file *File) WriteString(s string) (ret int, err Error) {
183         if file == nil {
184                 return 0, EINVAL
185         }
186         b := syscall.StringByteSlice(s)
187         b = b[0 : len(b)-1]
188         return file.Write(b)
189 }
190
191 // Mkdir creates a new directory with the specified name and permission bits.
192 // It returns an error, if any.
193 func Mkdir(name string, perm uint32) Error {
194         e := syscall.Mkdir(name, perm)
195         if iserror(e) {
196                 return &PathError{"mkdir", name, Errno(e)}
197         }
198         return nil
199 }
200
201 // Chdir changes the current working directory to the named directory.
202 func Chdir(dir string) Error {
203         if e := syscall.Chdir(dir); iserror(e) {
204                 return &PathError{"chdir", dir, Errno(e)}
205         }
206         return nil
207 }
208
209 // Chdir changes the current working directory to the file,
210 // which must be a directory.
211 func (f *File) Chdir() Error {
212         if e := syscall.Fchdir(f.fd); iserror(e) {
213                 return &PathError{"chdir", f.name, Errno(e)}
214         }
215         return nil
216 }
217
218 // Open opens the named file for reading.  If successful, methods on
219 // the returned file can be used for reading; the associated file
220 // descriptor has mode O_RDONLY.
221 // It returns the File and an Error, if any.
222 func Open(name string) (file *File, err Error) {
223         return OpenFile(name, O_RDONLY, 0)
224 }
225
226 // Create creates the named file mode 0666 (before umask), truncating
227 // it if it already exists.  If successful, methods on the returned
228 // File can be used for I/O; the associated file descriptor has mode
229 // O_RDWR.
230 // It returns the File and an Error, if any.
231 func Create(name string) (file *File, err Error) {
232         return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
233 }