file.go 13.7 KB
Newer Older
Rob Pike's avatar
Rob Pike committed
1 2 3 4
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

5
// Package os provides a platform-independent interface to operating system
6 7 8 9
// functionality. The design is Unix-like, although the error handling is
// Go-like; failing calls return values of type error rather than error numbers.
// Often, more information is available within the error. For example,
// if a call that takes a file name fails, such as Open or Stat, the error
10 11
// will include the failing file name when printed and will be of type
// *PathError, which may be unpacked for more information.
12
//
13 14
// The os interface is intended to be uniform across all operating systems.
// Features not generally available appear in the system-specific package syscall.
15 16 17 18 19 20 21 22 23 24 25 26 27
//
// Here is a simple example, opening a file and reading some of it.
//
//	file, err := os.Open("file.go") // For read access.
//	if err != nil {
//		log.Fatal(err)
//	}
//
// If the open fails, the error string will be self-explanatory, like
//
//	open file.go: no such file or directory
//
// The file's data can then be read into a slice of bytes. Read and
Sanjay Menakuru's avatar
Sanjay Menakuru committed
28
// Write take their byte counts from the length of the argument slice.
29 30 31 32 33 34 35 36
//
//	data := make([]byte, 100)
//	count, err := file.Read(data)
//	if err != nil {
//		log.Fatal(err)
//	}
//	fmt.Printf("read %d bytes: %q\n", count, data[:count])
//
Rob Pike's avatar
Rob Pike committed
37 38
package os

39
import (
40
	"errors"
41
	"internal/poll"
42
	"internal/testlog"
Russ Cox's avatar
Russ Cox committed
43
	"io"
Andrew Bonventre's avatar
Andrew Bonventre committed
44
	"runtime"
45
	"syscall"
46
	"time"
47
)
Rob Pike's avatar
Rob Pike committed
48

Rob Pike's avatar
Rob Pike committed
49
// Name returns the name of the file as presented to Open.
50
func (f *File) Name() string { return f.name }
Rob Pike's avatar
Rob Pike committed
51

Russ Cox's avatar
Russ Cox committed
52
// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
Rob Pike's avatar
Rob Pike committed
53
// standard output, and standard error file descriptors.
54 55 56 57
//
// Note that the Go runtime writes to standard error for panics and crashes;
// closing Stderr may cause those messages to go elsewhere, perhaps
// to a file opened later.
Russ Cox's avatar
Russ Cox committed
58
var (
59 60 61
	Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
	Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
	Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
Rob Pike's avatar
Rob Pike committed
62 63
)

64
// Flags to OpenFile wrapping those of the underlying system. Not all
65
// flags may be implemented on a given system.
Russ Cox's avatar
Russ Cox committed
66
const (
67
	// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
68 69 70
	O_RDONLY int = syscall.O_RDONLY // open the file read-only.
	O_WRONLY int = syscall.O_WRONLY // open the file write-only.
	O_RDWR   int = syscall.O_RDWR   // open the file read-write.
71
	// The remaining values may be or'ed in to control behavior.
72 73
	O_APPEND int = syscall.O_APPEND // append data to the file when writing.
	O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
74
	O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist.
75 76
	O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
	O_TRUNC  int = syscall.O_TRUNC  // if possible, truncate file when opened.
Rob Pike's avatar
Rob Pike committed
77 78
)

79
// Seek whence values.
80 81
//
// Deprecated: Use io.SeekStart, io.SeekCurrent, and io.SeekEnd.
82 83 84 85 86 87
const (
	SEEK_SET int = 0 // seek relative to the origin of the file
	SEEK_CUR int = 1 // seek relative to the current offset
	SEEK_END int = 2 // seek relative to the end
)

Fazlul Shahriar's avatar
Fazlul Shahriar committed
88 89 90 91 92 93 94 95 96 97 98 99 100
// LinkError records an error during a link or symlink or rename
// system call and the paths that caused it.
type LinkError struct {
	Op  string
	Old string
	New string
	Err error
}

func (e *LinkError) Error() string {
	return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error()
}

Russ Cox's avatar
Russ Cox committed
101
// Read reads up to len(b) bytes from the File.
Russ Cox's avatar
Russ Cox committed
102 103
// It returns the number of bytes read and any error encountered.
// At end of file, Read returns 0, io.EOF.
104
func (f *File) Read(b []byte) (n int, err error) {
105 106
	if err := f.checkValid("read"); err != nil {
		return 0, err
Rob Pike's avatar
Rob Pike committed
107
	}
108
	n, e := f.read(b)
109
	return n, f.wrapErr("read", e)
Rob Pike's avatar
Rob Pike committed
110 111
}

