2010-04-13 16:30:11 -07:00
|
|
|
// 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.
|
|
|
|
|
|
all: merge NaCl branch (part 1)
See golang.org/s/go13nacl for design overview.
This CL is the mostly mechanical changes from rsc's Go 1.2 based NaCl branch, specifically 39cb35750369 to 500771b477cf from https://code.google.com/r/rsc-go13nacl. This CL does not include working NaCl support, there are probably two or three more large merges to come.
CL 15750044 is not included as it involves more invasive changes to the linker which will need to be merged separately.
The exact change lists included are
15050047: syscall: support for Native Client
15360044: syscall: unzip implementation for Native Client
15370044: syscall: Native Client SRPC implementation
15400047: cmd/dist, cmd/go, go/build, test: support for Native Client
15410048: runtime: support for Native Client
15410049: syscall: file descriptor table for Native Client
15410050: syscall: in-memory file system for Native Client
15440048: all: update +build lines for Native Client port
15540045: cmd/6g, cmd/8g, cmd/gc: support for Native Client
15570045: os: support for Native Client
15680044: crypto/..., hash/crc32, reflect, sync/atomic: support for amd64p32
15690044: net: support for Native Client
15690048: runtime: support for fake time like on Go Playground
15690051: build: disable various tests on Native Client
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/68150047
2014-02-25 09:47:42 -05:00
|
|
|
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
|
build: add build comments to core packages
The go/build package already recognizes
system-specific file names like
mycode_darwin.go
mycode_darwin_386.go
mycode_386.s
However, it is also common to write files that
apply to multiple architectures, so a recent CL added
to go/build the ability to process comments
listing a set of conditions for building. For example:
// +build darwin freebsd openbsd/386
says that this file should be compiled only on
OS X, FreeBSD, or 32-bit x86 OpenBSD systems.
These conventions are not yet documented
(hence this long CL description).
This CL adds build comments to the multi-system
files in the core library, a step toward making it
possible to use go/build to build them.
With this change go/build can handle crypto/rand,
exec, net, path/filepath, os/user, and time.
os and syscall need additional adjustments.
R=golang-dev, r, gri, r, gustavo
CC=golang-dev
https://golang.org/cl/5011046
2011-09-15 16:48:57 -04:00
|
|
|
|
2010-04-13 16:30:11 -07:00
|
|
|
package os
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"runtime"
|
|
|
|
|
"syscall"
|
|
|
|
|
)
|
|
|
|
|
|
2015-02-26 12:10:11 -08:00
|
|
|
func rename(oldname, newname string) error {
|
|
|
|
|
e := syscall.Rename(oldname, newname)
|
|
|
|
|
if e != nil {
|
|
|
|
|
return &LinkError{"rename", oldname, newname, e}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
allow copy of struct containing unexported fields
An experiment: allow structs to be copied even if they
contain unexported fields. This gives packages the
ability to return opaque values in their APIs, like reflect
does for reflect.Value but without the kludgy hacks reflect
resorts to.
In general, we trust programmers not to do silly things
like *x = *y on a package's struct pointers, just as we trust
programmers not to do unicode.Letter = unicode.Digit,
but packages that want a harder guarantee can introduce
an extra level of indirection, like in the changes to os.File
in this CL or by using an interface type.
All in one CL so that it can be rolled back more easily if
we decide this is a bad idea.
Originally discussed in March 2011.
https://groups.google.com/group/golang-dev/t/3f5d30938c7c45ef
R=golang-dev, adg, dvyukov, r, bradfitz, jan.mercl, gri
CC=golang-dev
https://golang.org/cl/5372095
2011-11-15 12:20:59 -05:00
|
|
|
// file is the real representation of *File.
|
|
|
|
|
// The extra level of indirection ensures that no clients of os
|
|
|
|
|
// can overwrite this data, which could cause the finalizer
|
|
|
|
|
// to close the wrong file descriptor.
|
|
|
|
|
type file struct {
|
2011-07-01 10:18:07 -04:00
|
|
|
fd int
|
|
|
|
|
name string
|
2011-07-05 16:01:29 +10:00
|
|
|
dirinfo *dirInfo // nil unless directory being read
|
2011-07-01 10:18:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fd returns the integer Unix file descriptor referencing the open file.
|
2014-11-06 09:36:51 -05:00
|
|
|
// The file descriptor is valid only until f.Close is called or f is garbage collected.
|
2012-02-10 14:16:15 +11:00
|
|
|
func (f *File) Fd() uintptr {
|
2011-12-01 11:23:39 -08:00
|
|
|
if f == nil {
|
2012-02-10 14:16:15 +11:00
|
|
|
return ^(uintptr(0))
|
2011-07-01 10:18:07 -04:00
|
|
|
}
|
2012-02-10 14:16:15 +11:00
|
|
|
return uintptr(f.fd)
|
2011-07-01 10:18:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewFile returns a new File with the given file descriptor and name.
|
2012-02-10 14:16:15 +11:00
|
|
|
func NewFile(fd uintptr, name string) *File {
|
|
|
|
|
fdi := int(fd)
|
|
|
|
|
if fdi < 0 {
|
2011-07-01 10:18:07 -04:00
|
|
|
return nil
|
|
|
|
|
}
|
2012-02-10 14:16:15 +11:00
|
|
|
f := &File{&file{fd: fdi, name: name}}
|
allow copy of struct containing unexported fields
An experiment: allow structs to be copied even if they
contain unexported fields. This gives packages the
ability to return opaque values in their APIs, like reflect
does for reflect.Value but without the kludgy hacks reflect
resorts to.
In general, we trust programmers not to do silly things
like *x = *y on a package's struct pointers, just as we trust
programmers not to do unicode.Letter = unicode.Digit,
but packages that want a harder guarantee can introduce
an extra level of indirection, like in the changes to os.File
in this CL or by using an interface type.
All in one CL so that it can be rolled back more easily if
we decide this is a bad idea.
Originally discussed in March 2011.
https://groups.google.com/group/golang-dev/t/3f5d30938c7c45ef
R=golang-dev, adg, dvyukov, r, bradfitz, jan.mercl, gri
CC=golang-dev
https://golang.org/cl/5372095
2011-11-15 12:20:59 -05:00
|
|
|
runtime.SetFinalizer(f.file, (*file).close)
|
2011-07-01 10:18:07 -04:00
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-13 16:30:11 -07:00
|
|
|
// Auxiliary information if the File describes a directory
|
|
|
|
|
type dirInfo struct {
|
|
|
|
|
buf []byte // buffer for directory I/O
|
|
|
|
|
nbuf int // length of buf; return value from Getdirentries
|
|
|
|
|
bufp int // location of next record in buf.
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-28 11:29:22 -08:00
|
|
|
// epipecheck raises SIGPIPE if we get an EPIPE error on standard
|
|
|
|
|
// output or standard error. See the SIGPIPE docs in os/signal, and
|
|
|
|
|
// issue 11845.
|
2012-07-27 22:21:33 +10:00
|
|
|
func epipecheck(file *File, e error) {
|
2015-12-28 11:29:22 -08:00
|
|
|
if e == syscall.EPIPE && (file.fd == 1 || file.fd == 2) {
|
|
|
|
|
sigpipe()
|
2012-07-27 22:21:33 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-03 13:03:50 -07:00
|
|
|
// DevNull is the name of the operating system's ``null device.''
|
|
|
|
|
// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
|
|
|
|
|
const DevNull = "/dev/null"
|
|
|
|
|
|
2011-04-04 23:42:14 -07:00
|
|
|
// OpenFile is the generalized open call; most users will use Open
|
2016-03-01 23:21:55 +00:00
|
|
|
// or Create instead. It opens the named file with specified flag
|
|
|
|
|
// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,
|
2011-04-04 23:42:14 -07:00
|
|
|
// methods on the returned File can be used for I/O.
|
2012-02-09 16:55:36 +11:00
|
|
|
// If there is an error, it will be of type *PathError.
|
2015-07-17 08:26:29 -07:00
|
|
|
func OpenFile(name string, flag int, perm FileMode) (*File, error) {
|
2014-12-16 08:22:17 -08:00
|
|
|
chmod := false
|
|
|
|
|
if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 {
|
|
|
|
|
if _, err := Stat(name); IsNotExist(err) {
|
|
|
|
|
chmod = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-17 16:28:15 +10:00
|
|
|
var r int
|
|
|
|
|
for {
|
|
|
|
|
var e error
|
|
|
|
|
r, e = syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
|
|
|
|
|
if e == nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-17 08:32:09 +10:00
|
|
|
// On OS X, sigaction(2) doesn't guarantee that SA_RESTART will cause
|
|
|
|
|
// open(2) to be restarted for regular files. This is easy to reproduce on
|
|
|
|
|
// fuse file systems (see http://golang.org/issue/11180).
|
2015-09-17 16:28:15 +10:00
|
|
|
if runtime.GOOS == "darwin" && e == syscall.EINTR {
|
|
|
|
|
continue
|
2015-09-17 08:32:09 +10:00
|
|
|
}
|
|
|
|
|
|
2011-11-13 22:44:52 -05:00
|
|
|
return nil, &PathError{"open", name, e}
|
2010-04-13 16:30:11 -07:00
|
|
|
}
|
|
|
|
|
|
2014-12-16 08:22:17 -08:00
|
|
|
// open(2) itself won't handle the sticky bit on *BSD and Solaris
|
2014-12-22 21:05:07 -08:00
|
|
|
if chmod {
|
|
|
|
|
Chmod(name, perm)
|
2014-12-16 08:22:17 -08:00
|
|
|
}
|
|
|
|
|
|
2010-04-13 16:30:11 -07:00
|
|
|
// There's a race here with fork/exec, which we are
|
2016-03-01 23:21:55 +00:00
|
|
|
// content to live with. See ../syscall/exec_unix.go.
|
2014-03-04 09:27:29 +09:00
|
|
|
if !supportsCloseOnExec {
|
2010-04-13 16:30:11 -07:00
|
|
|
syscall.CloseOnExec(r)
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-10 14:16:15 +11:00
|
|
|
return NewFile(uintptr(r), name), nil
|
2010-04-13 16:30:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close closes the File, rendering it unusable for I/O.
|
2011-11-01 21:49:08 -04:00
|
|
|
// It returns an error, if any.
|
2011-12-01 11:23:39 -08:00
|
|
|
func (f *File) Close() error {
|
2013-08-20 14:33:03 +10:00
|
|
|
if f == nil {
|
|
|
|
|
return ErrInvalid
|
|
|
|
|
}
|
2011-12-01 11:23:39 -08:00
|
|
|
return f.file.close()
|
allow copy of struct containing unexported fields
An experiment: allow structs to be copied even if they
contain unexported fields. This gives packages the
ability to return opaque values in their APIs, like reflect
does for reflect.Value but without the kludgy hacks reflect
resorts to.
In general, we trust programmers not to do silly things
like *x = *y on a package's struct pointers, just as we trust
programmers not to do unicode.Letter = unicode.Digit,
but packages that want a harder guarantee can introduce
an extra level of indirection, like in the changes to os.File
in this CL or by using an interface type.
All in one CL so that it can be rolled back more easily if
we decide this is a bad idea.
Originally discussed in March 2011.
https://groups.google.com/group/golang-dev/t/3f5d30938c7c45ef
R=golang-dev, adg, dvyukov, r, bradfitz, jan.mercl, gri
CC=golang-dev
https://golang.org/cl/5372095
2011-11-15 12:20:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (file *file) close() error {
|
2010-04-13 16:30:11 -07:00
|
|
|
if file == nil || file.fd < 0 {
|
2012-02-17 10:04:29 +11:00
|
|
|
return syscall.EINVAL
|
2010-04-13 16:30:11 -07:00
|
|
|
}
|
2011-11-01 21:49:08 -04:00
|
|
|
var err error
|
2011-11-13 22:44:52 -05:00
|
|
|
if e := syscall.Close(file.fd); e != nil {
|
|
|
|
|
err = &PathError{"close", file.name, e}
|
2010-04-13 16:30:11 -07:00
|
|
|
}
|
|
|
|
|
file.fd = -1 // so it can't be closed again
|
|
|
|
|
|
|
|
|
|
// no need for a finalizer anymore
|
|
|
|
|
runtime.SetFinalizer(file, nil)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-26 10:34:33 -07:00
|
|
|
// Darwin and FreeBSD can't read or write 2GB+ at a time,
|
|
|
|
|
// even on 64-bit systems. See golang.org/issue/7812.
|
2014-05-02 12:12:40 -04:00
|
|
|
// Use 1GB instead of, say, 2GB-1, to keep subsequent
|
|
|
|
|
// reads aligned.
|
2014-04-26 10:34:33 -07:00
|
|
|
const (
|
|
|
|
|
needsMaxRW = runtime.GOOS == "darwin" || runtime.GOOS == "freebsd"
|
2014-05-02 12:12:40 -04:00
|
|
|
maxRW = 1 << 30
|
2014-04-26 10:34:33 -07:00
|
|
|
)
|
|
|
|
|
|
2011-04-26 18:09:46 +10:00
|
|
|
// read reads up to len(b) bytes from the File.
|
|
|
|
|
// It returns the number of bytes read and an error, if any.
|
2011-11-13 22:44:52 -05:00
|
|
|
func (f *File) read(b []byte) (n int, err error) {
|
2014-04-26 10:34:33 -07:00
|
|
|
if needsMaxRW && len(b) > maxRW {
|
|
|
|
|
b = b[:maxRW]
|
|
|
|
|
}
|
2014-10-28 15:00:13 -04:00
|
|
|
return fixCount(syscall.Read(f.fd, b))
|
2011-04-26 18:09:46 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pread reads len(b) bytes from the File starting at byte offset off.
|
|
|
|
|
// It returns the number of bytes read and the error, if any.
|
2014-04-26 10:34:33 -07:00
|
|
|
// EOF is signaled by a zero count with err set to nil.
|
2011-11-13 22:44:52 -05:00
|
|
|
func (f *File) pread(b []byte, off int64) (n int, err error) {
|
2014-04-26 10:34:33 -07:00
|
|
|
if needsMaxRW && len(b) > maxRW {
|
|
|
|
|
b = b[:maxRW]
|
|
|
|
|
}
|
2014-10-28 15:00:13 -04:00
|
|
|
return fixCount(syscall.Pread(f.fd, b, off))
|
2011-04-26 18:09:46 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// write writes len(b) bytes to the File.
|
|
|
|
|
// It returns the number of bytes written and an error, if any.
|
2011-11-13 22:44:52 -05:00
|
|
|
func (f *File) write(b []byte) (n int, err error) {
|
2012-03-15 15:10:19 -04:00
|
|
|
for {
|
2014-04-26 10:34:33 -07:00
|
|
|
bcap := b
|
|
|
|
|
if needsMaxRW && len(bcap) > maxRW {
|
|
|
|
|
bcap = bcap[:maxRW]
|
|
|
|
|
}
|
2014-10-28 15:00:13 -04:00
|
|
|
m, err := fixCount(syscall.Write(f.fd, bcap))
|
2012-03-15 15:10:19 -04:00
|
|
|
n += m
|
|
|
|
|
|
|
|
|
|
// If the syscall wrote some data but not all (short write)
|
|
|
|
|
// or it returned EINTR, then assume it stopped early for
|
|
|
|
|
// reasons that are uninteresting to the caller, and try again.
|
2014-04-26 10:34:33 -07:00
|
|
|
if 0 < m && m < len(bcap) || err == syscall.EINTR {
|
|
|
|
|
b = b[m:]
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if needsMaxRW && len(bcap) != len(b) && err == nil {
|
2012-03-15 15:10:19 -04:00
|
|
|
b = b[m:]
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return n, err
|
|
|
|
|
}
|
2011-04-26 18:09:46 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pwrite writes len(b) bytes to the File starting at byte offset off.
|
|
|
|
|
// It returns the number of bytes written and an error, if any.
|
2011-11-13 22:44:52 -05:00
|
|
|
func (f *File) pwrite(b []byte, off int64) (n int, err error) {
|
2014-04-26 10:34:33 -07:00
|
|
|
if needsMaxRW && len(b) > maxRW {
|
|
|
|
|
b = b[:maxRW]
|
|
|
|
|
}
|
2014-10-28 15:00:13 -04:00
|
|
|
return fixCount(syscall.Pwrite(f.fd, b, off))
|
2011-04-26 18:09:46 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// seek sets the offset for the next Read or Write on file to offset, interpreted
|
|
|
|
|
// 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.
|
|
|
|
|
// It returns the new offset and an error, if any.
|
2011-11-13 22:44:52 -05:00
|
|
|
func (f *File) seek(offset int64, whence int) (ret int64, err error) {
|
2014-10-28 15:34:50 -04:00
|
|
|
return syscall.Seek(f.fd, offset, whence)
|
2011-04-26 18:09:46 +10:00
|
|
|
}
|
|
|
|
|
|
2010-04-26 23:17:14 -07:00
|
|
|
// Truncate changes the size of the named file.
|
|
|
|
|
// If the file is a symbolic link, it changes the size of the link's target.
|
2012-02-09 16:55:36 +11:00
|
|
|
// If there is an error, it will be of type *PathError.
|
2011-11-01 21:49:08 -04:00
|
|
|
func Truncate(name string, size int64) error {
|
2011-11-13 22:44:52 -05:00
|
|
|
if e := syscall.Truncate(name, size); e != nil {
|
|
|
|
|
return &PathError{"truncate", name, e}
|
2010-04-26 23:17:14 -07:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2011-03-29 14:23:36 -04:00
|
|
|
|
2011-12-20 11:52:20 +11:00
|
|
|
// Remove removes the named file or directory.
|
2012-02-09 16:55:36 +11:00
|
|
|
// If there is an error, it will be of type *PathError.
|
2011-12-20 11:52:20 +11:00
|
|
|
func Remove(name string) error {
|
|
|
|
|
// System call interface forces us to know
|
|
|
|
|
// whether name is a file or directory.
|
|
|
|
|
// Try both: it is cheaper on average than
|
|
|
|
|
// doing a Stat plus the right one.
|
|
|
|
|
e := syscall.Unlink(name)
|
|
|
|
|
if e == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
e1 := syscall.Rmdir(name)
|
|
|
|
|
if e1 == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Both failed: figure out which error to return.
|
|
|
|
|
// OS X and Linux differ on whether unlink(dir)
|
2016-03-01 23:21:55 +00:00
|
|
|
// returns EISDIR, so can't use that. However,
|
2011-12-20 11:52:20 +11:00
|
|
|
// both agree that rmdir(file) returns ENOTDIR,
|
|
|
|
|
// so we can use that to decide which error is real.
|
|
|
|
|
// Rmdir might also return ENOTDIR if given a bad
|
|
|
|
|
// file path, like /etc/passwd/foo, but in that case,
|
|
|
|
|
// both errors will be ENOTDIR, so it's okay to
|
|
|
|
|
// use the error from unlink.
|
|
|
|
|
if e1 != syscall.ENOTDIR {
|
|
|
|
|
e = e1
|
|
|
|
|
}
|
|
|
|
|
return &PathError{"remove", name, e}
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-14 14:06:50 -05:00
|
|
|
// TempDir returns the default directory to use for temporary files.
|
|
|
|
|
func TempDir() string {
|
|
|
|
|
dir := Getenv("TMPDIR")
|
|
|
|
|
if dir == "" {
|
2014-07-09 14:12:30 -04:00
|
|
|
if runtime.GOOS == "android" {
|
|
|
|
|
dir = "/data/local/tmp"
|
|
|
|
|
} else {
|
|
|
|
|
dir = "/tmp"
|
|
|
|
|
}
|
2011-11-14 14:06:50 -05:00
|
|
|
}
|
|
|
|
|
return dir
|
|
|
|
|
}
|
2014-07-17 17:02:46 +10:00
|
|
|
|
|
|
|
|
// Link creates newname as a hard link to the oldname file.
|
|
|
|
|
// If there is an error, it will be of type *LinkError.
|
|
|
|
|
func Link(oldname, newname string) error {
|
|
|
|
|
e := syscall.Link(oldname, newname)
|
|
|
|
|
if e != nil {
|
|
|
|
|
return &LinkError{"link", oldname, newname, e}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Symlink creates newname as a symbolic link to oldname.
|
|
|
|
|
// If there is an error, it will be of type *LinkError.
|
|
|
|
|
func Symlink(oldname, newname string) error {
|
|
|
|
|
e := syscall.Symlink(oldname, newname)
|
|
|
|
|
if e != nil {
|
|
|
|
|
return &LinkError{"symlink", oldname, newname, e}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|