file.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  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. // Package os provides a platform-independent interface to operating system
  5. // functionality. The design is Unix-like, although the error handling is
  6. // Go-like; failing calls return values of type error rather than error numbers.
  7. // Often, more information is available within the error. For example,
  8. // if a call that takes a file name fails, such as Open or Stat, the error
  9. // will include the failing file name when printed and will be of type
  10. // *PathError, which may be unpacked for more information.
  11. //
  12. // The os interface is intended to be uniform across all operating systems.
  13. // Features not generally available appear in the system-specific package syscall.
  14. //
  15. // Here is a simple example, opening a file and reading some of it.
  16. //
  17. // file, err := os.Open("file.go") // For read access.
  18. // if err != nil {
  19. // log.Fatal(err)
  20. // }
  21. //
  22. // If the open fails, the error string will be self-explanatory, like
  23. //
  24. // open file.go: no such file or directory
  25. //
  26. // The file's data can then be read into a slice of bytes. Read and
  27. // Write take their byte counts from the length of the argument slice.
  28. //
  29. // data := make([]byte, 100)
  30. // count, err := file.Read(data)
  31. // if err != nil {
  32. // log.Fatal(err)
  33. // }
  34. // fmt.Printf("read %d bytes: %q\n", count, data[:count])
  35. //
  36. package os
  37. import (
  38. "io"
  39. "syscall"
  40. )
  41. // Name returns the name of the file as presented to Open.
  42. func (f *File) Name() string { return f.name }
  43. // Stdin, Stdout, and Stderr are open Files pointing to the standard input,
  44. // standard output, and standard error file descriptors.
  45. var (
  46. Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
  47. Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
  48. Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
  49. )
  50. // Flags to Open wrapping those of the underlying system. Not all flags
  51. // may be implemented on a given system.
  52. const (
  53. O_RDONLY int = syscall.O_RDONLY // open the file read-only.
  54. O_WRONLY int = syscall.O_WRONLY // open the file write-only.
  55. O_RDWR int = syscall.O_RDWR // open the file read-write.
  56. O_APPEND int = syscall.O_APPEND // append data to the file when writing.
  57. O_CREATE int = syscall.O_CREAT // create a new file if none exists.
  58. O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
  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. // Seek whence values.
  63. const (
  64. SEEK_SET int = 0 // seek relative to the origin of the file
  65. SEEK_CUR int = 1 // seek relative to the current offset
  66. SEEK_END int = 2 // seek relative to the end
  67. )
  68. // LinkError records an error during a link or symlink or rename
  69. // system call and the paths that caused it.
  70. type LinkError struct {
  71. Op string
  72. Old string
  73. New string
  74. Err error
  75. }
  76. func (e *LinkError) Error() string {
  77. return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error()
  78. }
  79. // Read reads up to len(b) bytes from the File.
  80. // It returns the number of bytes read and an error, if any.
  81. // EOF is signaled by a zero count with err set to io.EOF.
  82. func (f *File) Read(b []byte) (n int, err error) {
  83. if f == nil {
  84. return 0, ErrInvalid
  85. }
  86. n, e := f.read(b)
  87. if n < 0 {
  88. n = 0
  89. }
  90. if n == 0 && len(b) > 0 && e == nil {
  91. return 0, io.EOF
  92. }
  93. if e != nil {
  94. err = &PathError{"read", f.name, e}
  95. }
  96. return n, err
  97. }
  98. // ReadAt reads len(b) bytes from the File starting at byte offset off.
  99. // It returns the number of bytes read and the error, if any.
  100. // ReadAt always returns a non-nil error when n < len(b).
  101. // At end of file, that error is io.EOF.
  102. func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
  103. if f == nil {
  104. return 0, ErrInvalid
  105. }
  106. for len(b) > 0 {
  107. m, e := f.pread(b, off)
  108. if m == 0 && e == nil {
  109. return n, io.EOF
  110. }
  111. if e != nil {
  112. err = &PathError{"read", f.name, e}
  113. break
  114. }
  115. n += m
  116. b = b[m:]
  117. off += int64(m)
  118. }
  119. return
  120. }
  121. // Write writes len(b) bytes to the File.
  122. // It returns the number of bytes written and an error, if any.
  123. // Write returns a non-nil error when n != len(b).
  124. func (f *File) Write(b []byte) (n int, err error) {
  125. if f == nil {
  126. return 0, ErrInvalid
  127. }
  128. n, e := f.write(b)
  129. if n < 0 {
  130. n = 0
  131. }
  132. if n != len(b) {
  133. err = io.ErrShortWrite
  134. }
  135. epipecheck(f, e)
  136. if e != nil {
  137. err = &PathError{"write", f.name, e}
  138. }
  139. return n, err
  140. }
  141. // WriteAt writes len(b) bytes to the File starting at byte offset off.
  142. // It returns the number of bytes written and an error, if any.
  143. // WriteAt returns a non-nil error when n != len(b).
  144. func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
  145. if f == nil {
  146. return 0, ErrInvalid
  147. }
  148. for len(b) > 0 {
  149. m, e := f.pwrite(b, off)
  150. if e != nil {
  151. err = &PathError{"write", f.name, e}
  152. break
  153. }
  154. n += m
  155. b = b[m:]
  156. off += int64(m)
  157. }
  158. return
  159. }
  160. // Seek sets the offset for the next Read or Write on file to offset, interpreted
  161. // according to whence: 0 means relative to the origin of the file, 1 means
  162. // relative to the current offset, and 2 means relative to the end.
  163. // It returns the new offset and an error, if any.
  164. func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
  165. if f == nil {
  166. return 0, ErrInvalid
  167. }
  168. r, e := f.seek(offset, whence)
  169. if e == nil && f.dirinfo != nil && r != 0 {
  170. e = syscall.EISDIR
  171. }
  172. if e != nil {
  173. return 0, &PathError{"seek", f.name, e}
  174. }
  175. return r, nil
  176. }
  177. // WriteString is like Write, but writes the contents of string s rather than
  178. // a slice of bytes.
  179. func (f *File) WriteString(s string) (ret int, err error) {
  180. if f == nil {
  181. return 0, ErrInvalid
  182. }
  183. return f.Write([]byte(s))
  184. }
  185. // Mkdir creates a new directory with the specified name and permission bits.
  186. // If there is an error, it will be of type *PathError.
  187. func Mkdir(name string, perm FileMode) error {
  188. e := syscall.Mkdir(name, syscallMode(perm))
  189. if e != nil {
  190. return &PathError{"mkdir", name, e}
  191. }
  192. return nil
  193. }
  194. // Chdir changes the current working directory to the named directory.
  195. // If there is an error, it will be of type *PathError.
  196. func Chdir(dir string) error {
  197. if e := syscall.Chdir(dir); e != nil {
  198. return &PathError{"chdir", dir, e}
  199. }
  200. return nil
  201. }
  202. // Chdir changes the current working directory to the file,
  203. // which must be a directory.
  204. // If there is an error, it will be of type *PathError.
  205. func (f *File) Chdir() error {
  206. if f == nil {
  207. return ErrInvalid
  208. }
  209. if e := syscall.Fchdir(f.fd); e != nil {
  210. return &PathError{"chdir", f.name, e}
  211. }
  212. return nil
  213. }
  214. // Open opens the named file for reading. If successful, methods on
  215. // the returned file can be used for reading; the associated file
  216. // descriptor has mode O_RDONLY.
  217. // If there is an error, it will be of type *PathError.
  218. func Open(name string) (file *File, err error) {
  219. return OpenFile(name, O_RDONLY, 0)
  220. }
  221. // Create creates the named file mode 0666 (before umask), truncating
  222. // it if it already exists. If successful, methods on the returned
  223. // File can be used for I/O; the associated file descriptor has mode
  224. // O_RDWR.
  225. // If there is an error, it will be of type *PathError.
  226. func Create(name string) (file *File, err error) {
  227. return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
  228. }
  229. // lstat is overridden in tests.
  230. var lstat = Lstat
  231. // Rename renames (moves) a file. OS-specific restrictions might apply.
  232. func Rename(oldpath, newpath string) error {
  233. return rename(oldpath, newpath)
  234. }
  235. // Many functions in package syscall return a count of -1 instead of 0.
  236. // Using fixCount(call()) instead of call() corrects the count.
  237. func fixCount(n int, err error) (int, error) {
  238. if n < 0 {
  239. n = 0
  240. }
  241. return n, err
  242. }