Russ Cox's avatar
Russ Cox committed
112
// ReadAt reads len(b) bytes from the File starting at byte offset off.
Russ Cox's avatar
Russ Cox committed
113
// It returns the number of bytes read and the error, if any.
Russ Cox's avatar
Russ Cox committed
114 115
// ReadAt always returns a non-nil error when n < len(b).
// At end of file, that error is io.EOF.
116
func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
117 118
	if err := f.checkValid("read"); err != nil {
		return 0, err
Russ Cox's avatar
Russ Cox committed
119
	}
120 121 122 123 124

	if off < 0 {
		return 0, &PathError{"readat", f.name, errors.New("negative offset")}
	}

Russ Cox's avatar
Russ Cox committed
125
	for len(b) > 0 {
126
		m, e := f.pread(b, off)
Russ Cox's avatar
Russ Cox committed
127
		if e != nil {
128
			err = f.wrapErr("read", e)
129
			break
Russ Cox's avatar
Russ Cox committed
130
		}
131 132 133
		n += m
		b = b[m:]
		off += int64(m)
Russ Cox's avatar
Russ Cox committed
134
	}
135
	return
Russ Cox's avatar
Russ Cox committed
136 137
}

Russ Cox's avatar
Russ Cox committed
138
// Write writes len(b) bytes to the File.
Russ Cox's avatar
Russ Cox committed
139 140
// It returns the number of bytes written and an error, if any.
// Write returns a non-nil error when n != len(b).
141
func (f *File) Write(b []byte) (n int, err error) {
142 143
	if err := f.checkValid("write"); err != nil {
		return 0, err
Rob Pike's avatar
Rob Pike committed
144
	}
145
	n, e := f.write(b)
146
	if n < 0 {
147
		n = 0
148
	}
Shenghou Ma's avatar
Shenghou Ma committed
149 150 151
	if n != len(b) {
		err = io.ErrShortWrite
	}
Yuval Pavel Zholkover's avatar
Yuval Pavel Zholkover committed
152

153
	epipecheck(f, e)
Yuval Pavel Zholkover's avatar
Yuval Pavel Zholkover committed
154

155 156 157 158 159
	if e != nil {
		err = f.wrapErr("write", e)
	}

	return n, err
Rob Pike's avatar
Rob Pike committed
160 161
}

Russ Cox's avatar
Russ Cox committed
162
// WriteAt writes len(b) bytes to the File starting at byte offset off.
Russ Cox's avatar
Russ Cox committed
163 164
// It returns the number of bytes written and an error, if any.
// WriteAt returns a non-nil error when n != len(b).
165
func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
166 167
	if err := f.checkValid("write"); err != nil {
		return 0, err
Russ Cox's avatar
Russ Cox committed
168
	}
169 170 171 172 173

	if off < 0 {
		return 0, &PathError{"writeat", f.name, errors.New("negative offset")}
	}

Russ Cox's avatar
Russ Cox committed
174
	for len(b) > 0 {
175
		m, e := f.pwrite(b, off)
Russ Cox's avatar
Russ Cox committed
176
		if e != nil {
177
			err = f.wrapErr("write", e)
178
			break
Russ Cox's avatar
Russ Cox committed
179
		}
180 181 182
		n += m
		b = b[m:]
		off += int64(m)
Russ Cox's avatar
Russ Cox committed
183
	}
184
	return
Russ Cox's avatar
Russ Cox committed
185 186
}

Russ Cox's avatar
Russ Cox committed
187
// Seek sets the offset for the next Read or Write on file to offset, interpreted
Rob Pike's avatar
Rob Pike committed
188 189
// according to whence: 0 means relative to the origin of the file, 1 means
// relative to the current offset, and 2 means relative to the end.
Russ Cox's avatar
Russ Cox committed
190
// It returns the new offset and an error, if any.
191
// The behavior of Seek on a file opened with O_APPEND is not specified.
192
func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
193 194
	if err := f.checkValid("seek"); err != nil {
		return 0, err
195
	}
196 197
	r, e := f.seek(offset, whence)
	if e == nil && f.dirinfo != nil && r != 0 {
198
		e = syscall.EISDIR
199
	}
Russ Cox's avatar
Russ Cox committed
200
	if e != nil {
201
		return 0, f.wrapErr("seek", e)
202
	}
203
	return r, nil
204 205
}

