Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 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 | |
Nigel Tao | 6a186d3 | 2011-04-20 09:57:05 +1000 | [diff] [blame] | 5 | // Package os provides a platform-independent interface to operating system |
Rob Pike | be0f6fe | 2012-02-09 16:55:36 +1100 | [diff] [blame] | 6 | // functionality. The design is Unix-like, although the error handling is |
| 7 | // Go-like; failing calls return values of type error rather than error numbers. |
| 8 | // Often, more information is available within the error. For example, |
| 9 | // if a call that takes a file name fails, such as Open or Stat, the error |
Rob Pike | efb28b2 | 2012-02-17 14:30:25 +1100 | [diff] [blame] | 10 | // will include the failing file name when printed and will be of type |
| 11 | // *PathError, which may be unpacked for more information. |
Robert Griesemer | 465b9c3 | 2012-10-30 13:38:01 -0700 | [diff] [blame] | 12 | // |
Rob Pike | 34e0725 | 2011-06-14 11:49:33 +1000 | [diff] [blame] | 13 | // The os interface is intended to be uniform across all operating systems. |
| 14 | // Features not generally available appear in the system-specific package syscall. |
Rob Pike | efb28b2 | 2012-02-17 14:30:25 +1100 | [diff] [blame] | 15 | // |
| 16 | // Here is a simple example, opening a file and reading some of it. |
| 17 | // |
| 18 | // file, err := os.Open("file.go") // For read access. |
| 19 | // if err != nil { |
| 20 | // log.Fatal(err) |
| 21 | // } |
| 22 | // |
| 23 | // If the open fails, the error string will be self-explanatory, like |
| 24 | // |
| 25 | // open file.go: no such file or directory |
| 26 | // |
| 27 | // The file's data can then be read into a slice of bytes. Read and |
Sanjay Menakuru | 27e07a2 | 2012-02-24 22:42:16 +1100 | [diff] [blame] | 28 | // Write take their byte counts from the length of the argument slice. |
Rob Pike | efb28b2 | 2012-02-17 14:30:25 +1100 | [diff] [blame] | 29 | // |
| 30 | // data := make([]byte, 100) |
| 31 | // count, err := file.Read(data) |
| 32 | // if err != nil { |
| 33 | // log.Fatal(err) |
| 34 | // } |
| 35 | // fmt.Printf("read %d bytes: %q\n", count, data[:count]) |
| 36 | // |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 37 | package os |
| 38 | |
Russ Cox | 91ceda5 | 2009-02-15 19:35:52 -0800 | [diff] [blame] | 39 | import ( |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 40 | "io" |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 41 | "syscall" |
Russ Cox | 91ceda5 | 2009-02-15 19:35:52 -0800 | [diff] [blame] | 42 | ) |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 43 | |
Rob Pike | 333cdd8 | 2009-03-07 16:56:44 -0800 | [diff] [blame] | 44 | // Name returns the name of the file as presented to Open. |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 45 | func (f *File) Name() string { return f.name } |
Rob Pike | 704bc9d | 2009-02-06 17:54:26 -0800 | [diff] [blame] | 46 | |
Russ Cox | 7a706fb | 2009-03-11 12:51:10 -0700 | [diff] [blame] | 47 | // Stdin, Stdout, and Stderr are open Files pointing to the standard input, |
Rob Pike | 333cdd8 | 2009-03-07 16:56:44 -0800 | [diff] [blame] | 48 | // standard output, and standard error file descriptors. |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 49 | var ( |
Brad Fitzpatrick | 4152b43 | 2012-02-10 14:16:15 +1100 | [diff] [blame] | 50 | Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin") |
| 51 | Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout") |
| 52 | Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr") |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 53 | ) |
| 54 | |
Rob Pike | 333cdd8 | 2009-03-07 16:56:44 -0800 | [diff] [blame] | 55 | // Flags to Open wrapping those of the underlying system. Not all flags |
| 56 | // may be implemented on a given system. |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 57 | const ( |
Brad Fitzpatrick | 4152b43 | 2012-02-10 14:16:15 +1100 | [diff] [blame] | 58 | O_RDONLY int = syscall.O_RDONLY // open the file read-only. |
| 59 | O_WRONLY int = syscall.O_WRONLY // open the file write-only. |
| 60 | O_RDWR int = syscall.O_RDWR // open the file read-write. |
| 61 | O_APPEND int = syscall.O_APPEND // append data to the file when writing. |
| 62 | O_CREATE int = syscall.O_CREAT // create a new file if none exists. |
| 63 | O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist |
| 64 | O_SYNC int = syscall.O_SYNC // open for synchronous I/O. |
| 65 | O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened. |
Rob Pike | 5ea7649 | 2008-09-11 15:09:10 -0700 | [diff] [blame] | 66 | ) |
| 67 | |
Brad Fitzpatrick | 2be13a8 | 2011-04-04 13:53:52 -0700 | [diff] [blame] | 68 | // Seek whence values. |
| 69 | const ( |
| 70 | SEEK_SET int = 0 // seek relative to the origin of the file |
| 71 | SEEK_CUR int = 1 // seek relative to the current offset |
| 72 | SEEK_END int = 2 // seek relative to the end |
| 73 | ) |
| 74 | |
Fazlul Shahriar | 441538e | 2012-02-20 12:31:24 +1100 | [diff] [blame] | 75 | // LinkError records an error during a link or symlink or rename |
| 76 | // system call and the paths that caused it. |
| 77 | type LinkError struct { |
| 78 | Op string |
| 79 | Old string |
| 80 | New string |
| 81 | Err error |
| 82 | } |
| 83 | |
| 84 | func (e *LinkError) Error() string { |
| 85 | return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error() |
| 86 | } |
| 87 | |
Russ Cox | 7a706fb | 2009-03-11 12:51:10 -0700 | [diff] [blame] | 88 | // Read reads up to len(b) bytes from the File. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 89 | // It returns the number of bytes read and an error, if any. |
| 90 | // EOF is signaled by a zero count with err set to io.EOF. |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 91 | func (f *File) Read(b []byte) (n int, err error) { |
| 92 | if f == nil { |
Rob Pike | 56069f0 | 2012-02-17 10:04:29 +1100 | [diff] [blame] | 93 | return 0, ErrInvalid |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 94 | } |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 95 | n, e := f.read(b) |
Russ Cox | 9e0fec9 | 2009-06-01 22:14:39 -0700 | [diff] [blame] | 96 | if n < 0 { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 97 | n = 0 |
Robert Griesemer | 23c8faa | 2008-11-14 15:13:29 -0800 | [diff] [blame] | 98 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 99 | if n == 0 && len(b) > 0 && e == nil { |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 100 | return 0, io.EOF |
Russ Cox | 64684cc | 2009-06-22 13:26:13 -0700 | [diff] [blame] | 101 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 102 | if e != nil { |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 103 | err = &PathError{"read", f.name, e} |
Russ Cox | a0bcaf4 | 2009-06-25 20:24:55 -0700 | [diff] [blame] | 104 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 105 | return n, err |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 106 | } |
| 107 | |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 108 | // ReadAt reads len(b) bytes from the File starting at byte offset off. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 109 | // It returns the number of bytes read and the error, if any. |
Russ Cox | c69d634 | 2011-11-22 12:22:28 -0500 | [diff] [blame] | 110 | // ReadAt always returns a non-nil error when n < len(b). |
| 111 | // At end of file, that error is io.EOF. |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 112 | func (f *File) ReadAt(b []byte, off int64) (n int, err error) { |
| 113 | if f == nil { |
Rob Pike | 56069f0 | 2012-02-17 10:04:29 +1100 | [diff] [blame] | 114 | return 0, ErrInvalid |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 115 | } |
| 116 | for len(b) > 0 { |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 117 | m, e := f.pread(b, off) |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 118 | if m == 0 && e == nil { |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 119 | return n, io.EOF |
Rob Pike | 4e201c7 | 2009-11-19 11:51:23 -0800 | [diff] [blame] | 120 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 121 | if e != nil { |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 122 | err = &PathError{"read", f.name, e} |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 123 | break |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 124 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 125 | n += m |
| 126 | b = b[m:] |
| 127 | off += int64(m) |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 128 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 129 | return |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 130 | } |
| 131 | |
Russ Cox | 7a706fb | 2009-03-11 12:51:10 -0700 | [diff] [blame] | 132 | // Write writes len(b) bytes to the File. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 133 | // It returns the number of bytes written and an error, if any. |
| 134 | // Write returns a non-nil error when n != len(b). |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 135 | func (f *File) Write(b []byte) (n int, err error) { |
| 136 | if f == nil { |
Rob Pike | 56069f0 | 2012-02-17 10:04:29 +1100 | [diff] [blame] | 137 | return 0, ErrInvalid |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 138 | } |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 139 | n, e := f.write(b) |
Russ Cox | 9e0fec9 | 2009-06-01 22:14:39 -0700 | [diff] [blame] | 140 | if n < 0 { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 141 | n = 0 |
Robert Griesemer | 23c8faa | 2008-11-14 15:13:29 -0800 | [diff] [blame] | 142 | } |
Shenghou Ma | aa0ae75 | 2013-12-09 23:25:13 -0500 | [diff] [blame] | 143 | if n != len(b) { |
| 144 | err = io.ErrShortWrite |
| 145 | } |
Yuval Pavel Zholkover | c256f0a | 2011-04-02 14:28:58 -0700 | [diff] [blame] | 146 | |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 147 | epipecheck(f, e) |
Yuval Pavel Zholkover | c256f0a | 2011-04-02 14:28:58 -0700 | [diff] [blame] | 148 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 149 | if e != nil { |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 150 | err = &PathError{"write", f.name, e} |
Russ Cox | a0bcaf4 | 2009-06-25 20:24:55 -0700 | [diff] [blame] | 151 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 152 | return n, err |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 153 | } |
| 154 | |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 155 | // WriteAt writes len(b) bytes to the File starting at byte offset off. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 156 | // It returns the number of bytes written and an error, if any. |
| 157 | // WriteAt returns a non-nil error when n != len(b). |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 158 | func (f *File) WriteAt(b []byte, off int64) (n int, err error) { |
| 159 | if f == nil { |
Rob Pike | 56069f0 | 2012-02-17 10:04:29 +1100 | [diff] [blame] | 160 | return 0, ErrInvalid |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 161 | } |
| 162 | for len(b) > 0 { |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 163 | m, e := f.pwrite(b, off) |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 164 | if e != nil { |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 165 | err = &PathError{"write", f.name, e} |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 166 | break |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 167 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 168 | n += m |
| 169 | b = b[m:] |
| 170 | off += int64(m) |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 171 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 172 | return |
Russ Cox | f7e92c5 | 2009-08-27 18:36:45 -0700 | [diff] [blame] | 173 | } |
| 174 | |
Russ Cox | 7a706fb | 2009-03-11 12:51:10 -0700 | [diff] [blame] | 175 | // Seek sets the offset for the next Read or Write on file to offset, interpreted |
Rob Pike | 333cdd8 | 2009-03-07 16:56:44 -0800 | [diff] [blame] | 176 | // according to whence: 0 means relative to the origin of the file, 1 means |
| 177 | // relative to the current offset, and 2 means relative to the end. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 178 | // It returns the new offset and an error, if any. |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 179 | func (f *File) Seek(offset int64, whence int) (ret int64, err error) { |
Rob Pike | 4cb086b | 2013-08-20 14:33:03 +1000 | [diff] [blame] | 180 | if f == nil { |
| 181 | return 0, ErrInvalid |
| 182 | } |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 183 | r, e := f.seek(offset, whence) |
| 184 | if e == nil && f.dirinfo != nil && r != 0 { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 185 | e = syscall.EISDIR |
Rob Pike | d94c5ab | 2009-02-10 11:27:45 -0800 | [diff] [blame] | 186 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 187 | if e != nil { |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 188 | return 0, &PathError{"seek", f.name, e} |
Rob Pike | d94c5ab | 2009-02-10 11:27:45 -0800 | [diff] [blame] | 189 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 190 | return r, nil |
Rob Pike | d94c5ab | 2009-02-10 11:27:45 -0800 | [diff] [blame] | 191 | } |
| 192 | |
Rob Pike | 333cdd8 | 2009-03-07 16:56:44 -0800 | [diff] [blame] | 193 | // WriteString is like Write, but writes the contents of string s rather than |
Nigel Tao | eb7d569 | 2012-10-22 16:26:47 +1100 | [diff] [blame] | 194 | // a slice of bytes. |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 195 | func (f *File) WriteString(s string) (ret int, err error) { |
| 196 | if f == nil { |
Rob Pike | 56069f0 | 2012-02-17 10:04:29 +1100 | [diff] [blame] | 197 | return 0, ErrInvalid |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 198 | } |
Brad Fitzpatrick | 744fb52 | 2011-12-01 11:23:39 -0800 | [diff] [blame] | 199 | return f.Write([]byte(s)) |
Rob Pike | c80b06a | 2008-09-11 13:03:46 -0700 | [diff] [blame] | 200 | } |
Russ Cox | 5267db3 | 2008-09-26 14:31:17 -0700 | [diff] [blame] | 201 | |
Rob Pike | 333cdd8 | 2009-03-07 16:56:44 -0800 | [diff] [blame] | 202 | // Mkdir creates a new directory with the specified name and permission bits. |
Rob Pike | be0f6fe | 2012-02-09 16:55:36 +1100 | [diff] [blame] | 203 | // If there is an error, it will be of type *PathError. |
Brad Fitzpatrick | 6454a3e | 2012-01-19 15:45:18 -0800 | [diff] [blame] | 204 | func Mkdir(name string, perm FileMode) error { |
| 205 | e := syscall.Mkdir(name, syscallMode(perm)) |
Kato Kazuyoshi | 6262902 | 2014-12-16 08:22:17 -0800 | [diff] [blame] | 206 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 207 | if e != nil { |
| 208 | return &PathError{"mkdir", name, e} |
Russ Cox | a0bcaf4 | 2009-06-25 20:24:55 -0700 | [diff] [blame] | 209 | } |
Kato Kazuyoshi | 9c0b145 | 2014-12-22 21:05:07 -0800 | [diff] [blame] | 210 | |
| 211 | // mkdir(2) itself won't handle the sticky bit on *BSD and Solaris |
| 212 | if !supportsCreateWithStickyBit && perm&ModeSticky != 0 { |
| 213 | Chmod(name, perm) |
| 214 | } |
| 215 | |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 216 | return nil |
Cary Hull | f960840 | 2008-10-09 00:15:37 -0700 | [diff] [blame] | 217 | } |
Rob Pike | 704bc9d | 2009-02-06 17:54:26 -0800 | [diff] [blame] | 218 | |
Russ Cox | 61ba160 | 2009-04-07 00:40:36 -0700 | [diff] [blame] | 219 | // Chdir changes the current working directory to the named directory. |
Rob Pike | be0f6fe | 2012-02-09 16:55:36 +1100 | [diff] [blame] | 220 | // If there is an error, it will be of type *PathError. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 221 | func Chdir(dir string) error { |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 222 | if e := syscall.Chdir(dir); e != nil { |
| 223 | return &PathError{"chdir", dir, e} |
Russ Cox | a0bcaf4 | 2009-06-25 20:24:55 -0700 | [diff] [blame] | 224 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 225 | return nil |
Russ Cox | 61ba160 | 2009-04-07 00:40:36 -0700 | [diff] [blame] | 226 | } |
| 227 | |
Russ Cox | 23c81f7 | 2009-05-18 10:49:34 -0700 | [diff] [blame] | 228 | // Chdir changes the current working directory to the file, |
| 229 | // which must be a directory. |
Rob Pike | be0f6fe | 2012-02-09 16:55:36 +1100 | [diff] [blame] | 230 | // If there is an error, it will be of type *PathError. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 231 | func (f *File) Chdir() error { |
Rob Pike | 4cb086b | 2013-08-20 14:33:03 +1000 | [diff] [blame] | 232 | if f == nil { |
| 233 | return ErrInvalid |
| 234 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 235 | if e := syscall.Fchdir(f.fd); e != nil { |
| 236 | return &PathError{"chdir", f.name, e} |
Russ Cox | a0bcaf4 | 2009-06-25 20:24:55 -0700 | [diff] [blame] | 237 | } |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 238 | return nil |
Russ Cox | 23c81f7 | 2009-05-18 10:49:34 -0700 | [diff] [blame] | 239 | } |
Rob Pike | 8a90fd3 | 2011-04-04 23:42:14 -0700 | [diff] [blame] | 240 | |
| 241 | // Open opens the named file for reading. If successful, methods on |
| 242 | // the returned file can be used for reading; the associated file |
| 243 | // descriptor has mode O_RDONLY. |
Rob Pike | be0f6fe | 2012-02-09 16:55:36 +1100 | [diff] [blame] | 244 | // If there is an error, it will be of type *PathError. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 245 | func Open(name string) (file *File, err error) { |
Rob Pike | 8a90fd3 | 2011-04-04 23:42:14 -0700 | [diff] [blame] | 246 | return OpenFile(name, O_RDONLY, 0) |
| 247 | } |
| 248 | |
| 249 | // Create creates the named file mode 0666 (before umask), truncating |
| 250 | // it if it already exists. If successful, methods on the returned |
| 251 | // File can be used for I/O; the associated file descriptor has mode |
| 252 | // O_RDWR. |
Rob Pike | be0f6fe | 2012-02-09 16:55:36 +1100 | [diff] [blame] | 253 | // If there is an error, it will be of type *PathError. |
Russ Cox | 08a073a | 2011-11-01 21:49:08 -0400 | [diff] [blame] | 254 | func Create(name string) (file *File, err error) { |
Rob Pike | 8a90fd3 | 2011-04-04 23:42:14 -0700 | [diff] [blame] | 255 | return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666) |
| 256 | } |
Brad Fitzpatrick | 8378804 | 2013-08-08 11:13:00 -0700 | [diff] [blame] | 257 | |
| 258 | // lstat is overridden in tests. |
| 259 | var lstat = Lstat |
Shenghou Ma | a4b66b7 | 2013-12-09 23:46:21 -0500 | [diff] [blame] | 260 | |
| 261 | // Rename renames (moves) a file. OS-specific restrictions might apply. |
| 262 | func Rename(oldpath, newpath string) error { |
| 263 | return rename(oldpath, newpath) |
| 264 | } |
Russ Cox | a62da20 | 2014-10-28 15:00:13 -0400 | [diff] [blame] | 265 | |
| 266 | // Many functions in package syscall return a count of -1 instead of 0. |
| 267 | // Using fixCount(call()) instead of call() corrects the count. |
| 268 | func fixCount(n int, err error) (int, error) { |
| 269 | if n < 0 { |
| 270 | n = 0 |
| 271 | } |
| 272 | return n, err |
| 273 | } |