Rob Pike's avatar
Rob Pike committed
206
// WriteString is like Write, but writes the contents of string s rather than
207
// a slice of bytes.
208
func (f *File) WriteString(s string) (n int, err error) {
209
	return f.Write([]byte(s))
Rob Pike's avatar
Rob Pike committed
210
}
Russ Cox's avatar
Russ Cox committed
211

212 213
// Mkdir creates a new directory with the specified name and permission
// bits (before umask).
214
// If there is an error, it will be of type *PathError.
215
func Mkdir(name string, perm FileMode) error {
216
	e := syscall.Mkdir(fixLongPath(name), syscallMode(perm))
217

Russ Cox's avatar
Russ Cox committed
218 219
	if e != nil {
		return &PathError{"mkdir", name, e}
Russ Cox's avatar
Russ Cox committed
220
	}
221 222 223

	// mkdir(2) itself won't handle the sticky bit on *BSD and Solaris
	if !supportsCreateWithStickyBit && perm&ModeSticky != 0 {
224
		setStickyBit(name)
225 226
	}

227
	return nil
Cary Hull's avatar
Cary Hull committed
228
}
Rob Pike's avatar
Rob Pike committed
229

230 231 232 233 234 235 236 237 238
// setStickyBit adds ModeSticky to the permision bits of path, non atomic.
func setStickyBit(name string) error {
	fi, err := Stat(name)
	if err != nil {
		return err
	}
	return Chmod(name, fi.Mode()|ModeSticky)
}

Russ Cox's avatar
Chdir  
Russ Cox committed
239
// Chdir changes the current working directory to the named directory.
240
// If there is an error, it will be of type *PathError.
Russ Cox's avatar
Russ Cox committed
241
func Chdir(dir string) error {
Russ Cox's avatar
Russ Cox committed
242
	if e := syscall.Chdir(dir); e != nil {
243
		testlog.Open(dir) // observe likely non-existent directory
Russ Cox's avatar
Russ Cox committed
244
		return &PathError{"chdir", dir, e}
Russ Cox's avatar
Russ Cox committed
245
	}
246 247 248 249 250 251
	if log := testlog.Logger(); log != nil {
		wd, err := Getwd()
		if err == nil {
			log.Chdir(wd)
		}
	}
252
	return nil
Russ Cox's avatar
Chdir  
Russ Cox committed
253 254
}

255
// Open opens the named file for reading. If successful, methods on
Rob Pike's avatar
Rob Pike committed
256 257
// the returned file can be used for reading; the associated file
// descriptor has mode O_RDONLY.
258
// If there is an error, it will be of type *PathError.
259
func Open(name string) (*File, error) {
Rob Pike's avatar
Rob Pike committed
260 261 262
	return OpenFile(name, O_RDONLY, 0)
}

263 264
// Create creates the named file with mode 0666 (before umask), truncating
// it if it already exists. If successful, methods on the returned
Rob Pike's avatar
Rob Pike committed
265 266
// File can be used for I/O; the associated file descriptor has mode
// O_RDWR.
267
// If there is an error, it will be of type *PathError.
268
func Create(name string) (*File, error) {
Rob Pike's avatar
Rob Pike committed
269 270
	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}
271

272 273
// OpenFile is the generalized open call; most users will use Open
// or Create instead. It opens the named file with specified flag
274
// (O_RDONLY etc.) and perm (before umask), if applicable. If successful,
275 276 277 278 279 280 281
// methods on the returned File can be used for I/O.
// If there is an error, it will be of type *PathError.
func OpenFile(name string, flag int, perm FileMode) (*File, error) {
	testlog.Open(name)
	return openFileNolog(name, flag, perm)
}

282 283
// lstat is overridden in tests.
var lstat = Lstat
Shenghou Ma's avatar
Shenghou Ma committed
284

285
// Rename renames (moves) oldpath to newpath.
286
// If newpath already exists and is not a directory, Rename replaces it.
287
// OS-specific restrictions may apply when oldpath and newpath are in different directories.
288
// If there is an error, it will be of type *LinkError.
Shenghou Ma's avatar
Shenghou Ma committed
289 290 291
func Rename(oldpath, newpath string) error {
	return rename(oldpath, newpath)
}
292 293 294 295 296 297 298 299 300

// Many functions in package syscall return a count of -1 instead of 0.
// Using fixCount(call()) instead of call() corrects the count.
func fixCount(n int, err error) (int, error) {
	if n < 0 {
		n = 0
	}
	return n, err
}
301 302 303 304 305 306 307 308 309 310 311 312 313

// wrapErr wraps an error that occurred during an operation on an open file.
// It passes io.EOF through unchanged, otherwise converts
// poll.ErrFileClosing to ErrClosed and wraps the error in a PathError.
func (f *File) wrapErr(op string, err error) error {
	if err == nil || err == io.EOF {
		return err
	}
	if err == poll.ErrFileClosing {
		err = ErrClosed
	}
	return &PathError{op, f.name, err}
}
314 315 316 317 318 319 320 321 322 323 324 325 326

// TempDir returns the default directory to use for temporary files.
//
// On Unix systems, it returns $TMPDIR if non-empty, else /tmp.
// On Windows, it uses GetTempPath, returning the first non-empty
// value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory.
// On Plan 9, it returns /tmp.
//
// The directory is neither guaranteed to exist nor have accessible
// permissions.
func TempDir() string {
	return tempDir()
}
327

Andrew Bonventre's avatar
Andrew Bonventre committed
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
// UserCacheDir returns the default root directory to use for user-specific
// cached data. Users should create their own application-specific subdirectory
// within this one and use that.
//
// On Unix systems, it returns $XDG_CACHE_HOME as specified by
// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html if
// non-empty, else $HOME/.cache.
// On Darwin, it returns $HOME/Library/Caches.
// On Windows, it returns %LocalAppData%.
// On Plan 9, it returns $home/lib/cache.
//
// If the location cannot be determined (for example, $HOME is not defined),
// then it will return an empty string.
func UserCacheDir() string {
	var dir string

	switch runtime.GOOS {
	case "windows":
		dir = Getenv("LocalAppData")

	case "darwin":
		dir = Getenv("HOME")
		if dir == "" {
			return ""
		}
		dir += "/Library/Caches"

	case "plan9":
		dir = Getenv("home")
		if dir == "" {
			return ""
		}
		dir += "/lib/cache"

	default: // Unix
		dir = Getenv("XDG_CACHE_HOME")
		if dir == "" {
			dir = Getenv("HOME")
			if dir == "" {
				return ""
			}
			dir += "/.cache"
		}
	}

	return dir
}

376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
// Chmod changes the mode of the named file to mode.
// If the file is a symbolic link, it changes the mode of the link's target.
// If there is an error, it will be of type *PathError.
//
// A different subset of the mode bits are used, depending on the
// operating system.
//
// On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
// ModeSticky are used.
//
// On Windows, the mode must be non-zero but otherwise only the 0200
// bit (owner writable) of mode is used; it controls whether the
// file's read-only attribute is set or cleared. attribute. The other
// bits are currently unused. Use mode 0400 for a read-only file and
// 0600 for a readable+writable file.
//
// On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
// and ModeTemporary are used.
func Chmod(name string, mode FileMode) error { return chmod(name, mode) }

// Chmod changes the mode of the file to mode.
// If there is an error, it will be of type *PathError.
func (f *File) Chmod(mode FileMode) error { return f.chmod(mode) }
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442

// SetDeadline sets the read and write deadlines for a File.
// It is equivalent to calling both SetReadDeadline and SetWriteDeadline.
//
// Only some kinds of files support setting a deadline. Calls to SetDeadline
// for files that do not support deadlines will return ErrNoDeadline.
// On most systems ordinary files do not support deadlines, but pipes do.
//
// A deadline is an absolute time after which I/O operations fail with an
// error instead of blocking. The deadline applies to all future and pending
// I/O, not just the immediately following call to Read or Write.
// After a deadline has been exceeded, the connection can be refreshed
// by setting a deadline in the future.
//
// An error returned after a timeout fails will implement the
// Timeout method, and calling the Timeout method will return true.
// The PathError and SyscallError types implement the Timeout method.
// In general, call IsTimeout to test whether an error indicates a timeout.
//
// An idle timeout can be implemented by repeatedly extending
// the deadline after successful Read or Write calls.
//
// A zero value for t means I/O operations will not time out.
func (f *File) SetDeadline(t time.Time) error {
	return f.setDeadline(t)
}

// SetReadDeadline sets the deadline for future Read calls and any
// currently-blocked Read call.
// A zero value for t means Read will not time out.
// Not all files support setting deadlines; see SetDeadline.
func (f *File) SetReadDeadline(t time.Time) error {
	return f.setReadDeadline(t)
}

// SetWriteDeadline sets the deadline for any future Write calls and any
// currently-blocked Write call.
// Even if Write times out, it may return n > 0, indicating that
// some of the data was successfully written.
// A zero value for t means Write will not time out.
// Not all files support setting deadlines; see SetDeadline.
func (f *File) SetWriteDeadline(t time.Time) error {
	return f.setWriteDeadline(t)
}