summaryrefslogtreecommitdiff
path: root/src/pkg/os
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/os')
-rw-r--r--src/pkg/os/dir_plan9.go73
-rw-r--r--src/pkg/os/dir_unix.go58
-rw-r--r--src/pkg/os/dir_windows.go14
-rw-r--r--src/pkg/os/doc.go135
-rw-r--r--src/pkg/os/env.go103
-rw-r--r--src/pkg/os/env_test.go70
-rw-r--r--src/pkg/os/env_unix_test.go30
-rw-r--r--src/pkg/os/error.go65
-rw-r--r--src/pkg/os/error_plan9.go53
-rw-r--r--src/pkg/os/error_test.go132
-rw-r--r--src/pkg/os/error_unix.go45
-rw-r--r--src/pkg/os/error_windows.go45
-rw-r--r--src/pkg/os/error_windows_test.go47
-rw-r--r--src/pkg/os/exec.go70
-rw-r--r--src/pkg/os/exec/example_test.go75
-rw-r--r--src/pkg/os/exec/exec.go493
-rw-r--r--src/pkg/os/exec/exec_test.go726
-rw-r--r--src/pkg/os/exec/lp_plan9.go53
-rw-r--r--src/pkg/os/exec/lp_test.go33
-rw-r--r--src/pkg/os/exec/lp_unix.go60
-rw-r--r--src/pkg/os/exec/lp_unix_test.go55
-rw-r--r--src/pkg/os/exec/lp_windows.go123
-rw-r--r--src/pkg/os/exec/lp_windows_test.go573
-rw-r--r--src/pkg/os/exec_plan9.go137
-rw-r--r--src/pkg/os/exec_posix.go134
-rw-r--r--src/pkg/os/exec_unix.go73
-rw-r--r--src/pkg/os/exec_windows.go115
-rw-r--r--src/pkg/os/export_test.go10
-rw-r--r--src/pkg/os/file.go257
-rw-r--r--src/pkg/os/file_plan9.go468
-rw-r--r--src/pkg/os/file_posix.go169
-rw-r--r--src/pkg/os/file_unix.go314
-rw-r--r--src/pkg/os/file_windows.go495
-rw-r--r--src/pkg/os/getwd.go119
-rw-r--r--src/pkg/os/getwd_darwin.go15
-rw-r--r--src/pkg/os/os_test.go1339
-rw-r--r--src/pkg/os/os_unix_test.go76
-rw-r--r--src/pkg/os/path.go123
-rw-r--r--src/pkg/os/path_plan9.go15
-rw-r--r--src/pkg/os/path_test.go215
-rw-r--r--src/pkg/os/path_unix.go17
-rw-r--r--src/pkg/os/path_windows.go16
-rw-r--r--src/pkg/os/pipe_bsd.go28
-rw-r--r--src/pkg/os/pipe_linux.go33
-rw-r--r--src/pkg/os/proc.go36
-rw-r--r--src/pkg/os/signal/example_test.go23
-rw-r--r--src/pkg/os/signal/sig.s23
-rw-r--r--src/pkg/os/signal/signal.go131
-rw-r--r--src/pkg/os/signal/signal_stub.go17
-rw-r--r--src/pkg/os/signal/signal_test.go208
-rw-r--r--src/pkg/os/signal/signal_unix.go53
-rw-r--r--src/pkg/os/signal/signal_windows_test.go103
-rw-r--r--src/pkg/os/stat_darwin.go61
-rw-r--r--src/pkg/os/stat_dragonfly.go61
-rw-r--r--src/pkg/os/stat_freebsd.go61
-rw-r--r--src/pkg/os/stat_linux.go61
-rw-r--r--src/pkg/os/stat_nacl.go62
-rw-r--r--src/pkg/os/stat_netbsd.go61
-rw-r--r--src/pkg/os/stat_openbsd.go61
-rw-r--r--src/pkg/os/stat_plan9.go110
-rw-r--r--src/pkg/os/stat_solaris.go61
-rw-r--r--src/pkg/os/stat_windows.go160
-rw-r--r--src/pkg/os/str.go22
-rw-r--r--src/pkg/os/sys_bsd.go20
-rw-r--r--src/pkg/os/sys_darwin.go31
-rw-r--r--src/pkg/os/sys_freebsd.go23
-rw-r--r--src/pkg/os/sys_linux.go26
-rw-r--r--src/pkg/os/sys_nacl.go9
-rw-r--r--src/pkg/os/sys_plan9.go26
-rw-r--r--src/pkg/os/sys_solaris.go11
-rw-r--r--src/pkg/os/sys_unix.go11
-rw-r--r--src/pkg/os/sys_windows.go15
-rw-r--r--src/pkg/os/types.go118
-rw-r--r--src/pkg/os/types_notwin.go25
-rw-r--r--src/pkg/os/types_windows.go104
-rw-r--r--src/pkg/os/user/lookup.go22
-rw-r--r--src/pkg/os/user/lookup_plan9.go46
-rw-r--r--src/pkg/os/user/lookup_stubs.go28
-rw-r--r--src/pkg/os/user/lookup_unix.go112
-rw-r--r--src/pkg/os/user/lookup_windows.go149
-rw-r--r--src/pkg/os/user/user.go43
-rw-r--r--src/pkg/os/user/user_test.go89
82 files changed, 0 insertions, 9582 deletions
diff --git a/src/pkg/os/dir_plan9.go b/src/pkg/os/dir_plan9.go
deleted file mode 100644
index 8195c02a4..000000000
--- a/src/pkg/os/dir_plan9.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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.
-
-package os
-
-import (
- "io"
- "syscall"
-)
-
-func (file *File) readdir(n int) ([]FileInfo, error) {
- // If this file has no dirinfo, create one.
- if file.dirinfo == nil {
- file.dirinfo = new(dirInfo)
- }
- d := file.dirinfo
- size := n
- if size <= 0 {
- size = 100
- n = -1
- }
- fi := make([]FileInfo, 0, size) // Empty with room to grow.
- for n != 0 {
- // Refill the buffer if necessary.
- if d.bufp >= d.nbuf {
- nb, err := file.Read(d.buf[:])
-
- // Update the buffer state before checking for errors.
- d.bufp, d.nbuf = 0, nb
-
- if err != nil {
- if err == io.EOF {
- break
- }
- return fi, &PathError{"readdir", file.name, err}
- }
- if nb < syscall.STATFIXLEN {
- return fi, &PathError{"readdir", file.name, syscall.ErrShortStat}
- }
- }
-
- // Get a record from the buffer.
- b := d.buf[d.bufp:]
- m := int(uint16(b[0])|uint16(b[1])<<8) + 2
- if m < syscall.STATFIXLEN {
- return fi, &PathError{"readdir", file.name, syscall.ErrShortStat}
- }
-
- dir, err := syscall.UnmarshalDir(b[:m])
- if err != nil {
- return fi, &PathError{"readdir", file.name, err}
- }
- fi = append(fi, fileInfoFromStat(dir))
-
- d.bufp += m
- n--
- }
-
- if n >= 0 && len(fi) == 0 {
- return fi, io.EOF
- }
- return fi, nil
-}
-
-func (file *File) readdirnames(n int) (names []string, err error) {
- fi, err := file.Readdir(n)
- names = make([]string, len(fi))
- for i := range fi {
- names[i] = fi[i].Name()
- }
- return
-}
diff --git a/src/pkg/os/dir_unix.go b/src/pkg/os/dir_unix.go
deleted file mode 100644
index d353e405e..000000000
--- a/src/pkg/os/dir_unix.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package os
-
-import (
- "io"
- "syscall"
-)
-
-const (
- blockSize = 4096
-)
-
-func (f *File) readdirnames(n int) (names []string, err error) {
- // If this file has no dirinfo, create one.
- if f.dirinfo == nil {
- f.dirinfo = new(dirInfo)
- // The buffer must be at least a block long.
- f.dirinfo.buf = make([]byte, blockSize)
- }
- d := f.dirinfo
-
- size := n
- if size <= 0 {
- size = 100
- n = -1
- }
-
- names = make([]string, 0, size) // Empty with room to grow.
- for n != 0 {
- // Refill the buffer if necessary
- if d.bufp >= d.nbuf {
- d.bufp = 0
- var errno error
- d.nbuf, errno = syscall.ReadDirent(f.fd, d.buf)
- if errno != nil {
- return names, NewSyscallError("readdirent", errno)
- }
- if d.nbuf <= 0 {
- break // EOF
- }
- }
-
- // Drain the buffer
- var nb, nc int
- nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names)
- d.bufp += nb
- n -= nc
- }
- if n >= 0 && len(names) == 0 {
- return names, io.EOF
- }
- return names, nil
-}
diff --git a/src/pkg/os/dir_windows.go b/src/pkg/os/dir_windows.go
deleted file mode 100644
index 931316048..000000000
--- a/src/pkg/os/dir_windows.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.
-
-package os
-
-func (file *File) readdirnames(n int) (names []string, err error) {
- fis, err := file.Readdir(n)
- names = make([]string, len(fis))
- for i, fi := range fis {
- names[i] = fi.Name()
- }
- return names, err
-}
diff --git a/src/pkg/os/doc.go b/src/pkg/os/doc.go
deleted file mode 100644
index 389a8eb14..000000000
--- a/src/pkg/os/doc.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2012 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.
-
-package os
-
-import "time"
-
-// FindProcess looks for a running process by its pid.
-// The Process it returns can be used to obtain information
-// about the underlying operating system process.
-func FindProcess(pid int) (p *Process, err error) {
- return findProcess(pid)
-}
-
-// StartProcess starts a new process with the program, arguments and attributes
-// specified by name, argv and attr.
-//
-// StartProcess is a low-level interface. The os/exec package provides
-// higher-level interfaces.
-//
-// If there is an error, it will be of type *PathError.
-func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) {
- return startProcess(name, argv, attr)
-}
-
-// Release releases any resources associated with the Process p,
-// rendering it unusable in the future.
-// Release only needs to be called if Wait is not.
-func (p *Process) Release() error {
- return p.release()
-}
-
-// Kill causes the Process to exit immediately.
-func (p *Process) Kill() error {
- return p.kill()
-}
-
-// Wait waits for the Process to exit, and then returns a
-// ProcessState describing its status and an error, if any.
-// Wait releases any resources associated with the Process.
-// On most operating systems, the Process must be a child
-// of the current process or an error will be returned.
-func (p *Process) Wait() (*ProcessState, error) {
- return p.wait()
-}
-
-// Signal sends a signal to the Process.
-// Sending Interrupt on Windows is not implemented.
-func (p *Process) Signal(sig Signal) error {
- return p.signal(sig)
-}
-
-// UserTime returns the user CPU time of the exited process and its children.
-func (p *ProcessState) UserTime() time.Duration {
- return p.userTime()
-}
-
-// SystemTime returns the system CPU time of the exited process and its children.
-func (p *ProcessState) SystemTime() time.Duration {
- return p.systemTime()
-}
-
-// Exited reports whether the program has exited.
-func (p *ProcessState) Exited() bool {
- return p.exited()
-}
-
-// Success reports whether the program exited successfully,
-// such as with exit status 0 on Unix.
-func (p *ProcessState) Success() bool {
- return p.success()
-}
-
-// Sys returns system-dependent exit information about
-// the process. Convert it to the appropriate underlying
-// type, such as syscall.WaitStatus on Unix, to access its contents.
-func (p *ProcessState) Sys() interface{} {
- return p.sys()
-}
-
-// SysUsage returns system-dependent resource usage information about
-// the exited process. Convert it to the appropriate underlying
-// type, such as *syscall.Rusage on Unix, to access its contents.
-// (On Unix, *syscall.Rusage matches struct rusage as defined in the
-// getrusage(2) manual page.)
-func (p *ProcessState) SysUsage() interface{} {
- return p.sysUsage()
-}
-
-// Hostname returns the host name reported by the kernel.
-func Hostname() (name string, err error) {
- return hostname()
-}
-
-// Readdir reads the contents of the directory associated with file and
-// returns a slice of up to n FileInfo values, as would be returned
-// by Lstat, in directory order. Subsequent calls on the same file will yield
-// further FileInfos.
-//
-// If n > 0, Readdir returns at most n FileInfo structures. In this case, if
-// Readdir returns an empty slice, it will return a non-nil error
-// explaining why. At the end of a directory, the error is io.EOF.
-//
-// If n <= 0, Readdir returns all the FileInfo from the directory in
-// a single slice. In this case, if Readdir succeeds (reads all
-// the way to the end of the directory), it returns the slice and a
-// nil error. If it encounters an error before the end of the
-// directory, Readdir returns the FileInfo read until that point
-// and a non-nil error.
-func (f *File) Readdir(n int) (fi []FileInfo, err error) {
- if f == nil {
- return nil, ErrInvalid
- }
- return f.readdir(n)
-}
-
-// Readdirnames reads and returns a slice of names from the directory f.
-//
-// If n > 0, Readdirnames returns at most n names. In this case, if
-// Readdirnames returns an empty slice, it will return a non-nil error
-// explaining why. At the end of a directory, the error is io.EOF.
-//
-// If n <= 0, Readdirnames returns all the names from the directory in
-// a single slice. In this case, if Readdirnames succeeds (reads all
-// the way to the end of the directory), it returns the slice and a
-// nil error. If it encounters an error before the end of the
-// directory, Readdirnames returns the names read until that point and
-// a non-nil error.
-func (f *File) Readdirnames(n int) (names []string, err error) {
- if f == nil {
- return nil, ErrInvalid
- }
- return f.readdirnames(n)
-}
diff --git a/src/pkg/os/env.go b/src/pkg/os/env.go
deleted file mode 100644
index db7fc72b8..000000000
--- a/src/pkg/os/env.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2010 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.
-
-// General environment variables.
-
-package os
-
-import "syscall"
-
-// Expand replaces ${var} or $var in the string based on the mapping function.
-// For example, os.ExpandEnv(s) is equivalent to os.Expand(s, os.Getenv).
-func Expand(s string, mapping func(string) string) string {
- buf := make([]byte, 0, 2*len(s))
- // ${} is all ASCII, so bytes are fine for this operation.
- i := 0
- for j := 0; j < len(s); j++ {
- if s[j] == '$' && j+1 < len(s) {
- buf = append(buf, s[i:j]...)
- name, w := getShellName(s[j+1:])
- buf = append(buf, mapping(name)...)
- j += w
- i = j + 1
- }
- }
- return string(buf) + s[i:]
-}
-
-// ExpandEnv replaces ${var} or $var in the string according to the values
-// of the current environment variables. References to undefined
-// variables are replaced by the empty string.
-func ExpandEnv(s string) string {
- return Expand(s, Getenv)
-}
-
-// isSpellSpecialVar reports whether the character identifies a special
-// shell variable such as $*.
-func isShellSpecialVar(c uint8) bool {
- switch c {
- case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- return true
- }
- return false
-}
-
-// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
-func isAlphaNum(c uint8) bool {
- return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
-}
-
-// getName returns the name that begins the string and the number of bytes
-// consumed to extract it. If the name is enclosed in {}, it's part of a ${}
-// expansion and two more bytes are needed than the length of the name.
-func getShellName(s string) (string, int) {
- switch {
- case s[0] == '{':
- if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
- return s[1:2], 3
- }
- // Scan to closing brace
- for i := 1; i < len(s); i++ {
- if s[i] == '}' {
- return s[1:i], i + 1
- }
- }
- return "", 1 // Bad syntax; just eat the brace.
- case isShellSpecialVar(s[0]):
- return s[0:1], 1
- }
- // Scan alphanumerics.
- var i int
- for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
- }
- return s[:i], i
-}
-
-// Getenv retrieves the value of the environment variable named by the key.
-// It returns the value, which will be empty if the variable is not present.
-func Getenv(key string) string {
- v, _ := syscall.Getenv(key)
- return v
-}
-
-// Setenv sets the value of the environment variable named by the key.
-// It returns an error, if any.
-func Setenv(key, value string) error {
- err := syscall.Setenv(key, value)
- if err != nil {
- return NewSyscallError("setenv", err)
- }
- return nil
-}
-
-// Clearenv deletes all environment variables.
-func Clearenv() {
- syscall.Clearenv()
-}
-
-// Environ returns a copy of strings representing the environment,
-// in the form "key=value".
-func Environ() []string {
- return syscall.Environ()
-}
diff --git a/src/pkg/os/env_test.go b/src/pkg/os/env_test.go
deleted file mode 100644
index 991fa4d05..000000000
--- a/src/pkg/os/env_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2010 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.
-
-package os_test
-
-import (
- . "os"
- "reflect"
- "testing"
-)
-
-// testGetenv gives us a controlled set of variables for testing Expand.
-func testGetenv(s string) string {
- switch s {
- case "*":
- return "all the args"
- case "#":
- return "NARGS"
- case "$":
- return "PID"
- case "1":
- return "ARGUMENT1"
- case "HOME":
- return "/usr/gopher"
- case "H":
- return "(Value of H)"
- case "home_1":
- return "/usr/foo"
- case "_":
- return "underscore"
- }
- return ""
-}
-
-var expandTests = []struct {
- in, out string
-}{
- {"", ""},
- {"$*", "all the args"},
- {"$$", "PID"},
- {"${*}", "all the args"},
- {"$1", "ARGUMENT1"},
- {"${1}", "ARGUMENT1"},
- {"now is the time", "now is the time"},
- {"$HOME", "/usr/gopher"},
- {"$home_1", "/usr/foo"},
- {"${HOME}", "/usr/gopher"},
- {"${H}OME", "(Value of H)OME"},
- {"A$$$#$1$H$home_1*B", "APIDNARGSARGUMENT1(Value of H)/usr/foo*B"},
-}
-
-func TestExpand(t *testing.T) {
- for _, test := range expandTests {
- result := Expand(test.in, testGetenv)
- if result != test.out {
- t.Errorf("Expand(%q)=%q; expected %q", test.in, result, test.out)
- }
- }
-}
-
-func TestConsistentEnviron(t *testing.T) {
- e0 := Environ()
- for i := 0; i < 10; i++ {
- e1 := Environ()
- if !reflect.DeepEqual(e0, e1) {
- t.Fatalf("environment changed")
- }
- }
-}
diff --git a/src/pkg/os/env_unix_test.go b/src/pkg/os/env_unix_test.go
deleted file mode 100644
index 5ec07ee1b..000000000
--- a/src/pkg/os/env_unix_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2013 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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package os_test
-
-import (
- . "os"
- "testing"
-)
-
-var setenvEinvalTests = []struct {
- k, v string
-}{
- {"", ""}, // empty key
- {"k=v", ""}, // '=' in key
- {"\x00", ""}, // '\x00' in key
- {"k", "\x00"}, // '\x00' in value
-}
-
-func TestSetenvUnixEinval(t *testing.T) {
- for _, tt := range setenvEinvalTests {
- err := Setenv(tt.k, tt.v)
- if err == nil {
- t.Errorf(`Setenv(%q, %q) == nil, want error`, tt.k, tt.v)
- }
- }
-}
diff --git a/src/pkg/os/error.go b/src/pkg/os/error.go
deleted file mode 100644
index 8810e6930..000000000
--- a/src/pkg/os/error.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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.
-
-package os
-
-import (
- "errors"
-)
-
-// Portable analogs of some common system call errors.
-var (
- ErrInvalid = errors.New("invalid argument")
- ErrPermission = errors.New("permission denied")
- ErrExist = errors.New("file already exists")
- ErrNotExist = errors.New("file does not exist")
-)
-
-// PathError records an error and the operation and file path that caused it.
-type PathError struct {
- Op string
- Path string
- Err error
-}
-
-func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
-
-// SyscallError records an error from a specific system call.
-type SyscallError struct {
- Syscall string
- Err error
-}
-
-func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }
-
-// NewSyscallError returns, as an error, a new SyscallError
-// with the given system call name and error details.
-// As a convenience, if err is nil, NewSyscallError returns nil.
-func NewSyscallError(syscall string, err error) error {
- if err == nil {
- return nil
- }
- return &SyscallError{syscall, err}
-}
-
-// IsExist returns a boolean indicating whether the error is known to report
-// that a file or directory already exists. It is satisfied by ErrExist as
-// well as some syscall errors.
-func IsExist(err error) bool {
- return isExist(err)
-}
-
-// IsNotExist returns a boolean indicating whether the error is known to
-// report that a file or directory does not exist. It is satisfied by
-// ErrNotExist as well as some syscall errors.
-func IsNotExist(err error) bool {
- return isNotExist(err)
-}
-
-// IsPermission returns a boolean indicating whether the error is known to
-// report that permission is denied. It is satisfied by ErrPermission as well
-// as some syscall errors.
-func IsPermission(err error) bool {
- return isPermission(err)
-}
diff --git a/src/pkg/os/error_plan9.go b/src/pkg/os/error_plan9.go
deleted file mode 100644
index 85260c82a..000000000
--- a/src/pkg/os/error_plan9.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2011 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.
-
-package os
-
-func isExist(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return contains(err.Error(), " exists")
-}
-
-func isNotExist(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return contains(err.Error(), "does not exist")
-}
-
-func isPermission(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return contains(err.Error(), "permission denied")
-}
-
-// contains is a local version of strings.Contains. It knows len(sep) > 1.
-func contains(s, sep string) bool {
- n := len(sep)
- c := sep[0]
- for i := 0; i+n <= len(s); i++ {
- if s[i] == c && s[i:i+n] == sep {
- return true
- }
- }
- return false
-}
diff --git a/src/pkg/os/error_test.go b/src/pkg/os/error_test.go
deleted file mode 100644
index 02ed2351c..000000000
--- a/src/pkg/os/error_test.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2012 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.
-
-package os_test
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "testing"
-)
-
-func TestErrIsExist(t *testing.T) {
- f, err := ioutil.TempFile("", "_Go_ErrIsExist")
- if err != nil {
- t.Fatalf("open ErrIsExist tempfile: %s", err)
- return
- }
- defer os.Remove(f.Name())
- defer f.Close()
- f2, err := os.OpenFile(f.Name(), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
- if err == nil {
- f2.Close()
- t.Fatal("Open should have failed")
- return
- }
- if s := checkErrorPredicate("os.IsExist", os.IsExist, err); s != "" {
- t.Fatal(s)
- return
- }
-}
-
-func testErrNotExist(name string) string {
- f, err := os.Open(name)
- if err == nil {
- f.Close()
- return "Open should have failed"
- }
- if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err); s != "" {
- return s
- }
-
- err = os.Chdir(name)
- if err == nil {
- return "Chdir should have failed"
- }
- if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err); s != "" {
- return s
- }
- return ""
-}
-
-func TestErrIsNotExist(t *testing.T) {
- tmpDir, err := ioutil.TempDir("", "_Go_ErrIsNotExist")
- if err != nil {
- t.Fatalf("create ErrIsNotExist tempdir: %s", err)
- return
- }
- defer os.RemoveAll(tmpDir)
-
- name := filepath.Join(tmpDir, "NotExists")
- if s := testErrNotExist(name); s != "" {
- t.Fatal(s)
- return
- }
-
- name = filepath.Join(name, "NotExists2")
- if s := testErrNotExist(name); s != "" {
- t.Fatal(s)
- return
- }
-}
-
-func checkErrorPredicate(predName string, pred func(error) bool, err error) string {
- if !pred(err) {
- return fmt.Sprintf("%s does not work as expected for %#v", predName, err)
- }
- return ""
-}
-
-var isExistTests = []struct {
- err error
- is bool
- isnot bool
-}{
- {&os.PathError{Err: os.ErrInvalid}, false, false},
- {&os.PathError{Err: os.ErrPermission}, false, false},
- {&os.PathError{Err: os.ErrExist}, true, false},
- {&os.PathError{Err: os.ErrNotExist}, false, true},
- {&os.LinkError{Err: os.ErrInvalid}, false, false},
- {&os.LinkError{Err: os.ErrPermission}, false, false},
- {&os.LinkError{Err: os.ErrExist}, true, false},
- {&os.LinkError{Err: os.ErrNotExist}, false, true},
- {nil, false, false},
-}
-
-func TestIsExist(t *testing.T) {
- for _, tt := range isExistTests {
- if is := os.IsExist(tt.err); is != tt.is {
- t.Errorf("os.IsExist(%T %v) = %v, want %v", tt.err, tt.err, is, tt.is)
- }
- if isnot := os.IsNotExist(tt.err); isnot != tt.isnot {
- t.Errorf("os.IsNotExist(%T %v) = %v, want %v", tt.err, tt.err, isnot, tt.isnot)
- }
- }
-}
-
-func TestErrPathNUL(t *testing.T) {
- f, err := ioutil.TempFile("", "_Go_ErrPathNUL\x00")
- if err == nil {
- f.Close()
- t.Fatal("TempFile should have failed")
- }
- f, err = ioutil.TempFile("", "_Go_ErrPathNUL")
- if err != nil {
- t.Fatalf("open ErrPathNUL tempfile: %s", err)
- }
- defer os.Remove(f.Name())
- defer f.Close()
- f2, err := os.OpenFile(f.Name(), os.O_RDWR, 0600)
- if err != nil {
- t.Fatalf("open ErrPathNUL: %s", err)
- }
- f2.Close()
- f2, err = os.OpenFile(f.Name()+"\x00", os.O_RDWR, 0600)
- if err == nil {
- f2.Close()
- t.Fatal("Open should have failed")
- }
-}
diff --git a/src/pkg/os/error_unix.go b/src/pkg/os/error_unix.go
deleted file mode 100644
index f2aabbb45..000000000
--- a/src/pkg/os/error_unix.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package os
-
-import "syscall"
-
-func isExist(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return err == syscall.EEXIST || err == ErrExist
-}
-
-func isNotExist(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return err == syscall.ENOENT || err == ErrNotExist
-}
-
-func isPermission(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return err == syscall.EACCES || err == syscall.EPERM || err == ErrPermission
-}
diff --git a/src/pkg/os/error_windows.go b/src/pkg/os/error_windows.go
deleted file mode 100644
index 83db6c078..000000000
--- a/src/pkg/os/error_windows.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 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.
-
-package os
-
-import "syscall"
-
-func isExist(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return err == syscall.ERROR_ALREADY_EXISTS ||
- err == syscall.ERROR_FILE_EXISTS || err == ErrExist
-}
-
-func isNotExist(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return err == syscall.ERROR_FILE_NOT_FOUND ||
- err == syscall.ERROR_PATH_NOT_FOUND || err == ErrNotExist
-}
-
-func isPermission(err error) bool {
- switch pe := err.(type) {
- case nil:
- return false
- case *PathError:
- err = pe.Err
- case *LinkError:
- err = pe.Err
- }
- return err == syscall.ERROR_ACCESS_DENIED || err == ErrPermission
-}
diff --git a/src/pkg/os/error_windows_test.go b/src/pkg/os/error_windows_test.go
deleted file mode 100644
index 3e6504f8d..000000000
--- a/src/pkg/os/error_windows_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2012 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.
-
-package os_test
-
-import (
- "io/ioutil"
- "os"
- "path/filepath"
- "testing"
-)
-
-func TestErrIsExistAfterRename(t *testing.T) {
- dir, err := ioutil.TempDir("", "go-build")
- if err != nil {
- t.Fatalf("Create temp directory: %v", err)
- }
- defer os.RemoveAll(dir)
-
- src := filepath.Join(dir, "src")
- dest := filepath.Join(dir, "dest")
-
- f, err := os.Create(src)
- if err != nil {
- t.Fatalf("Create file %v: %v", src, err)
- }
- f.Close()
- err = os.Rename(src, dest)
- if err != nil {
- t.Fatalf("Rename %v to %v: %v", src, dest, err)
- }
-
- f, err = os.Create(src)
- if err != nil {
- t.Fatalf("Create file %v: %v", src, err)
- }
- f.Close()
- err = os.Rename(src, dest)
- if err == nil {
- t.Fatal("Rename should have failed")
- }
- if s := checkErrorPredicate("os.IsExist", os.IsExist, err); s != "" {
- t.Fatal(s)
- return
- }
-}
diff --git a/src/pkg/os/exec.go b/src/pkg/os/exec.go
deleted file mode 100644
index 5aea3098b..000000000
--- a/src/pkg/os/exec.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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.
-
-package os
-
-import (
- "runtime"
- "sync/atomic"
- "syscall"
-)
-
-// Process stores the information about a process created by StartProcess.
-type Process struct {
- Pid int
- handle uintptr
- isdone uint32 // process has been successfully waited on, non zero if true
-}
-
-func newProcess(pid int, handle uintptr) *Process {
- p := &Process{Pid: pid, handle: handle}
- runtime.SetFinalizer(p, (*Process).Release)
- return p
-}
-
-func (p *Process) setDone() {
- atomic.StoreUint32(&p.isdone, 1)
-}
-
-func (p *Process) done() bool {
- return atomic.LoadUint32(&p.isdone) > 0
-}
-
-// ProcAttr holds the attributes that will be applied to a new process
-// started by StartProcess.
-type ProcAttr struct {
- // If Dir is non-empty, the child changes into the directory before
- // creating the process.
- Dir string
- // If Env is non-nil, it gives the environment variables for the
- // new process in the form returned by Environ.
- // If it is nil, the result of Environ will be used.
- Env []string
- // Files specifies the open files inherited by the new process. The
- // first three entries correspond to standard input, standard output, and
- // standard error. An implementation may support additional entries,
- // depending on the underlying operating system. A nil entry corresponds
- // to that file being closed when the process starts.
- Files []*File
-
- // Operating system-specific process creation attributes.
- // Note that setting this field means that your program
- // may not execute properly or even compile on some
- // operating systems.
- Sys *syscall.SysProcAttr
-}
-
-// A Signal represents an operating system signal.
-// The usual underlying implementation is operating system-dependent:
-// on Unix it is syscall.Signal.
-type Signal interface {
- String() string
- Signal() // to distinguish from other Stringers
-}
-
-// Getpid returns the process id of the caller.
-func Getpid() int { return syscall.Getpid() }
-
-// Getppid returns the process id of the caller's parent.
-func Getppid() int { return syscall.Getppid() }
diff --git a/src/pkg/os/exec/example_test.go b/src/pkg/os/exec/example_test.go
deleted file mode 100644
index 55eaac8ab..000000000
--- a/src/pkg/os/exec/example_test.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2012 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.
-
-package exec_test
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "log"
- "os/exec"
- "strings"
-)
-
-func ExampleLookPath() {
- path, err := exec.LookPath("fortune")
- if err != nil {
- log.Fatal("installing fortune is in your future")
- }
- fmt.Printf("fortune is available at %s\n", path)
-}
-
-func ExampleCommand() {
- cmd := exec.Command("tr", "a-z", "A-Z")
- cmd.Stdin = strings.NewReader("some input")
- var out bytes.Buffer
- cmd.Stdout = &out
- err := cmd.Run()
- if err != nil {
- log.Fatal(err)
- }
- fmt.Printf("in all caps: %q\n", out.String())
-}
-
-func ExampleCmd_Output() {
- out, err := exec.Command("date").Output()
- if err != nil {
- log.Fatal(err)
- }
- fmt.Printf("The date is %s\n", out)
-}
-
-func ExampleCmd_Start() {
- cmd := exec.Command("sleep", "5")
- err := cmd.Start()
- if err != nil {
- log.Fatal(err)
- }
- log.Printf("Waiting for command to finish...")
- err = cmd.Wait()
- log.Printf("Command finished with error: %v", err)
-}
-
-func ExampleCmd_StdoutPipe() {
- cmd := exec.Command("echo", "-n", `{"Name": "Bob", "Age": 32}`)
- stdout, err := cmd.StdoutPipe()
- if err != nil {
- log.Fatal(err)
- }
- if err := cmd.Start(); err != nil {
- log.Fatal(err)
- }
- var person struct {
- Name string
- Age int
- }
- if err := json.NewDecoder(stdout).Decode(&person); err != nil {
- log.Fatal(err)
- }
- if err := cmd.Wait(); err != nil {
- log.Fatal(err)
- }
- fmt.Printf("%s is %d years old\n", person.Name, person.Age)
-}
diff --git a/src/pkg/os/exec/exec.go b/src/pkg/os/exec/exec.go
deleted file mode 100644
index a70ed0d20..000000000
--- a/src/pkg/os/exec/exec.go
+++ /dev/null
@@ -1,493 +0,0 @@
-// 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.
-
-// Package exec runs external commands. It wraps os.StartProcess to make it
-// easier to remap stdin and stdout, connect I/O with pipes, and do other
-// adjustments.
-package exec
-
-import (
- "bytes"
- "errors"
- "io"
- "os"
- "path/filepath"
- "runtime"
- "strconv"
- "strings"
- "sync"
- "syscall"
-)
-
-// Error records the name of a binary that failed to be executed
-// and the reason it failed.
-type Error struct {
- Name string
- Err error
-}
-
-func (e *Error) Error() string {
- return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
-}
-
-// Cmd represents an external command being prepared or run.
-type Cmd struct {
- // Path is the path of the command to run.
- //
- // This is the only field that must be set to a non-zero
- // value. If Path is relative, it is evaluated relative
- // to Dir.
- Path string
-
- // Args holds command line arguments, including the command as Args[0].
- // If the Args field is empty or nil, Run uses {Path}.
- //
- // In typical use, both Path and Args are set by calling Command.
- Args []string
-
- // Env specifies the environment of the process.
- // If Env is nil, Run uses the current process's environment.
- Env []string
-
- // Dir specifies the working directory of the command.
- // If Dir is the empty string, Run runs the command in the
- // calling process's current directory.
- Dir string
-
- // Stdin specifies the process's standard input. If Stdin is
- // nil, the process reads from the null device (os.DevNull).
- Stdin io.Reader
-
- // Stdout and Stderr specify the process's standard output and error.
- //
- // If either is nil, Run connects the corresponding file descriptor
- // to the null device (os.DevNull).
- //
- // If Stdout and Stderr are the same writer, at most one
- // goroutine at a time will call Write.
- Stdout io.Writer
- Stderr io.Writer
-
- // ExtraFiles specifies additional open files to be inherited by the
- // new process. It does not include standard input, standard output, or
- // standard error. If non-nil, entry i becomes file descriptor 3+i.
- //
- // BUG: on OS X 10.6, child processes may sometimes inherit unwanted fds.
- // http://golang.org/issue/2603
- ExtraFiles []*os.File
-
- // SysProcAttr holds optional, operating system-specific attributes.
- // Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
- SysProcAttr *syscall.SysProcAttr
-
- // Process is the underlying process, once started.
- Process *os.Process
-
- // ProcessState contains information about an exited process,
- // available after a call to Wait or Run.
- ProcessState *os.ProcessState
-
- lookPathErr error // LookPath error, if any.
- finished bool // when Wait was called
- childFiles []*os.File
- closeAfterStart []io.Closer
- closeAfterWait []io.Closer
- goroutine []func() error
- errch chan error // one send per goroutine
-}
-
-// Command returns the Cmd struct to execute the named program with
-// the given arguments.
-//
-// It sets only the Path and Args in the returned structure.
-//
-// If name contains no path separators, Command uses LookPath to
-// resolve the path to a complete name if possible. Otherwise it uses
-// name directly.
-//
-// The returned Cmd's Args field is constructed from the command name
-// followed by the elements of arg, so arg should not include the
-// command name itself. For example, Command("echo", "hello")
-func Command(name string, arg ...string) *Cmd {
- cmd := &Cmd{
- Path: name,
- Args: append([]string{name}, arg...),
- }
- if filepath.Base(name) == name {
- if lp, err := LookPath(name); err != nil {
- cmd.lookPathErr = err
- } else {
- cmd.Path = lp
- }
- }
- return cmd
-}
-
-// interfaceEqual protects against panics from doing equality tests on
-// two interfaces with non-comparable underlying types.
-func interfaceEqual(a, b interface{}) bool {
- defer func() {
- recover()
- }()
- return a == b
-}
-
-func (c *Cmd) envv() []string {
- if c.Env != nil {
- return c.Env
- }
- return os.Environ()
-}
-
-func (c *Cmd) argv() []string {
- if len(c.Args) > 0 {
- return c.Args
- }
- return []string{c.Path}
-}
-
-func (c *Cmd) stdin() (f *os.File, err error) {
- if c.Stdin == nil {
- f, err = os.Open(os.DevNull)
- if err != nil {
- return
- }
- c.closeAfterStart = append(c.closeAfterStart, f)
- return
- }
-
- if f, ok := c.Stdin.(*os.File); ok {
- return f, nil
- }
-
- pr, pw, err := os.Pipe()
- if err != nil {
- return
- }
-
- c.closeAfterStart = append(c.closeAfterStart, pr)
- c.closeAfterWait = append(c.closeAfterWait, pw)
- c.goroutine = append(c.goroutine, func() error {
- _, err := io.Copy(pw, c.Stdin)
- if err1 := pw.Close(); err == nil {
- err = err1
- }
- return err
- })
- return pr, nil
-}
-
-func (c *Cmd) stdout() (f *os.File, err error) {
- return c.writerDescriptor(c.Stdout)
-}
-
-func (c *Cmd) stderr() (f *os.File, err error) {
- if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
- return c.childFiles[1], nil
- }
- return c.writerDescriptor(c.Stderr)
-}
-
-func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
- if w == nil {
- f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
- if err != nil {
- return
- }
- c.closeAfterStart = append(c.closeAfterStart, f)
- return
- }
-
- if f, ok := w.(*os.File); ok {
- return f, nil
- }
-
- pr, pw, err := os.Pipe()
- if err != nil {
- return
- }
-
- c.closeAfterStart = append(c.closeAfterStart, pw)
- c.closeAfterWait = append(c.closeAfterWait, pr)
- c.goroutine = append(c.goroutine, func() error {
- _, err := io.Copy(w, pr)
- return err
- })
- return pw, nil
-}
-
-func (c *Cmd) closeDescriptors(closers []io.Closer) {
- for _, fd := range closers {
- fd.Close()
- }
-}
-
-// Run starts the specified command and waits for it to complete.
-//
-// The returned error is nil if the command runs, has no problems
-// copying stdin, stdout, and stderr, and exits with a zero exit
-// status.
-//
-// If the command fails to run or doesn't complete successfully, the
-// error is of type *ExitError. Other error types may be
-// returned for I/O problems.
-func (c *Cmd) Run() error {
- if err := c.Start(); err != nil {
- return err
- }
- return c.Wait()
-}
-
-// lookExtensions finds windows executable by its dir and path.
-// It uses LookPath to try appropriate extensions.
-// lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
-func lookExtensions(path, dir string) (string, error) {
- if filepath.Base(path) == path {
- path = filepath.Join(".", path)
- }
- if dir == "" {
- return LookPath(path)
- }
- if filepath.VolumeName(path) != "" {
- return LookPath(path)
- }
- if len(path) > 1 && os.IsPathSeparator(path[0]) {
- return LookPath(path)
- }
- dirandpath := filepath.Join(dir, path)
- // We assume that LookPath will only add file extension.
- lp, err := LookPath(dirandpath)
- if err != nil {
- return "", err
- }
- ext := strings.TrimPrefix(lp, dirandpath)
- return path + ext, nil
-}
-
-// Start starts the specified command but does not wait for it to complete.
-//
-// The Wait method will return the exit code and release associated resources
-// once the command exits.
-func (c *Cmd) Start() error {
- if c.lookPathErr != nil {
- c.closeDescriptors(c.closeAfterStart)
- c.closeDescriptors(c.closeAfterWait)
- return c.lookPathErr
- }
- if runtime.GOOS == "windows" {
- lp, err := lookExtensions(c.Path, c.Dir)
- if err != nil {
- c.closeDescriptors(c.closeAfterStart)
- c.closeDescriptors(c.closeAfterWait)
- return err
- }
- c.Path = lp
- }
- if c.Process != nil {
- return errors.New("exec: already started")
- }
-
- type F func(*Cmd) (*os.File, error)
- for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
- fd, err := setupFd(c)
- if err != nil {
- c.closeDescriptors(c.closeAfterStart)
- c.closeDescriptors(c.closeAfterWait)
- return err
- }
- c.childFiles = append(c.childFiles, fd)
- }
- c.childFiles = append(c.childFiles, c.ExtraFiles...)
-
- var err error
- c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
- Dir: c.Dir,
- Files: c.childFiles,
- Env: c.envv(),
- Sys: c.SysProcAttr,
- })
- if err != nil {
- c.closeDescriptors(c.closeAfterStart)
- c.closeDescriptors(c.closeAfterWait)
- return err
- }
-
- c.closeDescriptors(c.closeAfterStart)
-
- c.errch = make(chan error, len(c.goroutine))
- for _, fn := range c.goroutine {
- go func(fn func() error) {
- c.errch <- fn()
- }(fn)
- }
-
- return nil
-}
-
-// An ExitError reports an unsuccessful exit by a command.
-type ExitError struct {
- *os.ProcessState
-}
-
-func (e *ExitError) Error() string {
- return e.ProcessState.String()
-}
-
-// Wait waits for the command to exit.
-// It must have been started by Start.
-//
-// The returned error is nil if the command runs, has no problems
-// copying stdin, stdout, and stderr, and exits with a zero exit
-// status.
-//
-// If the command fails to run or doesn't complete successfully, the
-// error is of type *ExitError. Other error types may be
-// returned for I/O problems.
-//
-// Wait releases any resources associated with the Cmd.
-func (c *Cmd) Wait() error {
- if c.Process == nil {
- return errors.New("exec: not started")
- }
- if c.finished {
- return errors.New("exec: Wait was already called")
- }
- c.finished = true
- state, err := c.Process.Wait()
- c.ProcessState = state
-
- var copyError error
- for _ = range c.goroutine {
- if err := <-c.errch; err != nil && copyError == nil {
- copyError = err
- }
- }
-
- c.closeDescriptors(c.closeAfterWait)
-
- if err != nil {
- return err
- } else if !state.Success() {
- return &ExitError{state}
- }
-
- return copyError
-}
-
-// Output runs the command and returns its standard output.
-func (c *Cmd) Output() ([]byte, error) {
- if c.Stdout != nil {
- return nil, errors.New("exec: Stdout already set")
- }
- var b bytes.Buffer
- c.Stdout = &b
- err := c.Run()
- return b.Bytes(), err
-}
-
-// CombinedOutput runs the command and returns its combined standard
-// output and standard error.
-func (c *Cmd) CombinedOutput() ([]byte, error) {
- if c.Stdout != nil {
- return nil, errors.New("exec: Stdout already set")
- }
- if c.Stderr != nil {
- return nil, errors.New("exec: Stderr already set")
- }
- var b bytes.Buffer
- c.Stdout = &b
- c.Stderr = &b
- err := c.Run()
- return b.Bytes(), err
-}
-
-// StdinPipe returns a pipe that will be connected to the command's
-// standard input when the command starts.
-// The pipe will be closed automatically after Wait sees the command exit.
-// A caller need only call Close to force the pipe to close sooner.
-// For example, if the command being run will not exit until standard input
-// is closed, the caller must close the pipe.
-func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
- if c.Stdin != nil {
- return nil, errors.New("exec: Stdin already set")
- }
- if c.Process != nil {
- return nil, errors.New("exec: StdinPipe after process started")
- }
- pr, pw, err := os.Pipe()
- if err != nil {
- return nil, err
- }
- c.Stdin = pr
- c.closeAfterStart = append(c.closeAfterStart, pr)
- wc := &closeOnce{File: pw}
- c.closeAfterWait = append(c.closeAfterWait, wc)
- return wc, nil
-}
-
-type closeOnce struct {
- *os.File
-
- once sync.Once
- err error
-}
-
-func (c *closeOnce) Close() error {
- c.once.Do(c.close)
- return c.err
-}
-
-func (c *closeOnce) close() {
- c.err = c.File.Close()
-}
-
-// StdoutPipe returns a pipe that will be connected to the command's
-// standard output when the command starts.
-//
-// Wait will close the pipe after seeing the command exit, so most callers
-// need not close the pipe themselves; however, an implication is that
-// it is incorrect to call Wait before all reads from the pipe have completed.
-// For the same reason, it is incorrect to call Run when using StdoutPipe.
-// See the example for idiomatic usage.
-func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
- if c.Stdout != nil {
- return nil, errors.New("exec: Stdout already set")
- }
- if c.Process != nil {
- return nil, errors.New("exec: StdoutPipe after process started")
- }
- pr, pw, err := os.Pipe()
- if err != nil {
- return nil, err
- }
- c.Stdout = pw
- c.closeAfterStart = append(c.closeAfterStart, pw)
- c.closeAfterWait = append(c.closeAfterWait, pr)
- return pr, nil
-}
-
-// StderrPipe returns a pipe that will be connected to the command's
-// standard error when the command starts.
-//
-// Wait will close the pipe after seeing the command exit, so most callers
-// need not close the pipe themselves; however, an implication is that
-// it is incorrect to call Wait before all reads from the pipe have completed.
-// For the same reason, it is incorrect to use Run when using StderrPipe.
-// See the StdoutPipe example for idiomatic usage.
-func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
- if c.Stderr != nil {
- return nil, errors.New("exec: Stderr already set")
- }
- if c.Process != nil {
- return nil, errors.New("exec: StderrPipe after process started")
- }
- pr, pw, err := os.Pipe()
- if err != nil {
- return nil, err
- }
- c.Stderr = pw
- c.closeAfterStart = append(c.closeAfterStart, pw)
- c.closeAfterWait = append(c.closeAfterWait, pr)
- return pr, nil
-}
diff --git a/src/pkg/os/exec/exec_test.go b/src/pkg/os/exec/exec_test.go
deleted file mode 100644
index 6f77ac38a..000000000
--- a/src/pkg/os/exec/exec_test.go
+++ /dev/null
@@ -1,726 +0,0 @@
-// 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.
-
-// Use an external test to avoid os/exec -> net/http -> crypto/x509 -> os/exec
-// circular dependency on non-cgo darwin.
-
-package exec_test
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net"
- "net/http"
- "net/http/httptest"
- "os"
- "os/exec"
- "path/filepath"
- "runtime"
- "strconv"
- "strings"
- "testing"
- "time"
-)
-
-func helperCommand(t *testing.T, s ...string) *exec.Cmd {
- if runtime.GOOS == "nacl" {
- t.Skip("skipping on nacl")
- }
- cs := []string{"-test.run=TestHelperProcess", "--"}
- cs = append(cs, s...)
- cmd := exec.Command(os.Args[0], cs...)
- cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
- return cmd
-}
-
-func TestEcho(t *testing.T) {
- bs, err := helperCommand(t, "echo", "foo bar", "baz").Output()
- if err != nil {
- t.Errorf("echo: %v", err)
- }
- if g, e := string(bs), "foo bar baz\n"; g != e {
- t.Errorf("echo: want %q, got %q", e, g)
- }
-}
-
-func TestCommandRelativeName(t *testing.T) {
- // Run our own binary as a relative path
- // (e.g. "_test/exec.test") our parent directory.
- base := filepath.Base(os.Args[0]) // "exec.test"
- dir := filepath.Dir(os.Args[0]) // "/tmp/go-buildNNNN/os/exec/_test"
- if dir == "." {
- t.Skip("skipping; running test at root somehow")
- }
- parentDir := filepath.Dir(dir) // "/tmp/go-buildNNNN/os/exec"
- dirBase := filepath.Base(dir) // "_test"
- if dirBase == "." {
- t.Skipf("skipping; unexpected shallow dir of %q", dir)
- }
-
- cmd := exec.Command(filepath.Join(dirBase, base), "-test.run=TestHelperProcess", "--", "echo", "foo")
- cmd.Dir = parentDir
- cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
-
- out, err := cmd.Output()
- if err != nil {
- t.Errorf("echo: %v", err)
- }
- if g, e := string(out), "foo\n"; g != e {
- t.Errorf("echo: want %q, got %q", e, g)
- }
-}
-
-func TestCatStdin(t *testing.T) {
- // Cat, testing stdin and stdout.
- input := "Input string\nLine 2"
- p := helperCommand(t, "cat")
- p.Stdin = strings.NewReader(input)
- bs, err := p.Output()
- if err != nil {
- t.Errorf("cat: %v", err)
- }
- s := string(bs)
- if s != input {
- t.Errorf("cat: want %q, got %q", input, s)
- }
-}
-
-func TestCatGoodAndBadFile(t *testing.T) {
- // Testing combined output and error values.
- bs, err := helperCommand(t, "cat", "/bogus/file.foo", "exec_test.go").CombinedOutput()
- if _, ok := err.(*exec.ExitError); !ok {
- t.Errorf("expected *exec.ExitError from cat combined; got %T: %v", err, err)
- }
- s := string(bs)
- sp := strings.SplitN(s, "\n", 2)
- if len(sp) != 2 {
- t.Fatalf("expected two lines from cat; got %q", s)
- }
- errLine, body := sp[0], sp[1]
- if !strings.HasPrefix(errLine, "Error: open /bogus/file.foo") {
- t.Errorf("expected stderr to complain about file; got %q", errLine)
- }
- if !strings.Contains(body, "func TestHelperProcess(t *testing.T)") {
- t.Errorf("expected test code; got %q (len %d)", body, len(body))
- }
-}
-
-func TestNoExistBinary(t *testing.T) {
- // Can't run a non-existent binary
- err := exec.Command("/no-exist-binary").Run()
- if err == nil {
- t.Error("expected error from /no-exist-binary")
- }
-}
-
-func TestExitStatus(t *testing.T) {
- // Test that exit values are returned correctly
- cmd := helperCommand(t, "exit", "42")
- err := cmd.Run()
- want := "exit status 42"
- switch runtime.GOOS {
- case "plan9":
- want = fmt.Sprintf("exit status: '%s %d: 42'", filepath.Base(cmd.Path), cmd.ProcessState.Pid())
- }
- if werr, ok := err.(*exec.ExitError); ok {
- if s := werr.Error(); s != want {
- t.Errorf("from exit 42 got exit %q, want %q", s, want)
- }
- } else {
- t.Fatalf("expected *exec.ExitError from exit 42; got %T: %v", err, err)
- }
-}
-
-func TestPipes(t *testing.T) {
- check := func(what string, err error) {
- if err != nil {
- t.Fatalf("%s: %v", what, err)
- }
- }
- // Cat, testing stdin and stdout.
- c := helperCommand(t, "pipetest")
- stdin, err := c.StdinPipe()
- check("StdinPipe", err)
- stdout, err := c.StdoutPipe()
- check("StdoutPipe", err)
- stderr, err := c.StderrPipe()
- check("StderrPipe", err)
-
- outbr := bufio.NewReader(stdout)
- errbr := bufio.NewReader(stderr)
- line := func(what string, br *bufio.Reader) string {
- line, _, err := br.ReadLine()
- if err != nil {
- t.Fatalf("%s: %v", what, err)
- }
- return string(line)
- }
-
- err = c.Start()
- check("Start", err)
-
- _, err = stdin.Write([]byte("O:I am output\n"))
- check("first stdin Write", err)
- if g, e := line("first output line", outbr), "O:I am output"; g != e {
- t.Errorf("got %q, want %q", g, e)
- }
-
- _, err = stdin.Write([]byte("E:I am error\n"))
- check("second stdin Write", err)
- if g, e := line("first error line", errbr), "E:I am error"; g != e {
- t.Errorf("got %q, want %q", g, e)
- }
-
- _, err = stdin.Write([]byte("O:I am output2\n"))
- check("third stdin Write 3", err)
- if g, e := line("second output line", outbr), "O:I am output2"; g != e {
- t.Errorf("got %q, want %q", g, e)
- }
-
- stdin.Close()
- err = c.Wait()
- check("Wait", err)
-}
-
-const stdinCloseTestString = "Some test string."
-
-// Issue 6270.
-func TestStdinClose(t *testing.T) {
- check := func(what string, err error) {
- if err != nil {
- t.Fatalf("%s: %v", what, err)
- }
- }
- cmd := helperCommand(t, "stdinClose")
- stdin, err := cmd.StdinPipe()
- check("StdinPipe", err)
- // Check that we can access methods of the underlying os.File.`
- if _, ok := stdin.(interface {
- Fd() uintptr
- }); !ok {
- t.Error("can't access methods of underlying *os.File")
- }
- check("Start", cmd.Start())
- go func() {
- _, err := io.Copy(stdin, strings.NewReader(stdinCloseTestString))
- check("Copy", err)
- // Before the fix, this next line would race with cmd.Wait.
- check("Close", stdin.Close())
- }()
- check("Wait", cmd.Wait())
-}
-
-// Issue 5071
-func TestPipeLookPathLeak(t *testing.T) {
- fd0, lsof0 := numOpenFDS(t)
- for i := 0; i < 4; i++ {
- cmd := exec.Command("something-that-does-not-exist-binary")
- cmd.StdoutPipe()
- cmd.StderrPipe()
- cmd.StdinPipe()
- if err := cmd.Run(); err == nil {
- t.Fatal("unexpected success")
- }
- }
- for triesLeft := 3; triesLeft >= 0; triesLeft-- {
- open, lsof := numOpenFDS(t)
- fdGrowth := open - fd0
- if fdGrowth > 2 {
- if triesLeft > 0 {
- // Work around what appears to be a race with Linux's
- // proc filesystem (as used by lsof). It seems to only
- // be eventually consistent. Give it awhile to settle.
- // See golang.org/issue/7808
- time.Sleep(100 * time.Millisecond)
- continue
- }
- t.Errorf("leaked %d fds; want ~0; have:\n%s\noriginally:\n%s", fdGrowth, lsof, lsof0)
- }
- break
- }
-}
-
-func numOpenFDS(t *testing.T) (n int, lsof []byte) {
- lsof, err := exec.Command("lsof", "-n", "-p", strconv.Itoa(os.Getpid())).Output()
- if err != nil {
- t.Skip("skipping test; error finding or running lsof")
- }
- return bytes.Count(lsof, []byte("\n")), lsof
-}
-
-var testedAlreadyLeaked = false
-
-// basefds returns the number of expected file descriptors
-// to be present in a process at start.
-func basefds() uintptr {
- n := os.Stderr.Fd() + 1
-
- // Go runtime for 32-bit Plan 9 requires that /dev/bintime
- // be kept open.
- // See ../../runtime/time_plan9_386.c:/^runtime·nanotime
- if runtime.GOOS == "plan9" && runtime.GOARCH == "386" {
- n++
- }
- return n
-}
-
-func closeUnexpectedFds(t *testing.T, m string) {
- for fd := basefds(); fd <= 101; fd++ {
- err := os.NewFile(fd, "").Close()
- if err == nil {
- t.Logf("%s: Something already leaked - closed fd %d", m, fd)
- }
- }
-}
-
-func TestExtraFilesFDShuffle(t *testing.T) {
- t.Skip("flaky test; see http://golang.org/issue/5780")
- switch runtime.GOOS {
- case "darwin":
- // TODO(cnicolaou): http://golang.org/issue/2603
- // leads to leaked file descriptors in this test when it's
- // run from a builder.
- closeUnexpectedFds(t, "TestExtraFilesFDShuffle")
- case "netbsd":
- // http://golang.org/issue/3955
- closeUnexpectedFds(t, "TestExtraFilesFDShuffle")
- case "windows":
- t.Skip("no operating system support; skipping")
- }
-
- // syscall.StartProcess maps all the FDs passed to it in
- // ProcAttr.Files (the concatenation of stdin,stdout,stderr and
- // ExtraFiles) into consecutive FDs in the child, that is:
- // Files{11, 12, 6, 7, 9, 3} should result in the file
- // represented by FD 11 in the parent being made available as 0
- // in the child, 12 as 1, etc.
- //
- // We want to test that FDs in the child do not get overwritten
- // by one another as this shuffle occurs. The original implementation
- // was buggy in that in some data dependent cases it would ovewrite
- // stderr in the child with one of the ExtraFile members.
- // Testing for this case is difficult because it relies on using
- // the same FD values as that case. In particular, an FD of 3
- // must be at an index of 4 or higher in ProcAttr.Files and
- // the FD of the write end of the Stderr pipe (as obtained by
- // StderrPipe()) must be the same as the size of ProcAttr.Files;
- // therefore we test that the read end of this pipe (which is what
- // is returned to the parent by StderrPipe() being one less than
- // the size of ProcAttr.Files, i.e. 3+len(cmd.ExtraFiles).
- //
- // Moving this test case around within the overall tests may
- // affect the FDs obtained and hence the checks to catch these cases.
- npipes := 2
- c := helperCommand(t, "extraFilesAndPipes", strconv.Itoa(npipes+1))
- rd, wr, _ := os.Pipe()
- defer rd.Close()
- if rd.Fd() != 3 {
- t.Errorf("bad test value for test pipe: fd %d", rd.Fd())
- }
- stderr, _ := c.StderrPipe()
- wr.WriteString("_LAST")
- wr.Close()
-
- pipes := make([]struct {
- r, w *os.File
- }, npipes)
- data := []string{"a", "b"}
-
- for i := 0; i < npipes; i++ {
- r, w, err := os.Pipe()
- if err != nil {
- t.Fatalf("unexpected error creating pipe: %s", err)
- }
- pipes[i].r = r
- pipes[i].w = w
- w.WriteString(data[i])
- c.ExtraFiles = append(c.ExtraFiles, pipes[i].r)
- defer func() {
- r.Close()
- w.Close()
- }()
- }
- // Put fd 3 at the end.
- c.ExtraFiles = append(c.ExtraFiles, rd)
-
- stderrFd := int(stderr.(*os.File).Fd())
- if stderrFd != ((len(c.ExtraFiles) + 3) - 1) {
- t.Errorf("bad test value for stderr pipe")
- }
-
- expected := "child: " + strings.Join(data, "") + "_LAST"
-
- err := c.Start()
- if err != nil {
- t.Fatalf("Run: %v", err)
- }
- ch := make(chan string, 1)
- go func(ch chan string) {
- buf := make([]byte, 512)
- n, err := stderr.Read(buf)
- if err != nil {
- t.Fatalf("Read: %s", err)
- ch <- err.Error()
- } else {
- ch <- string(buf[:n])
- }
- close(ch)
- }(ch)
- select {
- case m := <-ch:
- if m != expected {
- t.Errorf("Read: '%s' not '%s'", m, expected)
- }
- case <-time.After(5 * time.Second):
- t.Errorf("Read timedout")
- }
- c.Wait()
-}
-
-func TestExtraFiles(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("no operating system support; skipping")
- }
-
- // Ensure that file descriptors have not already been leaked into
- // our environment.
- if !testedAlreadyLeaked {
- testedAlreadyLeaked = true
- closeUnexpectedFds(t, "TestExtraFiles")
- }
-
- // Force network usage, to verify the epoll (or whatever) fd
- // doesn't leak to the child,
- ln, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- t.Fatal(err)
- }
- defer ln.Close()
-
- // Make sure duplicated fds don't leak to the child.
- f, err := ln.(*net.TCPListener).File()
- if err != nil {
- t.Fatal(err)
- }
- defer f.Close()
- ln2, err := net.FileListener(f)
- if err != nil {
- t.Fatal(err)
- }
- defer ln2.Close()
-
- // Force TLS root certs to be loaded (which might involve
- // cgo), to make sure none of that potential C code leaks fds.
- ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
- // quiet expected TLS handshake error "remote error: bad certificate"
- ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
- ts.StartTLS()
- defer ts.Close()
- _, err = http.Get(ts.URL)
- if err == nil {
- t.Errorf("success trying to fetch %s; want an error", ts.URL)
- }
-
- tf, err := ioutil.TempFile("", "")
- if err != nil {
- t.Fatalf("TempFile: %v", err)
- }
- defer os.Remove(tf.Name())
- defer tf.Close()
-
- const text = "Hello, fd 3!"
- _, err = tf.Write([]byte(text))
- if err != nil {
- t.Fatalf("Write: %v", err)
- }
- _, err = tf.Seek(0, os.SEEK_SET)
- if err != nil {
- t.Fatalf("Seek: %v", err)
- }
-
- c := helperCommand(t, "read3")
- var stdout, stderr bytes.Buffer
- c.Stdout = &stdout
- c.Stderr = &stderr
- c.ExtraFiles = []*os.File{tf}
- err = c.Run()
- if err != nil {
- t.Fatalf("Run: %v; stdout %q, stderr %q", err, stdout.Bytes(), stderr.Bytes())
- }
- if stdout.String() != text {
- t.Errorf("got stdout %q, stderr %q; want %q on stdout", stdout.String(), stderr.String(), text)
- }
-}
-
-func TestExtraFilesRace(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("no operating system support; skipping")
- }
- listen := func() net.Listener {
- ln, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- t.Fatal(err)
- }
- return ln
- }
- listenerFile := func(ln net.Listener) *os.File {
- f, err := ln.(*net.TCPListener).File()
- if err != nil {
- t.Fatal(err)
- }
- return f
- }
- runCommand := func(c *exec.Cmd, out chan<- string) {
- bout, err := c.CombinedOutput()
- if err != nil {
- out <- "ERROR:" + err.Error()
- } else {
- out <- string(bout)
- }
- }
-
- for i := 0; i < 10; i++ {
- la := listen()
- ca := helperCommand(t, "describefiles")
- ca.ExtraFiles = []*os.File{listenerFile(la)}
- lb := listen()
- cb := helperCommand(t, "describefiles")
- cb.ExtraFiles = []*os.File{listenerFile(lb)}
- ares := make(chan string)
- bres := make(chan string)
- go runCommand(ca, ares)
- go runCommand(cb, bres)
- if got, want := <-ares, fmt.Sprintf("fd3: listener %s\n", la.Addr()); got != want {
- t.Errorf("iteration %d, process A got:\n%s\nwant:\n%s\n", i, got, want)
- }
- if got, want := <-bres, fmt.Sprintf("fd3: listener %s\n", lb.Addr()); got != want {
- t.Errorf("iteration %d, process B got:\n%s\nwant:\n%s\n", i, got, want)
- }
- la.Close()
- lb.Close()
- for _, f := range ca.ExtraFiles {
- f.Close()
- }
- for _, f := range cb.ExtraFiles {
- f.Close()
- }
-
- }
-}
-
-// TestHelperProcess isn't a real test. It's used as a helper process
-// for TestParameterRun.
-func TestHelperProcess(*testing.T) {
- if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
- return
- }
- defer os.Exit(0)
-
- // Determine which command to use to display open files.
- ofcmd := "lsof"
- switch runtime.GOOS {
- case "dragonfly", "freebsd", "netbsd", "openbsd":
- ofcmd = "fstat"
- case "plan9":
- ofcmd = "/bin/cat"
- }
-
- args := os.Args
- for len(args) > 0 {
- if args[0] == "--" {
- args = args[1:]
- break
- }
- args = args[1:]
- }
- if len(args) == 0 {
- fmt.Fprintf(os.Stderr, "No command\n")
- os.Exit(2)
- }
-
- cmd, args := args[0], args[1:]
- switch cmd {
- case "echo":
- iargs := []interface{}{}
- for _, s := range args {
- iargs = append(iargs, s)
- }
- fmt.Println(iargs...)
- case "cat":
- if len(args) == 0 {
- io.Copy(os.Stdout, os.Stdin)
- return
- }
- exit := 0
- for _, fn := range args {
- f, err := os.Open(fn)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error: %v\n", err)
- exit = 2
- } else {
- defer f.Close()
- io.Copy(os.Stdout, f)
- }
- }
- os.Exit(exit)
- case "pipetest":
- bufr := bufio.NewReader(os.Stdin)
- for {
- line, _, err := bufr.ReadLine()
- if err == io.EOF {
- break
- } else if err != nil {
- os.Exit(1)
- }
- if bytes.HasPrefix(line, []byte("O:")) {
- os.Stdout.Write(line)
- os.Stdout.Write([]byte{'\n'})
- } else if bytes.HasPrefix(line, []byte("E:")) {
- os.Stderr.Write(line)
- os.Stderr.Write([]byte{'\n'})
- } else {
- os.Exit(1)
- }
- }
- case "stdinClose":
- b, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error: %v\n", err)
- os.Exit(1)
- }
- if s := string(b); s != stdinCloseTestString {
- fmt.Fprintf(os.Stderr, "Error: Read %q, want %q", s, stdinCloseTestString)
- os.Exit(1)
- }
- os.Exit(0)
- case "read3": // read fd 3
- fd3 := os.NewFile(3, "fd3")
- bs, err := ioutil.ReadAll(fd3)
- if err != nil {
- fmt.Printf("ReadAll from fd 3: %v", err)
- os.Exit(1)
- }
- switch runtime.GOOS {
- case "dragonfly":
- // TODO(jsing): Determine why DragonFly is leaking
- // file descriptors...
- case "darwin":
- // TODO(bradfitz): broken? Sometimes.
- // http://golang.org/issue/2603
- // Skip this additional part of the test for now.
- case "netbsd":
- // TODO(jsing): This currently fails on NetBSD due to
- // the cloned file descriptors that result from opening
- // /dev/urandom.
- // http://golang.org/issue/3955
- case "plan9":
- // TODO(0intro): Determine why Plan 9 is leaking
- // file descriptors.
- // http://golang.org/issue/7118
- case "solaris":
- // TODO(aram): This fails on Solaris because libc opens
- // its own files, as it sees fit. Darwin does the same,
- // see: http://golang.org/issue/2603
- default:
- // Now verify that there are no other open fds.
- var files []*os.File
- for wantfd := basefds() + 1; wantfd <= 100; wantfd++ {
- f, err := os.Open(os.Args[0])
- if err != nil {
- fmt.Printf("error opening file with expected fd %d: %v", wantfd, err)
- os.Exit(1)
- }
- if got := f.Fd(); got != wantfd {
- fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd)
- var args []string
- switch runtime.GOOS {
- case "plan9":
- args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())}
- default:
- args = []string{"-p", fmt.Sprint(os.Getpid())}
- }
- out, _ := exec.Command(ofcmd, args...).CombinedOutput()
- fmt.Print(string(out))
- os.Exit(1)
- }
- files = append(files, f)
- }
- for _, f := range files {
- f.Close()
- }
- }
- // Referring to fd3 here ensures that it is not
- // garbage collected, and therefore closed, while
- // executing the wantfd loop above. It doesn't matter
- // what we do with fd3 as long as we refer to it;
- // closing it is the easy choice.
- fd3.Close()
- os.Stdout.Write(bs)
- case "exit":
- n, _ := strconv.Atoi(args[0])
- os.Exit(n)
- case "describefiles":
- f := os.NewFile(3, fmt.Sprintf("fd3"))
- ln, err := net.FileListener(f)
- if err == nil {
- fmt.Printf("fd3: listener %s\n", ln.Addr())
- ln.Close()
- }
- os.Exit(0)
- case "extraFilesAndPipes":
- n, _ := strconv.Atoi(args[0])
- pipes := make([]*os.File, n)
- for i := 0; i < n; i++ {
- pipes[i] = os.NewFile(uintptr(3+i), strconv.Itoa(i))
- }
- response := ""
- for i, r := range pipes {
- ch := make(chan string, 1)
- go func(c chan string) {
- buf := make([]byte, 10)
- n, err := r.Read(buf)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Child: read error: %v on pipe %d\n", err, i)
- os.Exit(1)
- }
- c <- string(buf[:n])
- close(c)
- }(ch)
- select {
- case m := <-ch:
- response = response + m
- case <-time.After(5 * time.Second):
- fmt.Fprintf(os.Stderr, "Child: Timeout reading from pipe: %d\n", i)
- os.Exit(1)
- }
- }
- fmt.Fprintf(os.Stderr, "child: %s", response)
- os.Exit(0)
- case "exec":
- cmd := exec.Command(args[1])
- cmd.Dir = args[0]
- output, err := cmd.CombinedOutput()
- if err != nil {
- fmt.Fprintf(os.Stderr, "Child: %s %s", err, string(output))
- os.Exit(1)
- }
- fmt.Printf("%s", string(output))
- os.Exit(0)
- case "lookpath":
- p, err := exec.LookPath(args[0])
- if err != nil {
- fmt.Fprintf(os.Stderr, "LookPath failed: %v\n", err)
- os.Exit(1)
- }
- fmt.Print(p)
- os.Exit(0)
- default:
- fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
- os.Exit(2)
- }
-}
diff --git a/src/pkg/os/exec/lp_plan9.go b/src/pkg/os/exec/lp_plan9.go
deleted file mode 100644
index 5aa8a54ed..000000000
--- a/src/pkg/os/exec/lp_plan9.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2011 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.
-
-package exec
-
-import (
- "errors"
- "os"
- "strings"
-)
-
-// ErrNotFound is the error resulting if a path search failed to find an executable file.
-var ErrNotFound = errors.New("executable file not found in $path")
-
-func findExecutable(file string) error {
- d, err := os.Stat(file)
- if err != nil {
- return err
- }
- if m := d.Mode(); !m.IsDir() && m&0111 != 0 {
- return nil
- }
- return os.ErrPermission
-}
-
-// LookPath searches for an executable binary named file
-// in the directories named by the path environment variable.
-// If file begins with "/", "#", "./", or "../", it is tried
-// directly and the path is not consulted.
-// The result may be an absolute path or a path relative to the current directory.
-func LookPath(file string) (string, error) {
- // skip the path lookup for these prefixes
- skip := []string{"/", "#", "./", "../"}
-
- for _, p := range skip {
- if strings.HasPrefix(file, p) {
- err := findExecutable(file)
- if err == nil {
- return file, nil
- }
- return "", &Error{file, err}
- }
- }
-
- path := os.Getenv("path")
- for _, dir := range strings.Split(path, "\000") {
- if err := findExecutable(dir + "/" + file); err == nil {
- return dir + "/" + file, nil
- }
- }
- return "", &Error{file, ErrNotFound}
-}
diff --git a/src/pkg/os/exec/lp_test.go b/src/pkg/os/exec/lp_test.go
deleted file mode 100644
index 77d8e848c..000000000
--- a/src/pkg/os/exec/lp_test.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2011 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.
-
-package exec
-
-import (
- "testing"
-)
-
-var nonExistentPaths = []string{
- "some-non-existent-path",
- "non-existent-path/slashed",
-}
-
-func TestLookPathNotFound(t *testing.T) {
- for _, name := range nonExistentPaths {
- path, err := LookPath(name)
- if err == nil {
- t.Fatalf("LookPath found %q in $PATH", name)
- }
- if path != "" {
- t.Fatalf("LookPath path == %q when err != nil", path)
- }
- perr, ok := err.(*Error)
- if !ok {
- t.Fatal("LookPath error is not an exec.Error")
- }
- if perr.Name != name {
- t.Fatalf("want Error name %q, got %q", name, perr.Name)
- }
- }
-}
diff --git a/src/pkg/os/exec/lp_unix.go b/src/pkg/os/exec/lp_unix.go
deleted file mode 100644
index 3f895d5b3..000000000
--- a/src/pkg/os/exec/lp_unix.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2010 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package exec
-
-import (
- "errors"
- "os"
- "strings"
-)
-
-// ErrNotFound is the error resulting if a path search failed to find an executable file.
-var ErrNotFound = errors.New("executable file not found in $PATH")
-
-func findExecutable(file string) error {
- d, err := os.Stat(file)
- if err != nil {
- return err
- }
- if m := d.Mode(); !m.IsDir() && m&0111 != 0 {
- return nil
- }
- return os.ErrPermission
-}
-
-// LookPath searches for an executable binary named file
-// in the directories named by the PATH environment variable.
-// If file contains a slash, it is tried directly and the PATH is not consulted.
-// The result may be an absolute path or a path relative to the current directory.
-func LookPath(file string) (string, error) {
- // NOTE(rsc): I wish we could use the Plan 9 behavior here
- // (only bypass the path if file begins with / or ./ or ../)
- // but that would not match all the Unix shells.
-
- if strings.Contains(file, "/") {
- err := findExecutable(file)
- if err == nil {
- return file, nil
- }
- return "", &Error{file, err}
- }
- pathenv := os.Getenv("PATH")
- if pathenv == "" {
- return "", &Error{file, ErrNotFound}
- }
- for _, dir := range strings.Split(pathenv, ":") {
- if dir == "" {
- // Unix shell semantics: path element "" means "."
- dir = "."
- }
- path := dir + "/" + file
- if err := findExecutable(path); err == nil {
- return path, nil
- }
- }
- return "", &Error{file, ErrNotFound}
-}
diff --git a/src/pkg/os/exec/lp_unix_test.go b/src/pkg/os/exec/lp_unix_test.go
deleted file mode 100644
index 051db664a..000000000
--- a/src/pkg/os/exec/lp_unix_test.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2013 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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package exec
-
-import (
- "io/ioutil"
- "os"
- "testing"
-)
-
-func TestLookPathUnixEmptyPath(t *testing.T) {
- tmp, err := ioutil.TempDir("", "TestLookPathUnixEmptyPath")
- if err != nil {
- t.Fatal("TempDir failed: ", err)
- }
- defer os.RemoveAll(tmp)
- wd, err := os.Getwd()
- if err != nil {
- t.Fatal("Getwd failed: ", err)
- }
- err = os.Chdir(tmp)
- if err != nil {
- t.Fatal("Chdir failed: ", err)
- }
- defer os.Chdir(wd)
-
- f, err := os.OpenFile("exec_me", os.O_CREATE|os.O_EXCL, 0700)
- if err != nil {
- t.Fatal("OpenFile failed: ", err)
- }
- err = f.Close()
- if err != nil {
- t.Fatal("Close failed: ", err)
- }
-
- pathenv := os.Getenv("PATH")
- defer os.Setenv("PATH", pathenv)
-
- err = os.Setenv("PATH", "")
- if err != nil {
- t.Fatal("Setenv failed: ", err)
- }
-
- path, err := LookPath("exec_me")
- if err == nil {
- t.Fatal("LookPath found exec_me in empty $PATH")
- }
- if path != "" {
- t.Fatalf("LookPath path == %q when err != nil", path)
- }
-}
diff --git a/src/pkg/os/exec/lp_windows.go b/src/pkg/os/exec/lp_windows.go
deleted file mode 100644
index c3efd67e9..000000000
--- a/src/pkg/os/exec/lp_windows.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2010 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.
-
-package exec
-
-import (
- "errors"
- "os"
- "strings"
-)
-
-// ErrNotFound is the error resulting if a path search failed to find an executable file.
-var ErrNotFound = errors.New("executable file not found in %PATH%")
-
-func chkStat(file string) error {
- d, err := os.Stat(file)
- if err != nil {
- return err
- }
- if d.IsDir() {
- return os.ErrPermission
- }
- return nil
-}
-
-func hasExt(file string) bool {
- i := strings.LastIndex(file, ".")
- if i < 0 {
- return false
- }
- return strings.LastIndexAny(file, `:\/`) < i
-}
-
-func findExecutable(file string, exts []string) (string, error) {
- if len(exts) == 0 {
- return file, chkStat(file)
- }
- if hasExt(file) {
- if chkStat(file) == nil {
- return file, nil
- }
- }
- for _, e := range exts {
- if f := file + e; chkStat(f) == nil {
- return f, nil
- }
- }
- return ``, os.ErrNotExist
-}
-
-// LookPath searches for an executable binary named file
-// in the directories named by the PATH environment variable.
-// If file contains a slash, it is tried directly and the PATH is not consulted.
-// LookPath also uses PATHEXT environment variable to match
-// a suitable candidate.
-// The result may be an absolute path or a path relative to the current directory.
-func LookPath(file string) (f string, err error) {
- x := os.Getenv(`PATHEXT`)
- if x == `` {
- x = `.COM;.EXE;.BAT;.CMD`
- }
- exts := []string{}
- for _, e := range strings.Split(strings.ToLower(x), `;`) {
- if e == "" {
- continue
- }
- if e[0] != '.' {
- e = "." + e
- }
- exts = append(exts, e)
- }
- if strings.IndexAny(file, `:\/`) != -1 {
- if f, err = findExecutable(file, exts); err == nil {
- return
- }
- return ``, &Error{file, err}
- }
- if f, err = findExecutable(`.\`+file, exts); err == nil {
- return
- }
- if pathenv := os.Getenv(`PATH`); pathenv != `` {
- for _, dir := range splitList(pathenv) {
- if f, err = findExecutable(dir+`\`+file, exts); err == nil {
- return
- }
- }
- }
- return ``, &Error{file, ErrNotFound}
-}
-
-func splitList(path string) []string {
- // The same implementation is used in SplitList in path/filepath;
- // consider changing path/filepath when changing this.
-
- if path == "" {
- return []string{}
- }
-
- // Split path, respecting but preserving quotes.
- list := []string{}
- start := 0
- quo := false
- for i := 0; i < len(path); i++ {
- switch c := path[i]; {
- case c == '"':
- quo = !quo
- case c == os.PathListSeparator && !quo:
- list = append(list, path[start:i])
- start = i + 1
- }
- }
- list = append(list, path[start:])
-
- // Remove quotes.
- for i, s := range list {
- if strings.Contains(s, `"`) {
- list[i] = strings.Replace(s, `"`, ``, -1)
- }
- }
-
- return list
-}
diff --git a/src/pkg/os/exec/lp_windows_test.go b/src/pkg/os/exec/lp_windows_test.go
deleted file mode 100644
index 72df03ed2..000000000
--- a/src/pkg/os/exec/lp_windows_test.go
+++ /dev/null
@@ -1,573 +0,0 @@
-// Copyright 2013 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.
-
-package exec
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "testing"
-)
-
-func installExe(t *testing.T, dest, src string) {
- fsrc, err := os.Open(src)
- if err != nil {
- t.Fatal("os.Open failed: ", err)
- }
- defer fsrc.Close()
- fdest, err := os.Create(dest)
- if err != nil {
- t.Fatal("os.Create failed: ", err)
- }
- defer fdest.Close()
- _, err = io.Copy(fdest, fsrc)
- if err != nil {
- t.Fatal("io.Copy failed: ", err)
- }
-}
-
-func installBat(t *testing.T, dest string) {
- f, err := os.Create(dest)
- if err != nil {
- t.Fatalf("failed to create batch file: %v", err)
- }
- defer f.Close()
- fmt.Fprintf(f, "@echo %s\n", dest)
-}
-
-func installProg(t *testing.T, dest, srcExe string) {
- err := os.MkdirAll(filepath.Dir(dest), 0700)
- if err != nil {
- t.Fatal("os.MkdirAll failed: ", err)
- }
- if strings.ToLower(filepath.Ext(dest)) == ".bat" {
- installBat(t, dest)
- return
- }
- installExe(t, dest, srcExe)
-}
-
-type lookPathTest struct {
- rootDir string
- PATH string
- PATHEXT string
- files []string
- searchFor string
- fails bool // test is expected to fail
-}
-
-func (test lookPathTest) runProg(t *testing.T, env []string, args ...string) (string, error) {
- cmd := Command(args[0], args[1:]...)
- cmd.Env = env
- cmd.Dir = test.rootDir
- args[0] = filepath.Base(args[0])
- cmdText := fmt.Sprintf("%q command", strings.Join(args, " "))
- out, err := cmd.CombinedOutput()
- if (err != nil) != test.fails {
- if test.fails {
- t.Fatalf("test=%+v: %s succeeded, but expected to fail", test, cmdText)
- }
- t.Fatalf("test=%+v: %s failed, but expected to succeed: %v - %v", test, cmdText, err, string(out))
- }
- if err != nil {
- return "", fmt.Errorf("test=%+v: %s failed: %v - %v", test, cmdText, err, string(out))
- }
- // normalise program output
- p := string(out)
- // trim terminating \r and \n that batch file outputs
- for len(p) > 0 && (p[len(p)-1] == '\n' || p[len(p)-1] == '\r') {
- p = p[:len(p)-1]
- }
- if !filepath.IsAbs(p) {
- return p, nil
- }
- if p[:len(test.rootDir)] != test.rootDir {
- t.Fatalf("test=%+v: %s output is wrong: %q must have %q prefix", test, cmdText, p, test.rootDir)
- }
- return p[len(test.rootDir)+1:], nil
-}
-
-func updateEnv(env []string, name, value string) []string {
- for i, e := range env {
- if strings.HasPrefix(strings.ToUpper(e), name+"=") {
- env[i] = name + "=" + value
- return env
- }
- }
- return append(env, name+"="+value)
-}
-
-func createEnv(dir, PATH, PATHEXT string) []string {
- env := os.Environ()
- env = updateEnv(env, "PATHEXT", PATHEXT)
- // Add dir in front of every directory in the PATH.
- dirs := splitList(PATH)
- for i := range dirs {
- dirs[i] = filepath.Join(dir, dirs[i])
- }
- path := strings.Join(dirs, ";")
- env = updateEnv(env, "PATH", path)
- return env
-}
-
-// createFiles copies srcPath file into multiply files.
-// It uses dir as preifx for all destination files.
-func createFiles(t *testing.T, dir string, files []string, srcPath string) {
- for _, f := range files {
- installProg(t, filepath.Join(dir, f), srcPath)
- }
-}
-
-func (test lookPathTest) run(t *testing.T, tmpdir, printpathExe string) {
- test.rootDir = tmpdir
- createFiles(t, test.rootDir, test.files, printpathExe)
- env := createEnv(test.rootDir, test.PATH, test.PATHEXT)
- // Run "cmd.exe /c test.searchFor" with new environment and
- // work directory set. All candidates are copies of printpath.exe.
- // These will output their program paths when run.
- should, errCmd := test.runProg(t, env, "cmd", "/c", test.searchFor)
- // Run the lookpath program with new environment and work directory set.
- env = append(env, "GO_WANT_HELPER_PROCESS=1")
- have, errLP := test.runProg(t, env, os.Args[0], "-test.run=TestHelperProcess", "--", "lookpath", test.searchFor)
- // Compare results.
- if errCmd == nil && errLP == nil {
- // both succeeded
- if should != have {
- t.Fatalf("test=%+v failed: expected to find %q, but found %q", test, should, have)
- }
- return
- }
- if errCmd != nil && errLP != nil {
- // both failed -> continue
- return
- }
- if errCmd != nil {
- t.Fatal(errCmd)
- }
- if errLP != nil {
- t.Fatal(errLP)
- }
-}
-
-var lookPathTests = []lookPathTest{
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\a.exe`, `p2\a`},
- searchFor: `a`,
- },
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1.dir;p2.dir`,
- files: []string{`p1.dir\a`, `p2.dir\a.exe`},
- searchFor: `a`,
- },
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\a.exe`},
- searchFor: `a.exe`,
- },
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\b.exe`},
- searchFor: `b`,
- },
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\b`, `p2\a`},
- searchFor: `a`,
- fails: true, // TODO(brainman): do not know why this fails
- },
- // If the command name specifies a path, the shell searches
- // the specified path for an executable file matching
- // the command name. If a match is found, the external
- // command (the executable file) executes.
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\a.exe`},
- searchFor: `p2\a`,
- },
- // If the command name specifies a path, the shell searches
- // the specified path for an executable file matching the command
- // name. ... If no match is found, the shell reports an error
- // and command processing completes.
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\b.exe`, `p2\a.exe`},
- searchFor: `p2\b`,
- fails: true,
- },
- // If the command name does not specify a path, the shell
- // searches the current directory for an executable file
- // matching the command name. If a match is found, the external
- // command (the executable file) executes.
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`a`, `p1\a.exe`, `p2\a.exe`},
- searchFor: `a`,
- },
- // The shell now searches each directory specified by the
- // PATH environment variable, in the order listed, for an
- // executable file matching the command name. If a match
- // is found, the external command (the executable file) executes.
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\a.exe`},
- searchFor: `a`,
- },
- // The shell now searches each directory specified by the
- // PATH environment variable, in the order listed, for an
- // executable file matching the command name. If no match
- // is found, the shell reports an error and command processing
- // completes.
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\a.exe`},
- searchFor: `b`,
- fails: true,
- },
- // If the command name includes a file extension, the shell
- // searches each directory for the exact file name specified
- // by the command name.
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\a.exe`},
- searchFor: `a.exe`,
- },
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\a.exe`},
- searchFor: `a.com`,
- fails: true, // includes extension and not exact file name match
- },
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1`,
- files: []string{`p1\a.exe.exe`},
- searchFor: `a.exe`,
- },
- {
- PATHEXT: `.COM;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.exe`, `p2\a.exe`},
- searchFor: `a.exe`,
- },
- // If the command name does not include a file extension, the shell
- // adds the extensions listed in the PATHEXT environment variable,
- // one by one, and searches the directory for that file name. Note
- // that the shell tries all possible file extensions in a specific
- // directory before moving on to search the next directory
- // (if there is one).
- {
- PATHEXT: `.COM;.EXE`,
- PATH: `p1;p2`,
- files: []string{`p1\a.bat`, `p2\a.exe`},
- searchFor: `a`,
- },
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.bat`, `p2\a.exe`},
- searchFor: `a`,
- },
- {
- PATHEXT: `.COM;.EXE;.BAT`,
- PATH: `p1;p2`,
- files: []string{`p1\a.bat`, `p1\a.exe`, `p2\a.bat`, `p2\a.exe`},
- searchFor: `a`,
- },
- {
- PATHEXT: `.COM`,
- PATH: `p1;p2`,
- files: []string{`p1\a.bat`, `p2\a.exe`},
- searchFor: `a`,
- fails: true, // tried all extensions in PATHEXT, but none matches
- },
-}
-
-func TestLookPath(t *testing.T) {
- tmp, err := ioutil.TempDir("", "TestLookPath")
- if err != nil {
- t.Fatal("TempDir failed: ", err)
- }
- defer os.RemoveAll(tmp)
-
- printpathExe := buildPrintPathExe(t, tmp)
-
- // Run all tests.
- for i, test := range lookPathTests {
- dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
- err := os.Mkdir(dir, 0700)
- if err != nil {
- t.Fatal("Mkdir failed: ", err)
- }
- test.run(t, dir, printpathExe)
- }
-}
-
-type commandTest struct {
- PATH string
- files []string
- dir string
- arg0 string
- want string
- fails bool // test is expected to fail
-}
-
-func (test commandTest) isSuccess(rootDir, output string, err error) error {
- if err != nil {
- return fmt.Errorf("test=%+v: exec: %v %v", test, err, output)
- }
- path := output
- if path[:len(rootDir)] != rootDir {
- return fmt.Errorf("test=%+v: %q must have %q prefix", test, path, rootDir)
- }
- path = path[len(rootDir)+1:]
- if path != test.want {
- return fmt.Errorf("test=%+v: want %q, got %q", test, test.want, path)
- }
- return nil
-}
-
-func (test commandTest) runOne(rootDir string, env []string, dir, arg0 string) error {
- cmd := Command(os.Args[0], "-test.run=TestHelperProcess", "--", "exec", dir, arg0)
- cmd.Dir = rootDir
- cmd.Env = env
- output, err := cmd.CombinedOutput()
- err = test.isSuccess(rootDir, string(output), err)
- if (err != nil) != test.fails {
- if test.fails {
- return fmt.Errorf("test=%+v: succeeded, but expected to fail", test)
- }
- return err
- }
- return nil
-}
-
-func (test commandTest) run(t *testing.T, rootDir, printpathExe string) {
- createFiles(t, rootDir, test.files, printpathExe)
- PATHEXT := `.COM;.EXE;.BAT`
- env := createEnv(rootDir, test.PATH, PATHEXT)
- env = append(env, "GO_WANT_HELPER_PROCESS=1")
- err := test.runOne(rootDir, env, test.dir, test.arg0)
- if err != nil {
- t.Error(err)
- }
-}
-
-var commandTests = []commandTest{
- // testing commands with no slash, like `a.exe`
- {
- // should find a.exe in current directory
- files: []string{`a.exe`},
- arg0: `a.exe`,
- want: `a.exe`,
- },
- {
- // like above, but add PATH in attempt to break the test
- PATH: `p2;p`,
- files: []string{`a.exe`, `p\a.exe`, `p2\a.exe`},
- arg0: `a.exe`,
- want: `a.exe`,
- },
- {
- // like above, but use "a" instead of "a.exe" for command
- PATH: `p2;p`,
- files: []string{`a.exe`, `p\a.exe`, `p2\a.exe`},
- arg0: `a`,
- want: `a.exe`,
- },
- // testing commands with slash, like `.\a.exe`
- {
- // should find p\a.exe
- files: []string{`p\a.exe`},
- arg0: `p\a.exe`,
- want: `p\a.exe`,
- },
- {
- // like above, but adding `.` in front of executable should still be OK
- files: []string{`p\a.exe`},
- arg0: `.\p\a.exe`,
- want: `p\a.exe`,
- },
- {
- // like above, but with PATH added in attempt to break it
- PATH: `p2`,
- files: []string{`p\a.exe`, `p2\a.exe`},
- arg0: `p\a.exe`,
- want: `p\a.exe`,
- },
- {
- // like above, but make sure .exe is tried even for commands with slash
- PATH: `p2`,
- files: []string{`p\a.exe`, `p2\a.exe`},
- arg0: `p\a`,
- want: `p\a.exe`,
- },
- // tests commands, like `a.exe`, with c.Dir set
- {
- // should not find a.exe in p, becasue LookPath(`a.exe`) will fail
- files: []string{`p\a.exe`},
- dir: `p`,
- arg0: `a.exe`,
- want: `p\a.exe`,
- fails: true,
- },
- {
- // LookPath(`a.exe`) will find `.\a.exe`, but prefixing that with
- // dir `p\a.exe` will refer to not existant file
- files: []string{`a.exe`, `p\not_important_file`},
- dir: `p`,
- arg0: `a.exe`,
- want: `a.exe`,
- fails: true,
- },
- {
- // like above, but making test succeed by installing file
- // in refered destination (so LookPath(`a.exe`) will still
- // find `.\a.exe`, but we successfully execute `p\a.exe`)
- files: []string{`a.exe`, `p\a.exe`},
- dir: `p`,
- arg0: `a.exe`,
- want: `p\a.exe`,
- },
- {
- // like above, but add PATH in attempt to break the test
- PATH: `p2;p`,
- files: []string{`a.exe`, `p\a.exe`, `p2\a.exe`},
- dir: `p`,
- arg0: `a.exe`,
- want: `p\a.exe`,
- },
- {
- // like above, but use "a" instead of "a.exe" for command
- PATH: `p2;p`,
- files: []string{`a.exe`, `p\a.exe`, `p2\a.exe`},
- dir: `p`,
- arg0: `a`,
- want: `p\a.exe`,
- },
- {
- // finds `a.exe` in the PATH regardless of dir set
- // because LookPath returns full path in that case
- PATH: `p2;p`,
- files: []string{`p\a.exe`, `p2\a.exe`},
- dir: `p`,
- arg0: `a.exe`,
- want: `p2\a.exe`,
- },
- // tests commands, like `.\a.exe`, with c.Dir set
- {
- // should use dir when command is path, like ".\a.exe"
- files: []string{`p\a.exe`},
- dir: `p`,
- arg0: `.\a.exe`,
- want: `p\a.exe`,
- },
- {
- // like above, but with PATH added in attempt to break it
- PATH: `p2`,
- files: []string{`p\a.exe`, `p2\a.exe`},
- dir: `p`,
- arg0: `.\a.exe`,
- want: `p\a.exe`,
- },
- {
- // like above, but make sure .exe is tried even for commands with slash
- PATH: `p2`,
- files: []string{`p\a.exe`, `p2\a.exe`},
- dir: `p`,
- arg0: `.\a`,
- want: `p\a.exe`,
- },
-}
-
-func TestCommand(t *testing.T) {
- tmp, err := ioutil.TempDir("", "TestCommand")
- if err != nil {
- t.Fatal("TempDir failed: ", err)
- }
- defer os.RemoveAll(tmp)
-
- printpathExe := buildPrintPathExe(t, tmp)
-
- // Run all tests.
- for i, test := range commandTests {
- dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
- err := os.Mkdir(dir, 0700)
- if err != nil {
- t.Fatal("Mkdir failed: ", err)
- }
- test.run(t, dir, printpathExe)
- }
-}
-
-// buildPrintPathExe creates a Go program that prints its own path.
-// dir is a temp directory where executable will be created.
-// The function returns full path to the created program.
-func buildPrintPathExe(t *testing.T, dir string) string {
- const name = "printpath"
- srcname := name + ".go"
- err := ioutil.WriteFile(filepath.Join(dir, srcname), []byte(printpathSrc), 0644)
- if err != nil {
- t.Fatalf("failed to create source: %v", err)
- }
- if err != nil {
- t.Fatalf("failed to execute template: %v", err)
- }
- outname := name + ".exe"
- cmd := Command("go", "build", "-o", outname, srcname)
- cmd.Dir = dir
- out, err := cmd.CombinedOutput()
- if err != nil {
- t.Fatalf("failed to build executable: %v - %v", err, string(out))
- }
- return filepath.Join(dir, outname)
-}
-
-const printpathSrc = `
-package main
-
-import (
- "os"
- "syscall"
- "unicode/utf16"
- "unsafe"
-)
-
-func getMyName() (string, error) {
- var sysproc = syscall.MustLoadDLL("kernel32.dll").MustFindProc("GetModuleFileNameW")
- b := make([]uint16, syscall.MAX_PATH)
- r, _, err := sysproc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)))
- n := uint32(r)
- if n == 0 {
- return "", err
- }
- return string(utf16.Decode(b[0:n])), nil
-}
-
-func main() {
- path, err := getMyName()
- if err != nil {
- os.Stderr.Write([]byte("getMyName failed: " + err.Error() + "\n"))
- os.Exit(1)
- }
- os.Stdout.Write([]byte(path))
-}
-`
diff --git a/src/pkg/os/exec_plan9.go b/src/pkg/os/exec_plan9.go
deleted file mode 100644
index 676be36ac..000000000
--- a/src/pkg/os/exec_plan9.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// 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.
-
-package os
-
-import (
- "errors"
- "runtime"
- "syscall"
- "time"
-)
-
-// The only signal values guaranteed to be present on all systems
-// are Interrupt (send the process an interrupt) and Kill (force
-// the process to exit).
-var (
- Interrupt Signal = syscall.Note("interrupt")
- Kill Signal = syscall.Note("kill")
-)
-
-func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
- sysattr := &syscall.ProcAttr{
- Dir: attr.Dir,
- Env: attr.Env,
- Sys: attr.Sys,
- }
-
- for _, f := range attr.Files {
- sysattr.Files = append(sysattr.Files, f.Fd())
- }
-
- pid, h, e := syscall.StartProcess(name, argv, sysattr)
- if e != nil {
- return nil, &PathError{"fork/exec", name, e}
- }
-
- return newProcess(pid, h), nil
-}
-
-func (p *Process) writeProcFile(file string, data string) error {
- f, e := OpenFile("/proc/"+itoa(p.Pid)+"/"+file, O_WRONLY, 0)
- if e != nil {
- return e
- }
- defer f.Close()
- _, e = f.Write([]byte(data))
- return e
-}
-
-func (p *Process) signal(sig Signal) error {
- if p.done() {
- return errors.New("os: process already finished")
- }
- if e := p.writeProcFile("note", sig.String()); e != nil {
- return NewSyscallError("signal", e)
- }
- return nil
-}
-
-func (p *Process) kill() error {
- return p.signal(Kill)
-}
-
-func (p *Process) wait() (ps *ProcessState, err error) {
- var waitmsg syscall.Waitmsg
-
- if p.Pid == -1 {
- return nil, ErrInvalid
- }
- err = syscall.WaitProcess(p.Pid, &waitmsg)
- if err != nil {
- return nil, NewSyscallError("wait", err)
- }
-
- p.setDone()
- ps = &ProcessState{
- pid: waitmsg.Pid,
- status: &waitmsg,
- }
- return ps, nil
-}
-
-func (p *Process) release() error {
- // NOOP for Plan 9.
- p.Pid = -1
- // no need for a finalizer anymore
- runtime.SetFinalizer(p, nil)
- return nil
-}
-
-func findProcess(pid int) (p *Process, err error) {
- // NOOP for Plan 9.
- return newProcess(pid, 0), nil
-}
-
-// ProcessState stores information about a process, as reported by Wait.
-type ProcessState struct {
- pid int // The process's id.
- status *syscall.Waitmsg // System-dependent status info.
-}
-
-// Pid returns the process id of the exited process.
-func (p *ProcessState) Pid() int {
- return p.pid
-}
-
-func (p *ProcessState) exited() bool {
- return p.status.Exited()
-}
-
-func (p *ProcessState) success() bool {
- return p.status.ExitStatus() == 0
-}
-
-func (p *ProcessState) sys() interface{} {
- return p.status
-}
-
-func (p *ProcessState) sysUsage() interface{} {
- return p.status
-}
-
-func (p *ProcessState) userTime() time.Duration {
- return time.Duration(p.status.Time[0]) * time.Millisecond
-}
-
-func (p *ProcessState) systemTime() time.Duration {
- return time.Duration(p.status.Time[1]) * time.Millisecond
-}
-
-func (p *ProcessState) String() string {
- if p == nil {
- return "<nil>"
- }
- return "exit status: " + p.status.Msg
-}
diff --git a/src/pkg/os/exec_posix.go b/src/pkg/os/exec_posix.go
deleted file mode 100644
index fb9d291e6..000000000
--- a/src/pkg/os/exec_posix.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package os
-
-import (
- "syscall"
-)
-
-// The only signal values guaranteed to be present on all systems
-// are Interrupt (send the process an interrupt) and Kill (force
-// the process to exit).
-var (
- Interrupt Signal = syscall.SIGINT
- Kill Signal = syscall.SIGKILL
-)
-
-func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
- // If there is no SysProcAttr (ie. no Chroot or changed
- // UID/GID), double-check existence of the directory we want
- // to chdir into. We can make the error clearer this way.
- if attr != nil && attr.Sys == nil && attr.Dir != "" {
- if _, err := Stat(attr.Dir); err != nil {
- pe := err.(*PathError)
- pe.Op = "chdir"
- return nil, pe
- }
- }
-
- sysattr := &syscall.ProcAttr{
- Dir: attr.Dir,
- Env: attr.Env,
- Sys: attr.Sys,
- }
- if sysattr.Env == nil {
- sysattr.Env = Environ()
- }
- for _, f := range attr.Files {
- sysattr.Files = append(sysattr.Files, f.Fd())
- }
-
- pid, h, e := syscall.StartProcess(name, argv, sysattr)
- if e != nil {
- return nil, &PathError{"fork/exec", name, e}
- }
- return newProcess(pid, h), nil
-}
-
-func (p *Process) kill() error {
- return p.Signal(Kill)
-}
-
-// ProcessState stores information about a process, as reported by Wait.
-type ProcessState struct {
- pid int // The process's id.
- status syscall.WaitStatus // System-dependent status info.
- rusage *syscall.Rusage
-}
-
-// Pid returns the process id of the exited process.
-func (p *ProcessState) Pid() int {
- return p.pid
-}
-
-func (p *ProcessState) exited() bool {
- return p.status.Exited()
-}
-
-func (p *ProcessState) success() bool {
- return p.status.ExitStatus() == 0
-}
-
-func (p *ProcessState) sys() interface{} {
- return p.status
-}
-
-func (p *ProcessState) sysUsage() interface{} {
- return p.rusage
-}
-
-// Convert i to decimal string.
-func itod(i int) string {
- if i == 0 {
- return "0"
- }
-
- u := uint64(i)
- if i < 0 {
- u = -u
- }
-
- // Assemble decimal in reverse order.
- var b [32]byte
- bp := len(b)
- for ; u > 0; u /= 10 {
- bp--
- b[bp] = byte(u%10) + '0'
- }
-
- if i < 0 {
- bp--
- b[bp] = '-'
- }
-
- return string(b[bp:])
-}
-
-func (p *ProcessState) String() string {
- if p == nil {
- return "<nil>"
- }
- status := p.Sys().(syscall.WaitStatus)
- res := ""
- switch {
- case status.Exited():
- res = "exit status " + itod(status.ExitStatus())
- case status.Signaled():
- res = "signal: " + status.Signal().String()
- case status.Stopped():
- res = "stop signal: " + status.StopSignal().String()
- if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
- res += " (trap " + itod(status.TrapCause()) + ")"
- }
- case status.Continued():
- res = "continued"
- }
- if status.CoreDump() {
- res += " (core dumped)"
- }
- return res
-}
diff --git a/src/pkg/os/exec_unix.go b/src/pkg/os/exec_unix.go
deleted file mode 100644
index 1b1e3350b..000000000
--- a/src/pkg/os/exec_unix.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package os
-
-import (
- "errors"
- "runtime"
- "syscall"
- "time"
-)
-
-func (p *Process) wait() (ps *ProcessState, err error) {
- if p.Pid == -1 {
- return nil, syscall.EINVAL
- }
- var status syscall.WaitStatus
- var rusage syscall.Rusage
- pid1, e := syscall.Wait4(p.Pid, &status, 0, &rusage)
- if e != nil {
- return nil, NewSyscallError("wait", e)
- }
- if pid1 != 0 {
- p.setDone()
- }
- ps = &ProcessState{
- pid: pid1,
- status: status,
- rusage: &rusage,
- }
- return ps, nil
-}
-
-func (p *Process) signal(sig Signal) error {
- if p.done() {
- return errors.New("os: process already finished")
- }
- if p.Pid == -1 {
- return errors.New("os: process already released")
- }
- s, ok := sig.(syscall.Signal)
- if !ok {
- return errors.New("os: unsupported signal type")
- }
- if e := syscall.Kill(p.Pid, s); e != nil {
- return e
- }
- return nil
-}
-
-func (p *Process) release() error {
- // NOOP for unix.
- p.Pid = -1
- // no need for a finalizer anymore
- runtime.SetFinalizer(p, nil)
- return nil
-}
-
-func findProcess(pid int) (p *Process, err error) {
- // NOOP for unix.
- return newProcess(pid, 0), nil
-}
-
-func (p *ProcessState) userTime() time.Duration {
- return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond
-}
-
-func (p *ProcessState) systemTime() time.Duration {
- return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond
-}
diff --git a/src/pkg/os/exec_windows.go b/src/pkg/os/exec_windows.go
deleted file mode 100644
index c4f3d4f85..000000000
--- a/src/pkg/os/exec_windows.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// 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.
-
-package os
-
-import (
- "errors"
- "runtime"
- "syscall"
- "time"
- "unsafe"
-)
-
-func (p *Process) wait() (ps *ProcessState, err error) {
- s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE)
- switch s {
- case syscall.WAIT_OBJECT_0:
- break
- case syscall.WAIT_FAILED:
- return nil, NewSyscallError("WaitForSingleObject", e)
- default:
- return nil, errors.New("os: unexpected result from WaitForSingleObject")
- }
- var ec uint32
- e = syscall.GetExitCodeProcess(syscall.Handle(p.handle), &ec)
- if e != nil {
- return nil, NewSyscallError("GetExitCodeProcess", e)
- }
- var u syscall.Rusage
- e = syscall.GetProcessTimes(syscall.Handle(p.handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime)
- if e != nil {
- return nil, NewSyscallError("GetProcessTimes", e)
- }
- p.setDone()
- // NOTE(brainman): It seems that sometimes process is not dead
- // when WaitForSingleObject returns. But we do not know any
- // other way to wait for it. Sleeping for a while seems to do
- // the trick sometimes. So we will sleep and smell the roses.
- defer time.Sleep(5 * time.Millisecond)
- defer p.Release()
- return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
-}
-
-func terminateProcess(pid, exitcode int) error {
- h, e := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false, uint32(pid))
- if e != nil {
- return NewSyscallError("OpenProcess", e)
- }
- defer syscall.CloseHandle(h)
- e = syscall.TerminateProcess(h, uint32(exitcode))
- return NewSyscallError("TerminateProcess", e)
-}
-
-func (p *Process) signal(sig Signal) error {
- if p.done() {
- return errors.New("os: process already finished")
- }
- if sig == Kill {
- return terminateProcess(p.Pid, 1)
- }
- // TODO(rsc): Handle Interrupt too?
- return syscall.Errno(syscall.EWINDOWS)
-}
-
-func (p *Process) release() error {
- if p.handle == uintptr(syscall.InvalidHandle) {
- return syscall.EINVAL
- }
- e := syscall.CloseHandle(syscall.Handle(p.handle))
- if e != nil {
- return NewSyscallError("CloseHandle", e)
- }
- p.handle = uintptr(syscall.InvalidHandle)
- // no need for a finalizer anymore
- runtime.SetFinalizer(p, nil)
- return nil
-}
-
-func findProcess(pid int) (p *Process, err error) {
- const da = syscall.STANDARD_RIGHTS_READ |
- syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE
- h, e := syscall.OpenProcess(da, false, uint32(pid))
- if e != nil {
- return nil, NewSyscallError("OpenProcess", e)
- }
- return newProcess(pid, uintptr(h)), nil
-}
-
-func init() {
- var argc int32
- cmd := syscall.GetCommandLine()
- argv, e := syscall.CommandLineToArgv(cmd, &argc)
- if e != nil {
- return
- }
- defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
- Args = make([]string, argc)
- for i, v := range (*argv)[:argc] {
- Args[i] = string(syscall.UTF16ToString((*v)[:]))
- }
-}
-
-func ftToDuration(ft *syscall.Filetime) time.Duration {
- n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals
- return time.Duration(n*100) * time.Nanosecond
-}
-
-func (p *ProcessState) userTime() time.Duration {
- return ftToDuration(&p.rusage.UserTime)
-}
-
-func (p *ProcessState) systemTime() time.Duration {
- return ftToDuration(&p.rusage.KernelTime)
-}
diff --git a/src/pkg/os/export_test.go b/src/pkg/os/export_test.go
deleted file mode 100644
index 9fa7936ae..000000000
--- a/src/pkg/os/export_test.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2011 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.
-
-package os
-
-// Export for testing.
-
-var Atime = atime
-var LstatP = &lstat
diff --git a/src/pkg/os/file.go b/src/pkg/os/file.go
deleted file mode 100644
index b4a745801..000000000
--- a/src/pkg/os/file.go
+++ /dev/null
@@ -1,257 +0,0 @@
-// 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.
-
-// Package os provides a platform-independent interface to operating system
-// 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
-// will include the failing file name when printed and will be of type
-// *PathError, which may be unpacked for more information.
-//
-// The os interface is intended to be uniform across all operating systems.
-// Features not generally available appear in the system-specific package syscall.
-//
-// 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
-// Write take their byte counts from the length of the argument slice.
-//
-// 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])
-//
-package os
-
-import (
- "io"
- "syscall"
-)
-
-// Name returns the name of the file as presented to Open.
-func (f *File) Name() string { return f.name }
-
-// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
-// standard output, and standard error file descriptors.
-var (
- Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
- Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
- Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
-)
-
-// Flags to Open wrapping those of the underlying system. Not all flags
-// may be implemented on a given system.
-const (
- 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.
- 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.
- O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
- O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
- O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.
-)
-
-// Seek whence values.
-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
-)
-
-// 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()
-}
-
-// Read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-// EOF is signaled by a zero count with err set to io.EOF.
-func (f *File) Read(b []byte) (n int, err error) {
- if f == nil {
- return 0, ErrInvalid
- }
- n, e := f.read(b)
- if n < 0 {
- n = 0
- }
- if n == 0 && len(b) > 0 && e == nil {
- return 0, io.EOF
- }
- if e != nil {
- err = &PathError{"read", f.name, e}
- }
- return n, err
-}
-
-// ReadAt reads len(b) bytes from the File starting at byte offset off.
-// It returns the number of bytes read and the error, if any.
-// ReadAt always returns a non-nil error when n < len(b).
-// At end of file, that error is io.EOF.
-func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
- if f == nil {
- return 0, ErrInvalid
- }
- for len(b) > 0 {
- m, e := f.pread(b, off)
- if m == 0 && e == nil {
- return n, io.EOF
- }
- if e != nil {
- err = &PathError{"read", f.name, e}
- break
- }
- n += m
- b = b[m:]
- off += int64(m)
- }
- return
-}
-
-// Write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-// Write returns a non-nil error when n != len(b).
-func (f *File) Write(b []byte) (n int, err error) {
- if f == nil {
- return 0, ErrInvalid
- }
- n, e := f.write(b)
- if n < 0 {
- n = 0
- }
- if n != len(b) {
- err = io.ErrShortWrite
- }
-
- epipecheck(f, e)
-
- if e != nil {
- err = &PathError{"write", f.name, e}
- }
- return n, err
-}
-
-// WriteAt writes len(b) bytes to the File starting at byte offset off.
-// It returns the number of bytes written and an error, if any.
-// WriteAt returns a non-nil error when n != len(b).
-func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
- if f == nil {
- return 0, ErrInvalid
- }
- for len(b) > 0 {
- m, e := f.pwrite(b, off)
- if e != nil {
- err = &PathError{"write", f.name, e}
- break
- }
- n += m
- b = b[m:]
- off += int64(m)
- }
- return
-}
-
-// 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.
-func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
- if f == nil {
- return 0, ErrInvalid
- }
- r, e := f.seek(offset, whence)
- if e == nil && f.dirinfo != nil && r != 0 {
- e = syscall.EISDIR
- }
- if e != nil {
- return 0, &PathError{"seek", f.name, e}
- }
- return r, nil
-}
-
-// WriteString is like Write, but writes the contents of string s rather than
-// a slice of bytes.
-func (f *File) WriteString(s string) (ret int, err error) {
- if f == nil {
- return 0, ErrInvalid
- }
- return f.Write([]byte(s))
-}
-
-// Mkdir creates a new directory with the specified name and permission bits.
-// If there is an error, it will be of type *PathError.
-func Mkdir(name string, perm FileMode) error {
- e := syscall.Mkdir(name, syscallMode(perm))
- if e != nil {
- return &PathError{"mkdir", name, e}
- }
- return nil
-}
-
-// Chdir changes the current working directory to the named directory.
-// If there is an error, it will be of type *PathError.
-func Chdir(dir string) error {
- if e := syscall.Chdir(dir); e != nil {
- return &PathError{"chdir", dir, e}
- }
- return nil
-}
-
-// Chdir changes the current working directory to the file,
-// which must be a directory.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chdir() error {
- if f == nil {
- return ErrInvalid
- }
- if e := syscall.Fchdir(f.fd); e != nil {
- return &PathError{"chdir", f.name, e}
- }
- return nil
-}
-
-// Open opens the named file for reading. If successful, methods on
-// the returned file can be used for reading; the associated file
-// descriptor has mode O_RDONLY.
-// If there is an error, it will be of type *PathError.
-func Open(name string) (file *File, err error) {
- return OpenFile(name, O_RDONLY, 0)
-}
-
-// Create creates the named file mode 0666 (before umask), truncating
-// it if it already exists. If successful, methods on the returned
-// File can be used for I/O; the associated file descriptor has mode
-// O_RDWR.
-// If there is an error, it will be of type *PathError.
-func Create(name string) (file *File, err error) {
- return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
-}
-
-// lstat is overridden in tests.
-var lstat = Lstat
-
-// Rename renames (moves) a file. OS-specific restrictions might apply.
-func Rename(oldpath, newpath string) error {
- return rename(oldpath, newpath)
-}
diff --git a/src/pkg/os/file_plan9.go b/src/pkg/os/file_plan9.go
deleted file mode 100644
index a804b8197..000000000
--- a/src/pkg/os/file_plan9.go
+++ /dev/null
@@ -1,468 +0,0 @@
-// Copyright 2011 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.
-
-package os
-
-import (
- "runtime"
- "syscall"
- "time"
-)
-
-// File represents an open file descriptor.
-type File struct {
- *file
-}
-
-// 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 {
- fd int
- name string
- dirinfo *dirInfo // nil unless directory being read
-}
-
-// Fd returns the integer Unix file descriptor referencing the open file.
-func (f *File) Fd() uintptr {
- if f == nil {
- return ^(uintptr(0))
- }
- return uintptr(f.fd)
-}
-
-// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd uintptr, name string) *File {
- fdi := int(fd)
- if fdi < 0 {
- return nil
- }
- f := &File{&file{fd: fdi, name: name}}
- runtime.SetFinalizer(f.file, (*file).close)
- return f
-}
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
- buf [syscall.STATMAX]byte // buffer for directory I/O
- nbuf int // length of buf; return value from Read
- bufp int // location of next record in buf.
-}
-
-func epipecheck(file *File, e error) {
-}
-
-// 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"
-
-// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
-func syscallMode(i FileMode) (o uint32) {
- o |= uint32(i.Perm())
- if i&ModeAppend != 0 {
- o |= syscall.DMAPPEND
- }
- if i&ModeExclusive != 0 {
- o |= syscall.DMEXCL
- }
- if i&ModeTemporary != 0 {
- o |= syscall.DMTMP
- }
- return
-}
-
-// OpenFile is the generalized open call; most users will use Open
-// or Create instead. It opens the named file with specified flag
-// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,
-// 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 *File, err error) {
- var (
- fd int
- e error
- create bool
- excl bool
- trunc bool
- append bool
- )
-
- if flag&O_CREATE == O_CREATE {
- flag = flag & ^O_CREATE
- create = true
- }
- if flag&O_EXCL == O_EXCL {
- excl = true
- }
- if flag&O_TRUNC == O_TRUNC {
- trunc = true
- }
- // O_APPEND is emulated on Plan 9
- if flag&O_APPEND == O_APPEND {
- flag = flag &^ O_APPEND
- append = true
- }
-
- if (create && trunc) || excl {
- fd, e = syscall.Create(name, flag, syscallMode(perm))
- } else {
- fd, e = syscall.Open(name, flag)
- if e != nil && create {
- var e1 error
- fd, e1 = syscall.Create(name, flag, syscallMode(perm))
- if e1 == nil {
- e = nil
- }
- }
- }
-
- if e != nil {
- return nil, &PathError{"open", name, e}
- }
-
- if append {
- if _, e = syscall.Seek(fd, 0, SEEK_END); e != nil {
- return nil, &PathError{"seek", name, e}
- }
- }
-
- return NewFile(uintptr(fd), name), nil
-}
-
-// Close closes the File, rendering it unusable for I/O.
-// It returns an error, if any.
-func (f *File) Close() error {
- if f == nil {
- return ErrInvalid
- }
- return f.file.close()
-}
-
-func (file *file) close() error {
- if file == nil || file.fd < 0 {
- return ErrInvalid
- }
- var err error
- syscall.ForkLock.RLock()
- if e := syscall.Close(file.fd); e != nil {
- err = &PathError{"close", file.name, e}
- }
- syscall.ForkLock.RUnlock()
- file.fd = -1 // so it can't be closed again
-
- // no need for a finalizer anymore
- runtime.SetFinalizer(file, nil)
- return err
-}
-
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Stat() (fi FileInfo, err error) {
- if f == nil {
- return nil, ErrInvalid
- }
- d, err := dirstat(f)
- if err != nil {
- return nil, err
- }
- return fileInfoFromStat(d), nil
-}
-
-// Truncate changes the size of the file.
-// It does not change the I/O offset.
-// If there is an error, it will be of type *PathError.
-func (f *File) Truncate(size int64) error {
- if f == nil {
- return ErrInvalid
- }
-
- var d syscall.Dir
- d.Null()
- d.Length = size
-
- var buf [syscall.STATFIXLEN]byte
- n, err := d.Marshal(buf[:])
- if err != nil {
- return &PathError{"truncate", f.name, err}
- }
- if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
- return &PathError{"truncate", f.name, err}
- }
- return nil
-}
-
-const chmodMask = uint32(syscall.DMAPPEND | syscall.DMEXCL | syscall.DMTMP | ModePerm)
-
-// 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 {
- if f == nil {
- return ErrInvalid
- }
- var d syscall.Dir
-
- odir, e := dirstat(f)
- if e != nil {
- return &PathError{"chmod", f.name, e}
- }
- d.Null()
- d.Mode = odir.Mode&^chmodMask | syscallMode(mode)&chmodMask
-
- var buf [syscall.STATFIXLEN]byte
- n, err := d.Marshal(buf[:])
- if err != nil {
- return &PathError{"chmod", f.name, err}
- }
- if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
- return &PathError{"chmod", f.name, err}
- }
- return nil
-}
-
-// Sync commits the current contents of the file to stable storage.
-// Typically, this means flushing the file system's in-memory copy
-// of recently written data to disk.
-func (f *File) Sync() (err error) {
- if f == nil {
- return ErrInvalid
- }
- var d syscall.Dir
- d.Null()
-
- var buf [syscall.STATFIXLEN]byte
- n, err := d.Marshal(buf[:])
- if err != nil {
- return NewSyscallError("fsync", err)
- }
- if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
- return NewSyscallError("fsync", err)
- }
- return nil
-}
-
-// read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-func (f *File) read(b []byte) (n int, err error) {
- return syscall.Read(f.fd, b)
-}
-
-// 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.
-// EOF is signaled by a zero count with err set to nil.
-func (f *File) pread(b []byte, off int64) (n int, err error) {
- return syscall.Pread(f.fd, b, off)
-}
-
-// write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-// Since Plan 9 preserves message boundaries, never allow
-// a zero-byte write.
-func (f *File) write(b []byte) (n int, err error) {
- if len(b) == 0 {
- return 0, nil
- }
- return syscall.Write(f.fd, b)
-}
-
-// 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.
-// Since Plan 9 preserves message boundaries, never allow
-// a zero-byte write.
-func (f *File) pwrite(b []byte, off int64) (n int, err error) {
- if len(b) == 0 {
- return 0, nil
- }
- return syscall.Pwrite(f.fd, b, off)
-}
-
-// 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.
-func (f *File) seek(offset int64, whence int) (ret int64, err error) {
- return syscall.Seek(f.fd, offset, whence)
-}
-
-// Truncate changes the size of the named file.
-// If the file is a symbolic link, it changes the size of the link's target.
-// If there is an error, it will be of type *PathError.
-func Truncate(name string, size int64) error {
- var d syscall.Dir
-
- d.Null()
- d.Length = size
-
- var buf [syscall.STATFIXLEN]byte
- n, err := d.Marshal(buf[:])
- if err != nil {
- return &PathError{"truncate", name, err}
- }
- if err = syscall.Wstat(name, buf[:n]); err != nil {
- return &PathError{"truncate", name, err}
- }
- return nil
-}
-
-// Remove removes the named file or directory.
-// If there is an error, it will be of type *PathError.
-func Remove(name string) error {
- if e := syscall.Remove(name); e != nil {
- return &PathError{"remove", name, e}
- }
- return nil
-}
-
-// HasPrefix from the strings package.
-func hasPrefix(s, prefix string) bool {
- return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
-}
-
-// Variant of LastIndex from the strings package.
-func lastIndex(s string, sep byte) int {
- for i := len(s) - 1; i >= 0; i-- {
- if s[i] == sep {
- return i
- }
- }
- return -1
-}
-
-func rename(oldname, newname string) error {
- dirname := oldname[:lastIndex(oldname, '/')+1]
- if hasPrefix(newname, dirname) {
- newname = newname[len(dirname):]
- } else {
- return &LinkError{"rename", oldname, newname, ErrInvalid}
- }
-
- // If newname still contains slashes after removing the oldname
- // prefix, the rename is cross-directory and must be rejected.
- // This case is caught by d.Marshal below.
-
- var d syscall.Dir
-
- d.Null()
- d.Name = newname
-
- buf := make([]byte, syscall.STATFIXLEN+len(d.Name))
- n, err := d.Marshal(buf[:])
- if err != nil {
- return &LinkError{"rename", oldname, newname, err}
- }
- if err = syscall.Wstat(oldname, buf[:n]); err != nil {
- return &LinkError{"rename", oldname, newname, err}
- }
- return nil
-}
-
-// 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.
-func Chmod(name string, mode FileMode) error {
- var d syscall.Dir
-
- odir, e := dirstat(name)
- if e != nil {
- return &PathError{"chmod", name, e}
- }
- d.Null()
- d.Mode = odir.Mode&^chmodMask | syscallMode(mode)&chmodMask
-
- var buf [syscall.STATFIXLEN]byte
- n, err := d.Marshal(buf[:])
- if err != nil {
- return &PathError{"chmod", name, err}
- }
- if err = syscall.Wstat(name, buf[:n]); err != nil {
- return &PathError{"chmod", name, err}
- }
- return nil
-}
-
-// Chtimes changes the access and modification times of the named
-// file, similar to the Unix utime() or utimes() functions.
-//
-// The underlying filesystem may truncate or round the values to a
-// less precise time unit.
-// If there is an error, it will be of type *PathError.
-func Chtimes(name string, atime time.Time, mtime time.Time) error {
- var d syscall.Dir
-
- d.Null()
- d.Atime = uint32(atime.Unix())
- d.Mtime = uint32(mtime.Unix())
-
- var buf [syscall.STATFIXLEN]byte
- n, err := d.Marshal(buf[:])
- if err != nil {
- return &PathError{"chtimes", name, err}
- }
- if err = syscall.Wstat(name, buf[:n]); err != nil {
- return &PathError{"chtimes", name, err}
- }
- return nil
-}
-
-// Pipe returns a connected pair of Files; reads from r return bytes
-// written to w. It returns the files and an error, if any.
-func Pipe() (r *File, w *File, err error) {
- var p [2]int
-
- syscall.ForkLock.RLock()
- if e := syscall.Pipe(p[0:]); e != nil {
- syscall.ForkLock.RUnlock()
- return nil, nil, NewSyscallError("pipe", e)
- }
- syscall.ForkLock.RUnlock()
-
- return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
-}
-
-// not supported on Plan 9
-
-// 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 {
- return &LinkError{"link", oldname, newname, syscall.EPLAN9}
-}
-
-// 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 {
- return &LinkError{"symlink", oldname, newname, syscall.EPLAN9}
-}
-
-// Readlink returns the destination of the named symbolic link.
-// If there is an error, it will be of type *PathError.
-func Readlink(name string) (string, error) {
- return "", &PathError{"readlink", name, syscall.EPLAN9}
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link's target.
-// If there is an error, it will be of type *PathError.
-func Chown(name string, uid, gid int) error {
- return &PathError{"chown", name, syscall.EPLAN9}
-}
-
-// Lchown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link itself.
-// If there is an error, it will be of type *PathError.
-func Lchown(name string, uid, gid int) error {
- return &PathError{"lchown", name, syscall.EPLAN9}
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chown(uid, gid int) error {
- if f == nil {
- return ErrInvalid
- }
- return &PathError{"chown", f.name, syscall.EPLAN9}
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
- return "/tmp"
-}
diff --git a/src/pkg/os/file_posix.go b/src/pkg/os/file_posix.go
deleted file mode 100644
index b3466b15c..000000000
--- a/src/pkg/os/file_posix.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sigpipe() // implemented in package runtime
-
-// 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
-}
-
-// Readlink returns the destination of the named symbolic link.
-// If there is an error, it will be of type *PathError.
-func Readlink(name string) (string, error) {
- for len := 128; ; len *= 2 {
- b := make([]byte, len)
- n, e := syscall.Readlink(name, b)
- if e != nil {
- return "", &PathError{"readlink", name, e}
- }
- if n < len {
- return string(b[0:n]), nil
- }
- }
-}
-
-func rename(oldname, newname string) error {
- e := syscall.Rename(oldname, newname)
- if e != nil {
- return &LinkError{"rename", oldname, newname, e}
- }
- return nil
-}
-
-// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
-func syscallMode(i FileMode) (o uint32) {
- o |= uint32(i.Perm())
- if i&ModeSetuid != 0 {
- o |= syscall.S_ISUID
- }
- if i&ModeSetgid != 0 {
- o |= syscall.S_ISGID
- }
- if i&ModeSticky != 0 {
- o |= syscall.S_ISVTX
- }
- // No mapping for Go's ModeTemporary (plan9 only).
- return
-}
-
-// 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.
-func Chmod(name string, mode FileMode) error {
- if e := syscall.Chmod(name, syscallMode(mode)); e != nil {
- return &PathError{"chmod", name, e}
- }
- return nil
-}
-
-// 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 {
- if f == nil {
- return ErrInvalid
- }
- if e := syscall.Fchmod(f.fd, syscallMode(mode)); e != nil {
- return &PathError{"chmod", f.name, e}
- }
- return nil
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link's target.
-// If there is an error, it will be of type *PathError.
-func Chown(name string, uid, gid int) error {
- if e := syscall.Chown(name, uid, gid); e != nil {
- return &PathError{"chown", name, e}
- }
- return nil
-}
-
-// Lchown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link itself.
-// If there is an error, it will be of type *PathError.
-func Lchown(name string, uid, gid int) error {
- if e := syscall.Lchown(name, uid, gid); e != nil {
- return &PathError{"lchown", name, e}
- }
- return nil
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chown(uid, gid int) error {
- if f == nil {
- return ErrInvalid
- }
- if e := syscall.Fchown(f.fd, uid, gid); e != nil {
- return &PathError{"chown", f.name, e}
- }
- return nil
-}
-
-// Truncate changes the size of the file.
-// It does not change the I/O offset.
-// If there is an error, it will be of type *PathError.
-func (f *File) Truncate(size int64) error {
- if f == nil {
- return ErrInvalid
- }
- if e := syscall.Ftruncate(f.fd, size); e != nil {
- return &PathError{"truncate", f.name, e}
- }
- return nil
-}
-
-// Sync commits the current contents of the file to stable storage.
-// Typically, this means flushing the file system's in-memory copy
-// of recently written data to disk.
-func (f *File) Sync() (err error) {
- if f == nil {
- return ErrInvalid
- }
- if e := syscall.Fsync(f.fd); e != nil {
- return NewSyscallError("fsync", e)
- }
- return nil
-}
-
-// Chtimes changes the access and modification times of the named
-// file, similar to the Unix utime() or utimes() functions.
-//
-// The underlying filesystem may truncate or round the values to a
-// less precise time unit.
-// If there is an error, it will be of type *PathError.
-func Chtimes(name string, atime time.Time, mtime time.Time) error {
- var utimes [2]syscall.Timespec
- utimes[0] = syscall.NsecToTimespec(atime.UnixNano())
- utimes[1] = syscall.NsecToTimespec(mtime.UnixNano())
- if e := syscall.UtimesNano(name, utimes[0:]); e != nil {
- return &PathError{"chtimes", name, e}
- }
- return nil
-}
diff --git a/src/pkg/os/file_unix.go b/src/pkg/os/file_unix.go
deleted file mode 100644
index 76168339d..000000000
--- a/src/pkg/os/file_unix.go
+++ /dev/null
@@ -1,314 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package os
-
-import (
- "runtime"
- "sync/atomic"
- "syscall"
-)
-
-// File represents an open file descriptor.
-type File struct {
- *file
-}
-
-// 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 {
- fd int
- name string
- dirinfo *dirInfo // nil unless directory being read
- nepipe int32 // number of consecutive EPIPE in Write
-}
-
-// Fd returns the integer Unix file descriptor referencing the open file.
-func (f *File) Fd() uintptr {
- if f == nil {
- return ^(uintptr(0))
- }
- return uintptr(f.fd)
-}
-
-// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd uintptr, name string) *File {
- fdi := int(fd)
- if fdi < 0 {
- return nil
- }
- f := &File{&file{fd: fdi, name: name}}
- runtime.SetFinalizer(f.file, (*file).close)
- return f
-}
-
-// 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.
-}
-
-func epipecheck(file *File, e error) {
- if e == syscall.EPIPE {
- if atomic.AddInt32(&file.nepipe, 1) >= 10 {
- sigpipe()
- }
- } else {
- atomic.StoreInt32(&file.nepipe, 0)
- }
-}
-
-// 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"
-
-// OpenFile is the generalized open call; most users will use Open
-// or Create instead. It opens the named file with specified flag
-// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,
-// 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 *File, err error) {
- r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
- if e != nil {
- return nil, &PathError{"open", name, e}
- }
-
- // There's a race here with fork/exec, which we are
- // content to live with. See ../syscall/exec_unix.go.
- if !supportsCloseOnExec {
- syscall.CloseOnExec(r)
- }
-
- return NewFile(uintptr(r), name), nil
-}
-
-// Close closes the File, rendering it unusable for I/O.
-// It returns an error, if any.
-func (f *File) Close() error {
- if f == nil {
- return ErrInvalid
- }
- return f.file.close()
-}
-
-func (file *file) close() error {
- if file == nil || file.fd < 0 {
- return syscall.EINVAL
- }
- var err error
- if e := syscall.Close(file.fd); e != nil {
- err = &PathError{"close", file.name, e}
- }
- file.fd = -1 // so it can't be closed again
-
- // no need for a finalizer anymore
- runtime.SetFinalizer(file, nil)
- return err
-}
-
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Stat() (fi FileInfo, err error) {
- if f == nil {
- return nil, ErrInvalid
- }
- var stat syscall.Stat_t
- err = syscall.Fstat(f.fd, &stat)
- if err != nil {
- return nil, &PathError{"stat", f.name, err}
- }
- return fileInfoFromStat(&stat, f.name), nil
-}
-
-// Stat returns a FileInfo describing the named file.
-// If there is an error, it will be of type *PathError.
-func Stat(name string) (fi FileInfo, err error) {
- var stat syscall.Stat_t
- err = syscall.Stat(name, &stat)
- if err != nil {
- return nil, &PathError{"stat", name, err}
- }
- return fileInfoFromStat(&stat, name), nil
-}
-
-// Lstat returns a FileInfo describing the named file.
-// If the file is a symbolic link, the returned FileInfo
-// describes the symbolic link. Lstat makes no attempt to follow the link.
-// If there is an error, it will be of type *PathError.
-func Lstat(name string) (fi FileInfo, err error) {
- var stat syscall.Stat_t
- err = syscall.Lstat(name, &stat)
- if err != nil {
- return nil, &PathError{"lstat", name, err}
- }
- return fileInfoFromStat(&stat, name), nil
-}
-
-func (f *File) readdir(n int) (fi []FileInfo, err error) {
- dirname := f.name
- if dirname == "" {
- dirname = "."
- }
- names, err := f.Readdirnames(n)
- fi = make([]FileInfo, 0, len(names))
- for _, filename := range names {
- fip, lerr := lstat(dirname + "/" + filename)
- if IsNotExist(lerr) {
- // File disappeared between readdir + stat.
- // Just treat it as if it didn't exist.
- continue
- }
- if lerr != nil {
- return fi, lerr
- }
- fi = append(fi, fip)
- }
- return fi, err
-}
-
-// Darwin and FreeBSD can't read or write 2GB+ at a time,
-// even on 64-bit systems. See golang.org/issue/7812.
-// Use 1GB instead of, say, 2GB-1, to keep subsequent
-// reads aligned.
-const (
- needsMaxRW = runtime.GOOS == "darwin" || runtime.GOOS == "freebsd"
- maxRW = 1 << 30
-)
-
-// read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-func (f *File) read(b []byte) (n int, err error) {
- if needsMaxRW && len(b) > maxRW {
- b = b[:maxRW]
- }
- return syscall.Read(f.fd, b)
-}
-
-// 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.
-// EOF is signaled by a zero count with err set to nil.
-func (f *File) pread(b []byte, off int64) (n int, err error) {
- if needsMaxRW && len(b) > maxRW {
- b = b[:maxRW]
- }
- return syscall.Pread(f.fd, b, off)
-}
-
-// write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-func (f *File) write(b []byte) (n int, err error) {
- for {
- bcap := b
- if needsMaxRW && len(bcap) > maxRW {
- bcap = bcap[:maxRW]
- }
- m, err := syscall.Write(f.fd, bcap)
- 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.
- if 0 < m && m < len(bcap) || err == syscall.EINTR {
- b = b[m:]
- continue
- }
-
- if needsMaxRW && len(bcap) != len(b) && err == nil {
- b = b[m:]
- continue
- }
-
- return n, err
- }
-}
-
-// 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.
-func (f *File) pwrite(b []byte, off int64) (n int, err error) {
- if needsMaxRW && len(b) > maxRW {
- b = b[:maxRW]
- }
- return syscall.Pwrite(f.fd, b, off)
-}
-
-// 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.
-func (f *File) seek(offset int64, whence int) (ret int64, err error) {
- return syscall.Seek(f.fd, offset, whence)
-}
-
-// Truncate changes the size of the named file.
-// If the file is a symbolic link, it changes the size of the link's target.
-// If there is an error, it will be of type *PathError.
-func Truncate(name string, size int64) error {
- if e := syscall.Truncate(name, size); e != nil {
- return &PathError{"truncate", name, e}
- }
- return nil
-}
-
-// Remove removes the named file or directory.
-// If there is an error, it will be of type *PathError.
-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)
- // returns EISDIR, so can't use that. However,
- // 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}
-}
-
-// basename removes trailing slashes and the leading directory name from path name
-func basename(name string) string {
- i := len(name) - 1
- // Remove trailing slashes
- for ; i > 0 && name[i] == '/'; i-- {
- name = name[:i]
- }
- // Remove leading directory name
- for i--; i >= 0; i-- {
- if name[i] == '/' {
- name = name[i+1:]
- break
- }
- }
-
- return name
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
- dir := Getenv("TMPDIR")
- if dir == "" {
- dir = "/tmp"
- }
- return dir
-}
diff --git a/src/pkg/os/file_windows.go b/src/pkg/os/file_windows.go
deleted file mode 100644
index efe8bc03f..000000000
--- a/src/pkg/os/file_windows.go
+++ /dev/null
@@ -1,495 +0,0 @@
-// 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.
-
-package os
-
-import (
- "io"
- "runtime"
- "sync"
- "syscall"
- "unicode/utf16"
- "unicode/utf8"
- "unsafe"
-)
-
-// File represents an open file descriptor.
-type File struct {
- *file
-}
-
-// 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 {
- fd syscall.Handle
- name string
- dirinfo *dirInfo // nil unless directory being read
- l sync.Mutex // used to implement windows pread/pwrite
-
- // only for console io
- isConsole bool
- lastbits []byte // first few bytes of the last incomplete rune in last write
- readbuf []rune // input console buffer
-}
-
-// Fd returns the Windows handle referencing the open file.
-func (file *File) Fd() uintptr {
- if file == nil {
- return uintptr(syscall.InvalidHandle)
- }
- return uintptr(file.fd)
-}
-
-// newFile returns a new File with the given file handle and name.
-// Unlike NewFile, it does not check that h is syscall.InvalidHandle.
-func newFile(h syscall.Handle, name string) *File {
- f := &File{&file{fd: h, name: name}}
- var m uint32
- if syscall.GetConsoleMode(f.fd, &m) == nil {
- f.isConsole = true
- }
- runtime.SetFinalizer(f.file, (*file).close)
- return f
-}
-
-// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd uintptr, name string) *File {
- h := syscall.Handle(fd)
- if h == syscall.InvalidHandle {
- return nil
- }
- return newFile(h, name)
-}
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
- data syscall.Win32finddata
- needdata bool
- path string
- isempty bool // set if FindFirstFile returns ERROR_FILE_NOT_FOUND
-}
-
-func epipecheck(file *File, e error) {
-}
-
-const DevNull = "NUL"
-
-func (f *file) isdir() bool { return f != nil && f.dirinfo != nil }
-
-func openFile(name string, flag int, perm FileMode) (file *File, err error) {
- r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
- if e != nil {
- return nil, e
- }
- return NewFile(uintptr(r), name), nil
-}
-
-func openDir(name string) (file *File, err error) {
- maskp, e := syscall.UTF16PtrFromString(name + `\*`)
- if e != nil {
- return nil, e
- }
- d := new(dirInfo)
- r, e := syscall.FindFirstFile(maskp, &d.data)
- if e != nil {
- // FindFirstFile returns ERROR_FILE_NOT_FOUND when
- // no matching files can be found. Then, if directory
- // exists, we should proceed.
- if e != syscall.ERROR_FILE_NOT_FOUND {
- return nil, e
- }
- var fa syscall.Win32FileAttributeData
- namep, e := syscall.UTF16PtrFromString(name)
- if e != nil {
- return nil, e
- }
- e = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
- if e != nil {
- return nil, e
- }
- if fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 {
- return nil, e
- }
- d.isempty = true
- }
- d.path = name
- if !isAbs(d.path) {
- cwd, _ := Getwd()
- d.path = cwd + `\` + d.path
- }
- f := newFile(r, name)
- f.dirinfo = d
- return f, nil
-}
-
-// OpenFile is the generalized open call; most users will use Open
-// or Create instead. It opens the named file with specified flag
-// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,
-// 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 *File, err error) {
- if name == "" {
- return nil, &PathError{"open", name, syscall.ENOENT}
- }
- r, errf := openFile(name, flag, perm)
- if errf == nil {
- return r, nil
- }
- r, errd := openDir(name)
- if errd == nil {
- if flag&O_WRONLY != 0 || flag&O_RDWR != 0 {
- r.Close()
- return nil, &PathError{"open", name, syscall.EISDIR}
- }
- return r, nil
- }
- return nil, &PathError{"open", name, errf}
-}
-
-// Close closes the File, rendering it unusable for I/O.
-// It returns an error, if any.
-func (file *File) Close() error {
- if file == nil {
- return ErrInvalid
- }
- return file.file.close()
-}
-
-func (file *file) close() error {
- if file == nil {
- return syscall.EINVAL
- }
- if file.isdir() && file.dirinfo.isempty {
- // "special" empty directories
- return nil
- }
- if file.fd == syscall.InvalidHandle {
- return syscall.EINVAL
- }
- var e error
- if file.isdir() {
- e = syscall.FindClose(syscall.Handle(file.fd))
- } else {
- e = syscall.CloseHandle(syscall.Handle(file.fd))
- }
- var err error
- if e != nil {
- err = &PathError{"close", file.name, e}
- }
- file.fd = syscall.InvalidHandle // so it can't be closed again
-
- // no need for a finalizer anymore
- runtime.SetFinalizer(file, nil)
- return err
-}
-
-func (file *File) readdir(n int) (fi []FileInfo, err error) {
- if file == nil {
- return nil, syscall.EINVAL
- }
- if !file.isdir() {
- return nil, &PathError{"Readdir", file.name, syscall.ENOTDIR}
- }
- if !file.dirinfo.isempty && file.fd == syscall.InvalidHandle {
- return nil, syscall.EINVAL
- }
- wantAll := n <= 0
- size := n
- if wantAll {
- n = -1
- size = 100
- }
- fi = make([]FileInfo, 0, size) // Empty with room to grow.
- d := &file.dirinfo.data
- for n != 0 && !file.dirinfo.isempty {
- if file.dirinfo.needdata {
- e := syscall.FindNextFile(syscall.Handle(file.fd), d)
- if e != nil {
- if e == syscall.ERROR_NO_MORE_FILES {
- break
- } else {
- err = &PathError{"FindNextFile", file.name, e}
- if !wantAll {
- fi = nil
- }
- return
- }
- }
- }
- file.dirinfo.needdata = true
- name := string(syscall.UTF16ToString(d.FileName[0:]))
- if name == "." || name == ".." { // Useless names
- continue
- }
- f := &fileStat{
- name: name,
- sys: syscall.Win32FileAttributeData{
- FileAttributes: d.FileAttributes,
- CreationTime: d.CreationTime,
- LastAccessTime: d.LastAccessTime,
- LastWriteTime: d.LastWriteTime,
- FileSizeHigh: d.FileSizeHigh,
- FileSizeLow: d.FileSizeLow,
- },
- path: file.dirinfo.path + `\` + name,
- }
- n--
- fi = append(fi, f)
- }
- if !wantAll && len(fi) == 0 {
- return fi, io.EOF
- }
- return fi, nil
-}
-
-// readConsole reads utf16 characters from console File,
-// encodes them into utf8 and stores them in buffer b.
-// It returns the number of utf8 bytes read and an error, if any.
-func (f *File) readConsole(b []byte) (n int, err error) {
- if len(b) == 0 {
- return 0, nil
- }
- if len(f.readbuf) == 0 {
- // syscall.ReadConsole seems to fail, if given large buffer.
- // So limit the buffer to 16000 characters.
- numBytes := len(b)
- if numBytes > 16000 {
- numBytes = 16000
- }
- // get more input data from os
- wchars := make([]uint16, numBytes)
- var p *uint16
- if len(b) > 0 {
- p = &wchars[0]
- }
- var nw uint32
- err := syscall.ReadConsole(f.fd, p, uint32(len(wchars)), &nw, nil)
- if err != nil {
- return 0, err
- }
- f.readbuf = utf16.Decode(wchars[:nw])
- }
- for i, r := range f.readbuf {
- if utf8.RuneLen(r) > len(b) {
- f.readbuf = f.readbuf[i:]
- return n, nil
- }
- nr := utf8.EncodeRune(b, r)
- b = b[nr:]
- n += nr
- }
- f.readbuf = nil
- return n, nil
-}
-
-// read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-func (f *File) read(b []byte) (n int, err error) {
- f.l.Lock()
- defer f.l.Unlock()
- if f.isConsole {
- return f.readConsole(b)
- }
- return syscall.Read(f.fd, b)
-}
-
-// 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.
-// EOF is signaled by a zero count with err set to 0.
-func (f *File) pread(b []byte, off int64) (n int, err error) {
- f.l.Lock()
- defer f.l.Unlock()
- curoffset, e := syscall.Seek(f.fd, 0, 1)
- if e != nil {
- return 0, e
- }
- defer syscall.Seek(f.fd, curoffset, 0)
- o := syscall.Overlapped{
- OffsetHigh: uint32(off >> 32),
- Offset: uint32(off),
- }
- var done uint32
- e = syscall.ReadFile(syscall.Handle(f.fd), b, &done, &o)
- if e != nil {
- if e == syscall.ERROR_HANDLE_EOF {
- // end of file
- return 0, nil
- }
- return 0, e
- }
- return int(done), nil
-}
-
-// writeConsole writes len(b) bytes to the console File.
-// It returns the number of bytes written and an error, if any.
-func (f *File) writeConsole(b []byte) (n int, err error) {
- n = len(b)
- runes := make([]rune, 0, 256)
- if len(f.lastbits) > 0 {
- b = append(f.lastbits, b...)
- f.lastbits = nil
-
- }
- for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
- r, l := utf8.DecodeRune(b)
- runes = append(runes, r)
- b = b[l:]
- }
- if len(b) > 0 {
- f.lastbits = make([]byte, len(b))
- copy(f.lastbits, b)
- }
- // syscall.WriteConsole seems to fail, if given large buffer.
- // So limit the buffer to 16000 characters. This number was
- // discovered by experimenting with syscall.WriteConsole.
- const maxWrite = 16000
- for len(runes) > 0 {
- m := len(runes)
- if m > maxWrite {
- m = maxWrite
- }
- chunk := runes[:m]
- runes = runes[m:]
- uint16s := utf16.Encode(chunk)
- for len(uint16s) > 0 {
- var written uint32
- err = syscall.WriteConsole(f.fd, &uint16s[0], uint32(len(uint16s)), &written, nil)
- if err != nil {
- return 0, nil
- }
- uint16s = uint16s[written:]
- }
- }
- return n, nil
-}
-
-// write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-func (f *File) write(b []byte) (n int, err error) {
- f.l.Lock()
- defer f.l.Unlock()
- if f.isConsole {
- return f.writeConsole(b)
- }
- return syscall.Write(f.fd, b)
-}
-
-// 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.
-func (f *File) pwrite(b []byte, off int64) (n int, err error) {
- f.l.Lock()
- defer f.l.Unlock()
- curoffset, e := syscall.Seek(f.fd, 0, 1)
- if e != nil {
- return 0, e
- }
- defer syscall.Seek(f.fd, curoffset, 0)
- o := syscall.Overlapped{
- OffsetHigh: uint32(off >> 32),
- Offset: uint32(off),
- }
- var done uint32
- e = syscall.WriteFile(syscall.Handle(f.fd), b, &done, &o)
- if e != nil {
- return 0, e
- }
- return int(done), nil
-}
-
-// 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.
-func (f *File) seek(offset int64, whence int) (ret int64, err error) {
- f.l.Lock()
- defer f.l.Unlock()
- return syscall.Seek(f.fd, offset, whence)
-}
-
-// Truncate changes the size of the named file.
-// If the file is a symbolic link, it changes the size of the link's target.
-func Truncate(name string, size int64) error {
- f, e := OpenFile(name, O_WRONLY|O_CREATE, 0666)
- if e != nil {
- return e
- }
- defer f.Close()
- e1 := f.Truncate(size)
- if e1 != nil {
- return e1
- }
- return nil
-}
-
-// Remove removes the named file or directory.
-// If there is an error, it will be of type *PathError.
-func Remove(name string) error {
- p, e := syscall.UTF16PtrFromString(name)
- if e != nil {
- return &PathError{"remove", name, e}
- }
-
- // Go file interface forces us to know whether
- // name is a file or directory. Try both.
- e = syscall.DeleteFile(p)
- if e == nil {
- return nil
- }
- e1 := syscall.RemoveDirectory(p)
- if e1 == nil {
- return nil
- }
-
- // Both failed: figure out which error to return.
- if e1 != e {
- a, e2 := syscall.GetFileAttributes(p)
- if e2 != nil {
- e = e2
- } else {
- if a&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- e = e1
- }
- }
- }
- return &PathError{"remove", name, e}
-}
-
-// Pipe returns a connected pair of Files; reads from r return bytes written to w.
-// It returns the files and an error, if any.
-func Pipe() (r *File, w *File, err error) {
- var p [2]syscall.Handle
-
- // See ../syscall/exec.go for description of lock.
- syscall.ForkLock.RLock()
- e := syscall.Pipe(p[0:])
- if e != nil {
- syscall.ForkLock.RUnlock()
- return nil, nil, NewSyscallError("pipe", e)
- }
- syscall.CloseOnExec(p[0])
- syscall.CloseOnExec(p[1])
- syscall.ForkLock.RUnlock()
-
- return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
- const pathSep = '\\'
- dirw := make([]uint16, syscall.MAX_PATH)
- n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
- if n > uint32(len(dirw)) {
- dirw = make([]uint16, n)
- n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
- if n > uint32(len(dirw)) {
- n = 0
- }
- }
- if n > 0 && dirw[n-1] == pathSep {
- n--
- }
- return string(utf16.Decode(dirw[0:n]))
-}
diff --git a/src/pkg/os/getwd.go b/src/pkg/os/getwd.go
deleted file mode 100644
index a72edeaee..000000000
--- a/src/pkg/os/getwd.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// 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.
-
-package os
-
-import (
- "sync"
- "syscall"
-)
-
-var getwdCache struct {
- sync.Mutex
- dir string
-}
-
-// useSyscallwd determines whether to use the return value of
-// syscall.Getwd based on its error.
-var useSyscallwd = func(error) bool { return true }
-
-// Getwd returns a rooted path name corresponding to the
-// current directory. If the current directory can be
-// reached via multiple paths (due to symbolic links),
-// Getwd may return any one of them.
-func Getwd() (dir string, err error) {
- // If the operating system provides a Getwd call, use it.
- if syscall.ImplementsGetwd {
- s, e := syscall.Getwd()
- if useSyscallwd(e) {
- return s, NewSyscallError("getwd", e)
- }
- }
-
- // Otherwise, we're trying to find our way back to ".".
- dot, err := Stat(".")
- if err != nil {
- return "", err
- }
-
- // Clumsy but widespread kludge:
- // if $PWD is set and matches ".", use it.
- dir = Getenv("PWD")
- if len(dir) > 0 && dir[0] == '/' {
- d, err := Stat(dir)
- if err == nil && SameFile(dot, d) {
- return dir, nil
- }
- }
-
- // Apply same kludge but to cached dir instead of $PWD.
- getwdCache.Lock()
- dir = getwdCache.dir
- getwdCache.Unlock()
- if len(dir) > 0 {
- d, err := Stat(dir)
- if err == nil && SameFile(dot, d) {
- return dir, nil
- }
- }
-
- // Root is a special case because it has no parent
- // and ends in a slash.
- root, err := Stat("/")
- if err != nil {
- // Can't stat root - no hope.
- return "", err
- }
- if SameFile(root, dot) {
- return "/", nil
- }
-
- // General algorithm: find name in parent
- // and then find name of parent. Each iteration
- // adds /name to the beginning of dir.
- dir = ""
- for parent := ".."; ; parent = "../" + parent {
- if len(parent) >= 1024 { // Sanity check
- return "", syscall.ENAMETOOLONG
- }
- fd, err := Open(parent)
- if err != nil {
- return "", err
- }
-
- for {
- names, err := fd.Readdirnames(100)
- if err != nil {
- fd.Close()
- return "", err
- }
- for _, name := range names {
- d, _ := Lstat(parent + "/" + name)
- if SameFile(d, dot) {
- dir = "/" + name + dir
- goto Found
- }
- }
- }
-
- Found:
- pd, err := fd.Stat()
- if err != nil {
- return "", err
- }
- fd.Close()
- if SameFile(pd, root) {
- break
- }
- // Set up for next round.
- dot = pd
- }
-
- // Save answer as hint to avoid the expensive path next time.
- getwdCache.Lock()
- getwdCache.dir = dir
- getwdCache.Unlock()
-
- return dir, nil
-}
diff --git a/src/pkg/os/getwd_darwin.go b/src/pkg/os/getwd_darwin.go
deleted file mode 100644
index e51ffcd5e..000000000
--- a/src/pkg/os/getwd_darwin.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-package os
-
-import "syscall"
-
-func init() {
- useSyscallwd = useSyscallwdDarwin
-}
-
-func useSyscallwdDarwin(err error) bool {
- return err != syscall.ENOTSUP
-}
diff --git a/src/pkg/os/os_test.go b/src/pkg/os/os_test.go
deleted file mode 100644
index 16d5984e9..000000000
--- a/src/pkg/os/os_test.go
+++ /dev/null
@@ -1,1339 +0,0 @@
-// 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.
-
-package os_test
-
-import (
- "bytes"
- "errors"
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- . "os"
- osexec "os/exec"
- "path/filepath"
- "reflect"
- "runtime"
- "sort"
- "strings"
- "syscall"
- "testing"
- "text/template"
- "time"
-)
-
-var dot = []string{
- "dir_unix.go",
- "env.go",
- "error.go",
- "file.go",
- "os_test.go",
- "types.go",
- "stat_darwin.go",
- "stat_linux.go",
-}
-
-type sysDir struct {
- name string
- files []string
-}
-
-var sysdir = func() (sd *sysDir) {
- switch runtime.GOOS {
- case "windows":
- sd = &sysDir{
- Getenv("SystemRoot") + "\\system32\\drivers\\etc",
- []string{
- "networks",
- "protocol",
- "services",
- },
- }
- case "plan9":
- sd = &sysDir{
- "/lib/ndb",
- []string{
- "common",
- "local",
- },
- }
- default:
- sd = &sysDir{
- "/etc",
- []string{
- "group",
- "hosts",
- "passwd",
- },
- }
- }
- return
-}()
-
-func size(name string, t *testing.T) int64 {
- file, err := Open(name)
- if err != nil {
- t.Fatal("open failed:", err)
- }
- defer file.Close()
- var buf [100]byte
- len := 0
- for {
- n, e := file.Read(buf[0:])
- len += n
- if e == io.EOF {
- break
- }
- if e != nil {
- t.Fatal("read failed:", err)
- }
- }
- return int64(len)
-}
-
-func equal(name1, name2 string) (r bool) {
- switch runtime.GOOS {
- case "windows":
- r = strings.ToLower(name1) == strings.ToLower(name2)
- default:
- r = name1 == name2
- }
- return
-}
-
-func newFile(testName string, t *testing.T) (f *File) {
- // Use a local file system, not NFS.
- // On Unix, override $TMPDIR in case the user
- // has it set to an NFS-mounted directory.
- dir := ""
- if runtime.GOOS != "windows" {
- dir = "/tmp"
- }
- f, err := ioutil.TempFile(dir, "_Go_"+testName)
- if err != nil {
- t.Fatalf("open %s: %s", testName, err)
- }
- return
-}
-
-var sfdir = sysdir.name
-var sfname = sysdir.files[0]
-
-func TestStat(t *testing.T) {
- path := sfdir + "/" + sfname
- dir, err := Stat(path)
- if err != nil {
- t.Fatal("stat failed:", err)
- }
- if !equal(sfname, dir.Name()) {
- t.Error("name should be ", sfname, "; is", dir.Name())
- }
- filesize := size(path, t)
- if dir.Size() != filesize {
- t.Error("size should be", filesize, "; is", dir.Size())
- }
-}
-
-func TestFstat(t *testing.T) {
- path := sfdir + "/" + sfname
- file, err1 := Open(path)
- if err1 != nil {
- t.Fatal("open failed:", err1)
- }
- defer file.Close()
- dir, err2 := file.Stat()
- if err2 != nil {
- t.Fatal("fstat failed:", err2)
- }
- if !equal(sfname, dir.Name()) {
- t.Error("name should be ", sfname, "; is", dir.Name())
- }
- filesize := size(path, t)
- if dir.Size() != filesize {
- t.Error("size should be", filesize, "; is", dir.Size())
- }
-}
-
-func TestLstat(t *testing.T) {
- path := sfdir + "/" + sfname
- dir, err := Lstat(path)
- if err != nil {
- t.Fatal("lstat failed:", err)
- }
- if !equal(sfname, dir.Name()) {
- t.Error("name should be ", sfname, "; is", dir.Name())
- }
- filesize := size(path, t)
- if dir.Size() != filesize {
- t.Error("size should be", filesize, "; is", dir.Size())
- }
-}
-
-// Read with length 0 should not return EOF.
-func TestRead0(t *testing.T) {
- path := sfdir + "/" + sfname
- f, err := Open(path)
- if err != nil {
- t.Fatal("open failed:", err)
- }
- defer f.Close()
-
- b := make([]byte, 0)
- n, err := f.Read(b)
- if n != 0 || err != nil {
- t.Errorf("Read(0) = %d, %v, want 0, nil", n, err)
- }
- b = make([]byte, 100)
- n, err = f.Read(b)
- if n <= 0 || err != nil {
- t.Errorf("Read(100) = %d, %v, want >0, nil", n, err)
- }
-}
-
-func testReaddirnames(dir string, contents []string, t *testing.T) {
- file, err := Open(dir)
- if err != nil {
- t.Fatalf("open %q failed: %v", dir, err)
- }
- defer file.Close()
- s, err2 := file.Readdirnames(-1)
- if err2 != nil {
- t.Fatalf("readdirnames %q failed: %v", dir, err2)
- }
- for _, m := range contents {
- found := false
- for _, n := range s {
- if n == "." || n == ".." {
- t.Errorf("got %s in directory", n)
- }
- if equal(m, n) {
- if found {
- t.Error("present twice:", m)
- }
- found = true
- }
- }
- if !found {
- t.Error("could not find", m)
- }
- }
-}
-
-func testReaddir(dir string, contents []string, t *testing.T) {
- file, err := Open(dir)
- if err != nil {
- t.Fatalf("open %q failed: %v", dir, err)
- }
- defer file.Close()
- s, err2 := file.Readdir(-1)
- if err2 != nil {
- t.Fatalf("readdir %q failed: %v", dir, err2)
- }
- for _, m := range contents {
- found := false
- for _, n := range s {
- if equal(m, n.Name()) {
- if found {
- t.Error("present twice:", m)
- }
- found = true
- }
- }
- if !found {
- t.Error("could not find", m)
- }
- }
-}
-
-func TestReaddirnames(t *testing.T) {
- testReaddirnames(".", dot, t)
- testReaddirnames(sysdir.name, sysdir.files, t)
-}
-
-func TestReaddir(t *testing.T) {
- testReaddir(".", dot, t)
- testReaddir(sysdir.name, sysdir.files, t)
-}
-
-// Read the directory one entry at a time.
-func smallReaddirnames(file *File, length int, t *testing.T) []string {
- names := make([]string, length)
- count := 0
- for {
- d, err := file.Readdirnames(1)
- if err == io.EOF {
- break
- }
- if err != nil {
- t.Fatalf("readdirnames %q failed: %v", file.Name(), err)
- }
- if len(d) == 0 {
- t.Fatalf("readdirnames %q returned empty slice and no error", file.Name())
- }
- names[count] = d[0]
- count++
- }
- return names[0:count]
-}
-
-// Check that reading a directory one entry at a time gives the same result
-// as reading it all at once.
-func TestReaddirnamesOneAtATime(t *testing.T) {
- // big directory that doesn't change often.
- dir := "/usr/bin"
- switch runtime.GOOS {
- case "windows":
- dir = Getenv("SystemRoot") + "\\system32"
- case "plan9":
- dir = "/bin"
- }
- file, err := Open(dir)
- if err != nil {
- t.Fatalf("open %q failed: %v", dir, err)
- }
- defer file.Close()
- all, err1 := file.Readdirnames(-1)
- if err1 != nil {
- t.Fatalf("readdirnames %q failed: %v", dir, err1)
- }
- file1, err2 := Open(dir)
- if err2 != nil {
- t.Fatalf("open %q failed: %v", dir, err2)
- }
- defer file1.Close()
- small := smallReaddirnames(file1, len(all)+100, t) // +100 in case we screw up
- if len(small) < len(all) {
- t.Fatalf("len(small) is %d, less than %d", len(small), len(all))
- }
- for i, n := range all {
- if small[i] != n {
- t.Errorf("small read %q mismatch: %v", small[i], n)
- }
- }
-}
-
-func TestReaddirNValues(t *testing.T) {
- if testing.Short() {
- t.Skip("test.short; skipping")
- }
- dir, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("TempDir: %v", err)
- }
- defer RemoveAll(dir)
- for i := 1; i <= 105; i++ {
- f, err := Create(filepath.Join(dir, fmt.Sprintf("%d", i)))
- if err != nil {
- t.Fatalf("Create: %v", err)
- }
- f.Write([]byte(strings.Repeat("X", i)))
- f.Close()
- }
-
- var d *File
- openDir := func() {
- var err error
- d, err = Open(dir)
- if err != nil {
- t.Fatalf("Open directory: %v", err)
- }
- }
-
- readDirExpect := func(n, want int, wantErr error) {
- fi, err := d.Readdir(n)
- if err != wantErr {
- t.Fatalf("Readdir of %d got error %v, want %v", n, err, wantErr)
- }
- if g, e := len(fi), want; g != e {
- t.Errorf("Readdir of %d got %d files, want %d", n, g, e)
- }
- }
-
- readDirNamesExpect := func(n, want int, wantErr error) {
- fi, err := d.Readdirnames(n)
- if err != wantErr {
- t.Fatalf("Readdirnames of %d got error %v, want %v", n, err, wantErr)
- }
- if g, e := len(fi), want; g != e {
- t.Errorf("Readdirnames of %d got %d files, want %d", n, g, e)
- }
- }
-
- for _, fn := range []func(int, int, error){readDirExpect, readDirNamesExpect} {
- // Test the slurp case
- openDir()
- fn(0, 105, nil)
- fn(0, 0, nil)
- d.Close()
-
- // Slurp with -1 instead
- openDir()
- fn(-1, 105, nil)
- fn(-2, 0, nil)
- fn(0, 0, nil)
- d.Close()
-
- // Test the bounded case
- openDir()
- fn(1, 1, nil)
- fn(2, 2, nil)
- fn(105, 102, nil) // and tests buffer >100 case
- fn(3, 0, io.EOF)
- d.Close()
- }
-}
-
-func touch(t *testing.T, name string) {
- f, err := Create(name)
- if err != nil {
- t.Fatal(err)
- }
- if err := f.Close(); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestReaddirStatFailures(t *testing.T) {
- switch runtime.GOOS {
- case "windows", "plan9":
- // Windows and Plan 9 already do this correctly,
- // but are structured with different syscalls such
- // that they don't use Lstat, so the hook below for
- // testing it wouldn't work.
- t.Skipf("skipping test on %v", runtime.GOOS)
- }
- dir, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("TempDir: %v", err)
- }
- defer RemoveAll(dir)
- touch(t, filepath.Join(dir, "good1"))
- touch(t, filepath.Join(dir, "x")) // will disappear or have an error
- touch(t, filepath.Join(dir, "good2"))
- defer func() {
- *LstatP = Lstat
- }()
- var xerr error // error to return for x
- *LstatP = func(path string) (FileInfo, error) {
- if xerr != nil && strings.HasSuffix(path, "x") {
- return nil, xerr
- }
- return Lstat(path)
- }
- readDir := func() ([]FileInfo, error) {
- d, err := Open(dir)
- if err != nil {
- t.Fatal(err)
- }
- defer d.Close()
- return d.Readdir(-1)
- }
- mustReadDir := func(testName string) []FileInfo {
- fis, err := readDir()
- if err != nil {
- t.Fatalf("%s: Readdir: %v", testName, err)
- }
- return fis
- }
- names := func(fis []FileInfo) []string {
- s := make([]string, len(fis))
- for i, fi := range fis {
- s[i] = fi.Name()
- }
- sort.Strings(s)
- return s
- }
-
- if got, want := names(mustReadDir("inital readdir")),
- []string{"good1", "good2", "x"}; !reflect.DeepEqual(got, want) {
- t.Errorf("initial readdir got %q; want %q", got, want)
- }
-
- xerr = ErrNotExist
- if got, want := names(mustReadDir("with x disappearing")),
- []string{"good1", "good2"}; !reflect.DeepEqual(got, want) {
- t.Errorf("with x disappearing, got %q; want %q", got, want)
- }
-
- xerr = errors.New("some real error")
- if _, err := readDir(); err != xerr {
- t.Errorf("with a non-ErrNotExist error, got error %v; want %v", err, xerr)
- }
-}
-
-func TestHardLink(t *testing.T) {
- // Hardlinks are not supported under windows or Plan 9.
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
- return
- }
- from, to := "hardlinktestfrom", "hardlinktestto"
- Remove(from) // Just in case.
- file, err := Create(to)
- if err != nil {
- t.Fatalf("open %q failed: %v", to, err)
- }
- defer Remove(to)
- if err = file.Close(); err != nil {
- t.Errorf("close %q failed: %v", to, err)
- }
- err = Link(to, from)
- if err != nil {
- t.Fatalf("link %q, %q failed: %v", to, from, err)
- }
- defer Remove(from)
- tostat, err := Stat(to)
- if err != nil {
- t.Fatalf("stat %q failed: %v", to, err)
- }
- fromstat, err := Stat(from)
- if err != nil {
- t.Fatalf("stat %q failed: %v", from, err)
- }
- if !SameFile(tostat, fromstat) {
- t.Errorf("link %q, %q did not create hard link", to, from)
- }
-}
-
-func TestSymlink(t *testing.T) {
- switch runtime.GOOS {
- case "windows", "plan9", "nacl":
- t.Skipf("skipping on %s", runtime.GOOS)
- }
- from, to := "symlinktestfrom", "symlinktestto"
- Remove(from) // Just in case.
- file, err := Create(to)
- if err != nil {
- t.Fatalf("open %q failed: %v", to, err)
- }
- defer Remove(to)
- if err = file.Close(); err != nil {
- t.Errorf("close %q failed: %v", to, err)
- }
- err = Symlink(to, from)
- if err != nil {
- t.Fatalf("symlink %q, %q failed: %v", to, from, err)
- }
- defer Remove(from)
- tostat, err := Lstat(to)
- if err != nil {
- t.Fatalf("stat %q failed: %v", to, err)
- }
- if tostat.Mode()&ModeSymlink != 0 {
- t.Fatalf("stat %q claims to have found a symlink", to)
- }
- fromstat, err := Stat(from)
- if err != nil {
- t.Fatalf("stat %q failed: %v", from, err)
- }
- if !SameFile(tostat, fromstat) {
- t.Errorf("symlink %q, %q did not create symlink", to, from)
- }
- fromstat, err = Lstat(from)
- if err != nil {
- t.Fatalf("lstat %q failed: %v", from, err)
- }
- if fromstat.Mode()&ModeSymlink == 0 {
- t.Fatalf("symlink %q, %q did not create symlink", to, from)
- }
- fromstat, err = Stat(from)
- if err != nil {
- t.Fatalf("stat %q failed: %v", from, err)
- }
- if fromstat.Mode()&ModeSymlink != 0 {
- t.Fatalf("stat %q did not follow symlink", from)
- }
- s, err := Readlink(from)
- if err != nil {
- t.Fatalf("readlink %q failed: %v", from, err)
- }
- if s != to {
- t.Fatalf("after symlink %q != %q", s, to)
- }
- file, err = Open(from)
- if err != nil {
- t.Fatalf("open %q failed: %v", from, err)
- }
- file.Close()
-}
-
-func TestLongSymlink(t *testing.T) {
- switch runtime.GOOS {
- case "windows", "plan9", "nacl":
- t.Skipf("skipping on %s", runtime.GOOS)
- }
- s := "0123456789abcdef"
- // Long, but not too long: a common limit is 255.
- s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s
- from := "longsymlinktestfrom"
- Remove(from) // Just in case.
- err := Symlink(s, from)
- if err != nil {
- t.Fatalf("symlink %q, %q failed: %v", s, from, err)
- }
- defer Remove(from)
- r, err := Readlink(from)
- if err != nil {
- t.Fatalf("readlink %q failed: %v", from, err)
- }
- if r != s {
- t.Fatalf("after symlink %q != %q", r, s)
- }
-}
-
-func TestRename(t *testing.T) {
- from, to := "renamefrom", "renameto"
- Remove(to) // Just in case.
- file, err := Create(from)
- if err != nil {
- t.Fatalf("open %q failed: %v", to, err)
- }
- if err = file.Close(); err != nil {
- t.Errorf("close %q failed: %v", to, err)
- }
- err = Rename(from, to)
- if err != nil {
- t.Fatalf("rename %q, %q failed: %v", to, from, err)
- }
- defer Remove(to)
- _, err = Stat(to)
- if err != nil {
- t.Errorf("stat %q failed: %v", to, err)
- }
-}
-
-func exec(t *testing.T, dir, cmd string, args []string, expect string) {
- r, w, err := Pipe()
- if err != nil {
- t.Fatalf("Pipe: %v", err)
- }
- defer r.Close()
- attr := &ProcAttr{Dir: dir, Files: []*File{nil, w, Stderr}}
- p, err := StartProcess(cmd, args, attr)
- if err != nil {
- t.Fatalf("StartProcess: %v", err)
- }
- w.Close()
-
- var b bytes.Buffer
- io.Copy(&b, r)
- output := b.String()
-
- fi1, _ := Stat(strings.TrimSpace(output))
- fi2, _ := Stat(expect)
- if !SameFile(fi1, fi2) {
- t.Errorf("exec %q returned %q wanted %q",
- strings.Join(append([]string{cmd}, args...), " "), output, expect)
- }
- p.Wait()
-}
-
-func TestStartProcess(t *testing.T) {
- if runtime.GOOS == "nacl" {
- t.Skip("skipping on nacl")
- }
-
- var dir, cmd string
- var args []string
- if runtime.GOOS == "windows" {
- cmd = Getenv("COMSPEC")
- dir = Getenv("SystemRoot")
- args = []string{"/c", "cd"}
- } else {
- cmd = "/bin/pwd"
- dir = "/"
- args = []string{}
- }
- cmddir, cmdbase := filepath.Split(cmd)
- args = append([]string{cmdbase}, args...)
- // Test absolute executable path.
- exec(t, dir, cmd, args, dir)
- // Test relative executable path.
- exec(t, cmddir, cmdbase, args, cmddir)
-}
-
-func checkMode(t *testing.T, path string, mode FileMode) {
- dir, err := Stat(path)
- if err != nil {
- t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
- }
- if dir.Mode()&0777 != mode {
- t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode(), mode)
- }
-}
-
-func TestChmod(t *testing.T) {
- // Chmod is not supported under windows.
- if runtime.GOOS == "windows" {
- return
- }
- f := newFile("TestChmod", t)
- defer Remove(f.Name())
- defer f.Close()
-
- if err := Chmod(f.Name(), 0456); err != nil {
- t.Fatalf("chmod %s 0456: %s", f.Name(), err)
- }
- checkMode(t, f.Name(), 0456)
-
- if err := f.Chmod(0123); err != nil {
- t.Fatalf("chmod %s 0123: %s", f.Name(), err)
- }
- checkMode(t, f.Name(), 0123)
-}
-
-func checkSize(t *testing.T, f *File, size int64) {
- dir, err := f.Stat()
- if err != nil {
- t.Fatalf("Stat %q (looking for size %d): %s", f.Name(), size, err)
- }
- if dir.Size() != size {
- t.Errorf("Stat %q: size %d want %d", f.Name(), dir.Size(), size)
- }
-}
-
-func TestFTruncate(t *testing.T) {
- f := newFile("TestFTruncate", t)
- defer Remove(f.Name())
- defer f.Close()
-
- checkSize(t, f, 0)
- f.Write([]byte("hello, world\n"))
- checkSize(t, f, 13)
- f.Truncate(10)
- checkSize(t, f, 10)
- f.Truncate(1024)
- checkSize(t, f, 1024)
- f.Truncate(0)
- checkSize(t, f, 0)
- _, err := f.Write([]byte("surprise!"))
- if err == nil {
- checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
- }
-}
-
-func TestTruncate(t *testing.T) {
- f := newFile("TestTruncate", t)
- defer Remove(f.Name())
- defer f.Close()
-
- checkSize(t, f, 0)
- f.Write([]byte("hello, world\n"))
- checkSize(t, f, 13)
- Truncate(f.Name(), 10)
- checkSize(t, f, 10)
- Truncate(f.Name(), 1024)
- checkSize(t, f, 1024)
- Truncate(f.Name(), 0)
- checkSize(t, f, 0)
- _, err := f.Write([]byte("surprise!"))
- if err == nil {
- checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
- }
-}
-
-// Use TempDir() to make sure we're on a local file system,
-// so that timings are not distorted by latency and caching.
-// On NFS, timings can be off due to caching of meta-data on
-// NFS servers (Issue 848).
-func TestChtimes(t *testing.T) {
- f := newFile("TestChtimes", t)
- defer Remove(f.Name())
- defer f.Close()
-
- f.Write([]byte("hello, world\n"))
- f.Close()
-
- st, err := Stat(f.Name())
- if err != nil {
- t.Fatalf("Stat %s: %s", f.Name(), err)
- }
- preStat := st
-
- // Move access and modification time back a second
- at := Atime(preStat)
- mt := preStat.ModTime()
- err = Chtimes(f.Name(), at.Add(-time.Second), mt.Add(-time.Second))
- if err != nil {
- t.Fatalf("Chtimes %s: %s", f.Name(), err)
- }
-
- st, err = Stat(f.Name())
- if err != nil {
- t.Fatalf("second Stat %s: %s", f.Name(), err)
- }
- postStat := st
-
- /* Plan 9, NaCl:
- Mtime is the time of the last change of content. Similarly, atime is set whenever the
- contents are accessed; also, it is set whenever mtime is set.
- */
- pat := Atime(postStat)
- pmt := postStat.ModTime()
- if !pat.Before(at) && runtime.GOOS != "plan9" && runtime.GOOS != "nacl" {
- t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat)
- }
-
- if !pmt.Before(mt) {
- t.Errorf("ModTime didn't go backwards; was=%d, after=%d", mt, pmt)
- }
-}
-
-func TestChdirAndGetwd(t *testing.T) {
- // TODO(brainman): file.Chdir() is not implemented on windows.
- if runtime.GOOS == "windows" {
- return
- }
- fd, err := Open(".")
- if err != nil {
- t.Fatalf("Open .: %s", err)
- }
- // These are chosen carefully not to be symlinks on a Mac
- // (unlike, say, /var, /etc, and /tmp).
- dirs := []string{"/", "/usr/bin"}
- // /usr/bin does not usually exist on Plan 9.
- if runtime.GOOS == "plan9" {
- dirs = []string{"/", "/usr"}
- }
- for mode := 0; mode < 2; mode++ {
- for _, d := range dirs {
- if mode == 0 {
- err = Chdir(d)
- } else {
- fd1, err := Open(d)
- if err != nil {
- t.Errorf("Open %s: %s", d, err)
- continue
- }
- err = fd1.Chdir()
- fd1.Close()
- }
- pwd, err1 := Getwd()
- err2 := fd.Chdir()
- if err2 != nil {
- // We changed the current directory and cannot go back.
- // Don't let the tests continue; they'll scribble
- // all over some other directory.
- fmt.Fprintf(Stderr, "fchdir back to dot failed: %s\n", err2)
- Exit(1)
- }
- if err != nil {
- fd.Close()
- t.Fatalf("Chdir %s: %s", d, err)
- }
- if err1 != nil {
- fd.Close()
- t.Fatalf("Getwd in %s: %s", d, err1)
- }
- if pwd != d {
- fd.Close()
- t.Fatalf("Getwd returned %q want %q", pwd, d)
- }
- }
- }
- fd.Close()
-}
-
-func TestSeek(t *testing.T) {
- f := newFile("TestSeek", t)
- defer Remove(f.Name())
- defer f.Close()
-
- const data = "hello, world\n"
- io.WriteString(f, data)
-
- type test struct {
- in int64
- whence int
- out int64
- }
- var tests = []test{
- {0, 1, int64(len(data))},
- {0, 0, 0},
- {5, 0, 5},
- {0, 2, int64(len(data))},
- {0, 0, 0},
- {-1, 2, int64(len(data)) - 1},
- {1 << 33, 0, 1 << 33},
- {1 << 33, 2, 1<<33 + int64(len(data))},
- }
- for i, tt := range tests {
- off, err := f.Seek(tt.in, tt.whence)
- if off != tt.out || err != nil {
- if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 {
- // Reiserfs rejects the big seeks.
- // http://code.google.com/p/go/issues/detail?id=91
- break
- }
- t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
- }
- }
-}
-
-type openErrorTest struct {
- path string
- mode int
- error error
-}
-
-var openErrorTests = []openErrorTest{
- {
- sfdir + "/no-such-file",
- O_RDONLY,
- syscall.ENOENT,
- },
- {
- sfdir,
- O_WRONLY,
- syscall.EISDIR,
- },
- {
- sfdir + "/" + sfname + "/no-such-file",
- O_WRONLY,
- syscall.ENOTDIR,
- },
-}
-
-func TestOpenError(t *testing.T) {
- for _, tt := range openErrorTests {
- f, err := OpenFile(tt.path, tt.mode, 0)
- if err == nil {
- t.Errorf("Open(%q, %d) succeeded", tt.path, tt.mode)
- f.Close()
- continue
- }
- perr, ok := err.(*PathError)
- if !ok {
- t.Errorf("Open(%q, %d) returns error of %T type; want *PathError", tt.path, tt.mode, err)
- }
- if perr.Err != tt.error {
- if runtime.GOOS == "plan9" {
- syscallErrStr := perr.Err.Error()
- expectedErrStr := strings.Replace(tt.error.Error(), "file ", "", 1)
- if !strings.HasSuffix(syscallErrStr, expectedErrStr) {
- t.Errorf("Open(%q, %d) = _, %q; want suffix %q", tt.path, tt.mode, syscallErrStr, expectedErrStr)
- }
- continue
- }
- if runtime.GOOS == "dragonfly" {
- // DragonFly incorrectly returns EACCES rather
- // EISDIR when a directory is opened for write.
- if tt.error == syscall.EISDIR && perr.Err == syscall.EACCES {
- continue
- }
- }
- t.Errorf("Open(%q, %d) = _, %q; want %q", tt.path, tt.mode, perr.Err.Error(), tt.error.Error())
- }
- }
-}
-
-func TestOpenNoName(t *testing.T) {
- f, err := Open("")
- if err == nil {
- t.Fatal(`Open("") succeeded`)
- f.Close()
- }
-}
-
-func run(t *testing.T, cmd []string) string {
- // Run /bin/hostname and collect output.
- r, w, err := Pipe()
- if err != nil {
- t.Fatal(err)
- }
- defer r.Close()
- p, err := StartProcess("/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}})
- if err != nil {
- t.Fatal(err)
- }
- w.Close()
-
- var b bytes.Buffer
- io.Copy(&b, r)
- _, err = p.Wait()
- if err != nil {
- t.Fatalf("run hostname Wait: %v", err)
- }
- err = p.Kill()
- if err == nil {
- t.Errorf("expected an error from Kill running 'hostname'")
- }
- output := b.String()
- if n := len(output); n > 0 && output[n-1] == '\n' {
- output = output[0 : n-1]
- }
- if output == "" {
- t.Fatalf("%v produced no output", cmd)
- }
-
- return output
-}
-
-func TestHostname(t *testing.T) {
- // There is no other way to fetch hostname on windows, but via winapi.
- // On Plan 9 it is can be taken from #c/sysname as Hostname() does.
- switch runtime.GOOS {
- case "windows", "plan9", "nacl":
- t.Skipf("skipping on %s", runtime.GOOS)
- }
-
- // Check internal Hostname() against the output of /bin/hostname.
- // Allow that the internal Hostname returns a Fully Qualified Domain Name
- // and the /bin/hostname only returns the first component
- hostname, err := Hostname()
- if err != nil {
- t.Fatalf("%v", err)
- }
- want := run(t, []string{"/bin/hostname"})
- if hostname != want {
- i := strings.Index(hostname, ".")
- if i < 0 || hostname[0:i] != want {
- t.Errorf("Hostname() = %q, want %q", hostname, want)
- }
- }
-}
-
-func TestReadAt(t *testing.T) {
- f := newFile("TestReadAt", t)
- defer Remove(f.Name())
- defer f.Close()
-
- const data = "hello, world\n"
- io.WriteString(f, data)
-
- b := make([]byte, 5)
- n, err := f.ReadAt(b, 7)
- if err != nil || n != len(b) {
- t.Fatalf("ReadAt 7: %d, %v", n, err)
- }
- if string(b) != "world" {
- t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
- }
-}
-
-func TestWriteAt(t *testing.T) {
- f := newFile("TestWriteAt", t)
- defer Remove(f.Name())
- defer f.Close()
-
- const data = "hello, world\n"
- io.WriteString(f, data)
-
- n, err := f.WriteAt([]byte("WORLD"), 7)
- if err != nil || n != 5 {
- t.Fatalf("WriteAt 7: %d, %v", n, err)
- }
-
- b, err := ioutil.ReadFile(f.Name())
- if err != nil {
- t.Fatalf("ReadFile %s: %v", f.Name(), err)
- }
- if string(b) != "hello, WORLD\n" {
- t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n")
- }
-}
-
-func writeFile(t *testing.T, fname string, flag int, text string) string {
- f, err := OpenFile(fname, flag, 0666)
- if err != nil {
- t.Fatalf("Open: %v", err)
- }
- n, err := io.WriteString(f, text)
- if err != nil {
- t.Fatalf("WriteString: %d, %v", n, err)
- }
- f.Close()
- data, err := ioutil.ReadFile(fname)
- if err != nil {
- t.Fatalf("ReadFile: %v", err)
- }
- return string(data)
-}
-
-func TestAppend(t *testing.T) {
- const f = "append.txt"
- defer Remove(f)
- s := writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
- if s != "new" {
- t.Fatalf("writeFile: have %q want %q", s, "new")
- }
- s = writeFile(t, f, O_APPEND|O_RDWR, "|append")
- if s != "new|append" {
- t.Fatalf("writeFile: have %q want %q", s, "new|append")
- }
- s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "|append")
- if s != "new|append|append" {
- t.Fatalf("writeFile: have %q want %q", s, "new|append|append")
- }
- err := Remove(f)
- if err != nil {
- t.Fatalf("Remove: %v", err)
- }
- s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "new&append")
- if s != "new&append" {
- t.Fatalf("writeFile: after append have %q want %q", s, "new&append")
- }
- s = writeFile(t, f, O_CREATE|O_RDWR, "old")
- if s != "old&append" {
- t.Fatalf("writeFile: after create have %q want %q", s, "old&append")
- }
- s = writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
- if s != "new" {
- t.Fatalf("writeFile: after truncate have %q want %q", s, "new")
- }
-}
-
-func TestStatDirWithTrailingSlash(t *testing.T) {
- // Create new temporary directory and arrange to clean it up.
- path, err := ioutil.TempDir("", "/_TestStatDirWithSlash_")
- if err != nil {
- t.Fatalf("TempDir: %s", err)
- }
- defer RemoveAll(path)
-
- // Stat of path should succeed.
- _, err = Stat(path)
- if err != nil {
- t.Fatalf("stat %s failed: %s", path, err)
- }
-
- // Stat of path+"/" should succeed too.
- path += "/"
- _, err = Stat(path)
- if err != nil {
- t.Fatalf("stat %s failed: %s", path, err)
- }
-}
-
-func TestNilProcessStateString(t *testing.T) {
- var ps *ProcessState
- s := ps.String()
- if s != "<nil>" {
- t.Errorf("(*ProcessState)(nil).String() = %q, want %q", s, "<nil>")
- }
-}
-
-func TestSameFile(t *testing.T) {
- fa, err := Create("a")
- if err != nil {
- t.Fatalf("Create(a): %v", err)
- }
- defer Remove(fa.Name())
- fa.Close()
- fb, err := Create("b")
- if err != nil {
- t.Fatalf("Create(b): %v", err)
- }
- defer Remove(fb.Name())
- fb.Close()
-
- ia1, err := Stat("a")
- if err != nil {
- t.Fatalf("Stat(a): %v", err)
- }
- ia2, err := Stat("a")
- if err != nil {
- t.Fatalf("Stat(a): %v", err)
- }
- if !SameFile(ia1, ia2) {
- t.Errorf("files should be same")
- }
-
- ib, err := Stat("b")
- if err != nil {
- t.Fatalf("Stat(b): %v", err)
- }
- if SameFile(ia1, ib) {
- t.Errorf("files should be different")
- }
-}
-
-func TestDevNullFile(t *testing.T) {
- f, err := Open(DevNull)
- if err != nil {
- t.Fatalf("Open(%s): %v", DevNull, err)
- }
- defer f.Close()
- fi, err := f.Stat()
- if err != nil {
- t.Fatalf("Stat(%s): %v", DevNull, err)
- }
- name := filepath.Base(DevNull)
- if fi.Name() != name {
- t.Fatalf("wrong file name have %v want %v", fi.Name(), name)
- }
- if fi.Size() != 0 {
- t.Fatalf("wrong file size have %d want 0", fi.Size())
- }
-}
-
-var testLargeWrite = flag.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
-
-func TestLargeWriteToConsole(t *testing.T) {
- if !*testLargeWrite {
- t.Skip("skipping console-flooding test; enable with -large_write")
- }
- b := make([]byte, 32000)
- for i := range b {
- b[i] = '.'
- }
- b[len(b)-1] = '\n'
- n, err := Stdout.Write(b)
- if err != nil {
- t.Fatalf("Write to os.Stdout failed: %v", err)
- }
- if n != len(b) {
- t.Errorf("Write to os.Stdout should return %d; got %d", len(b), n)
- }
- n, err = Stderr.Write(b)
- if err != nil {
- t.Fatalf("Write to os.Stderr failed: %v", err)
- }
- if n != len(b) {
- t.Errorf("Write to os.Stderr should return %d; got %d", len(b), n)
- }
-}
-
-func TestStatDirModeExec(t *testing.T) {
- const mode = 0111
-
- path, err := ioutil.TempDir("", "go-build")
- if err != nil {
- t.Fatalf("Failed to create temp directory: %v", err)
- }
- defer RemoveAll(path)
-
- if err := Chmod(path, 0777); err != nil {
- t.Fatalf("Chmod %q 0777: %v", path, err)
- }
-
- dir, err := Stat(path)
- if err != nil {
- t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
- }
- if dir.Mode()&mode != mode {
- t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode()&mode, mode)
- }
-}
-
-func TestReadAtEOF(t *testing.T) {
- f := newFile("TestReadAtEOF", t)
- defer Remove(f.Name())
- defer f.Close()
-
- _, err := f.ReadAt(make([]byte, 10), 0)
- switch err {
- case io.EOF:
- // all good
- case nil:
- t.Fatalf("ReadAt succeeded")
- default:
- t.Fatalf("ReadAt failed: %s", err)
- }
-}
-
-func testKillProcess(t *testing.T, processKiller func(p *Process)) {
- if runtime.GOOS == "nacl" {
- t.Skip("skipping on nacl")
- }
-
- dir, err := ioutil.TempDir("", "go-build")
- if err != nil {
- t.Fatalf("Failed to create temp directory: %v", err)
- }
- defer RemoveAll(dir)
-
- src := filepath.Join(dir, "main.go")
- f, err := Create(src)
- if err != nil {
- t.Fatalf("Failed to create %v: %v", src, err)
- }
- st := template.Must(template.New("source").Parse(`
-package main
-import "time"
-func main() {
- time.Sleep(time.Second)
-}
-`))
- err = st.Execute(f, nil)
- if err != nil {
- f.Close()
- t.Fatalf("Failed to execute template: %v", err)
- }
- f.Close()
-
- exe := filepath.Join(dir, "main.exe")
- output, err := osexec.Command("go", "build", "-o", exe, src).CombinedOutput()
- if err != nil {
- t.Fatalf("Failed to build exe %v: %v %v", exe, err, string(output))
- }
-
- cmd := osexec.Command(exe)
- err = cmd.Start()
- if err != nil {
- t.Fatalf("Failed to start test process: %v", err)
- }
- go func() {
- time.Sleep(100 * time.Millisecond)
- processKiller(cmd.Process)
- }()
- err = cmd.Wait()
- if err == nil {
- t.Errorf("Test process succeeded, but expected to fail")
- }
-}
-
-func TestKillStartProcess(t *testing.T) {
- testKillProcess(t, func(p *Process) {
- err := p.Kill()
- if err != nil {
- t.Fatalf("Failed to kill test process: %v", err)
- }
- })
-}
-
-func TestKillFindProcess(t *testing.T) {
- testKillProcess(t, func(p *Process) {
- p2, err := FindProcess(p.Pid)
- if err != nil {
- t.Fatalf("Failed to find test process: %v", err)
- }
- err = p2.Kill()
- if err != nil {
- t.Fatalf("Failed to kill test process: %v", err)
- }
- })
-}
-
-var nilFileMethodTests = []struct {
- name string
- f func(*File) error
-}{
- {"Chdir", func(f *File) error { return f.Chdir() }},
- {"Close", func(f *File) error { return f.Close() }},
- {"Chmod", func(f *File) error { return f.Chmod(0) }},
- {"Chown", func(f *File) error { return f.Chown(0, 0) }},
- {"Read", func(f *File) error { _, err := f.Read(make([]byte, 0)); return err }},
- {"ReadAt", func(f *File) error { _, err := f.ReadAt(make([]byte, 0), 0); return err }},
- {"Readdir", func(f *File) error { _, err := f.Readdir(1); return err }},
- {"Readdirnames", func(f *File) error { _, err := f.Readdirnames(1); return err }},
- {"Seek", func(f *File) error { _, err := f.Seek(0, 0); return err }},
- {"Stat", func(f *File) error { _, err := f.Stat(); return err }},
- {"Sync", func(f *File) error { return f.Sync() }},
- {"Truncate", func(f *File) error { return f.Truncate(0) }},
- {"Write", func(f *File) error { _, err := f.Write(make([]byte, 0)); return err }},
- {"WriteAt", func(f *File) error { _, err := f.WriteAt(make([]byte, 0), 0); return err }},
- {"WriteString", func(f *File) error { _, err := f.WriteString(""); return err }},
-}
-
-// Test that all File methods give ErrInvalid if the receiver is nil.
-func TestNilFileMethods(t *testing.T) {
- for _, tt := range nilFileMethodTests {
- var file *File
- got := tt.f(file)
- if got != ErrInvalid {
- t.Errorf("%v should fail when f is nil; got %v", tt.name, got)
- }
- }
-}
diff --git a/src/pkg/os/os_unix_test.go b/src/pkg/os/os_unix_test.go
deleted file mode 100644
index 21d40ccaf..000000000
--- a/src/pkg/os/os_unix_test.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package os_test
-
-import (
- . "os"
- "runtime"
- "syscall"
- "testing"
-)
-
-func checkUidGid(t *testing.T, path string, uid, gid int) {
- dir, err := Stat(path)
- if err != nil {
- t.Fatalf("Stat %q (looking for uid/gid %d/%d): %s", path, uid, gid, err)
- }
- sys := dir.Sys().(*syscall.Stat_t)
- if int(sys.Uid) != uid {
- t.Errorf("Stat %q: uid %d want %d", path, sys.Uid, uid)
- }
- if int(sys.Gid) != gid {
- t.Errorf("Stat %q: gid %d want %d", path, sys.Gid, gid)
- }
-}
-
-func TestChown(t *testing.T) {
- // Chown is not supported under windows os Plan 9.
- // Plan9 provides a native ChownPlan9 version instead.
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
- return
- }
- // Use TempDir() to make sure we're on a local file system,
- // so that the group ids returned by Getgroups will be allowed
- // on the file. On NFS, the Getgroups groups are
- // basically useless.
- f := newFile("TestChown", t)
- defer Remove(f.Name())
- defer f.Close()
- dir, err := f.Stat()
- if err != nil {
- t.Fatalf("stat %s: %s", f.Name(), err)
- }
-
- // Can't change uid unless root, but can try
- // changing the group id. First try our current group.
- gid := Getgid()
- t.Log("gid:", gid)
- if err = Chown(f.Name(), -1, gid); err != nil {
- t.Fatalf("chown %s -1 %d: %s", f.Name(), gid, err)
- }
- sys := dir.Sys().(*syscall.Stat_t)
- checkUidGid(t, f.Name(), int(sys.Uid), gid)
-
- // Then try all the auxiliary groups.
- groups, err := Getgroups()
- if err != nil {
- t.Fatalf("getgroups: %s", err)
- }
- t.Log("groups: ", groups)
- for _, g := range groups {
- if err = Chown(f.Name(), -1, g); err != nil {
- t.Fatalf("chown %s -1 %d: %s", f.Name(), g, err)
- }
- checkUidGid(t, f.Name(), int(sys.Uid), g)
-
- // change back to gid to test fd.Chown
- if err = f.Chown(-1, gid); err != nil {
- t.Fatalf("fchown %s -1 %d: %s", f.Name(), gid, err)
- }
- checkUidGid(t, f.Name(), int(sys.Uid), gid)
- }
-}
diff --git a/src/pkg/os/path.go b/src/pkg/os/path.go
deleted file mode 100644
index 02a77ec80..000000000
--- a/src/pkg/os/path.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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.
-
-package os
-
-import (
- "io"
- "syscall"
-)
-
-// MkdirAll creates a directory named path,
-// along with any necessary parents, and returns nil,
-// or else returns an error.
-// The permission bits perm are used for all
-// directories that MkdirAll creates.
-// If path is already a directory, MkdirAll does nothing
-// and returns nil.
-func MkdirAll(path string, perm FileMode) error {
- // If path exists, stop with success or error.
- dir, err := Stat(path)
- if err == nil {
- if dir.IsDir() {
- return nil
- }
- return &PathError{"mkdir", path, syscall.ENOTDIR}
- }
-
- // Doesn't already exist; make sure parent does.
- i := len(path)
- for i > 0 && IsPathSeparator(path[i-1]) { // Skip trailing path separator.
- i--
- }
-
- j := i
- for j > 0 && !IsPathSeparator(path[j-1]) { // Scan backward over element.
- j--
- }
-
- if j > 1 {
- // Create parent
- err = MkdirAll(path[0:j-1], perm)
- if err != nil {
- return err
- }
- }
-
- // Now parent exists, try to create.
- err = Mkdir(path, perm)
- if err != nil {
- // Handle arguments like "foo/." by
- // double-checking that directory doesn't exist.
- dir, err1 := Lstat(path)
- if err1 == nil && dir.IsDir() {
- return nil
- }
- return err
- }
- return nil
-}
-
-// RemoveAll removes path and any children it contains.
-// It removes everything it can but returns the first error
-// it encounters. If the path does not exist, RemoveAll
-// returns nil (no error).
-func RemoveAll(path string) error {
- // Simple case: if Remove works, we're done.
- err := Remove(path)
- if err == nil {
- return nil
- }
-
- // Otherwise, is this a directory we need to recurse into?
- dir, serr := Lstat(path)
- if serr != nil {
- if serr, ok := serr.(*PathError); ok && (IsNotExist(serr.Err) || serr.Err == syscall.ENOTDIR) {
- return nil
- }
- return serr
- }
- if !dir.IsDir() {
- // Not a directory; return the error from Remove.
- return err
- }
-
- // Directory.
- fd, err := Open(path)
- if err != nil {
- return err
- }
-
- // Remove contents & return first error.
- err = nil
- for {
- names, err1 := fd.Readdirnames(100)
- for _, name := range names {
- err1 := RemoveAll(path + string(PathSeparator) + name)
- if err == nil {
- err = err1
- }
- }
- if err1 == io.EOF {
- break
- }
- // If Readdirnames returned an error, use it.
- if err == nil {
- err = err1
- }
- if len(names) == 0 {
- break
- }
- }
-
- // Close directory, because windows won't remove opened directory.
- fd.Close()
-
- // Remove directory.
- err1 := Remove(path)
- if err == nil {
- err = err1
- }
- return err
-}
diff --git a/src/pkg/os/path_plan9.go b/src/pkg/os/path_plan9.go
deleted file mode 100644
index 64bad500a..000000000
--- a/src/pkg/os/path_plan9.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2011 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.
-
-package os
-
-const (
- PathSeparator = '/' // OS-specific path separator
- PathListSeparator = '\000' // OS-specific path list separator
-)
-
-// IsPathSeparator returns true if c is a directory separator character.
-func IsPathSeparator(c uint8) bool {
- return PathSeparator == c
-}
diff --git a/src/pkg/os/path_test.go b/src/pkg/os/path_test.go
deleted file mode 100644
index 3af21cde9..000000000
--- a/src/pkg/os/path_test.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// 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.
-
-package os_test
-
-import (
- "io/ioutil"
- . "os"
- "path/filepath"
- "runtime"
- "syscall"
- "testing"
-)
-
-func TestMkdirAll(t *testing.T) {
- tmpDir := TempDir()
- path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
- err := MkdirAll(path, 0777)
- if err != nil {
- t.Fatalf("MkdirAll %q: %s", path, err)
- }
- defer RemoveAll(tmpDir + "/_TestMkdirAll_")
-
- // Already exists, should succeed.
- err = MkdirAll(path, 0777)
- if err != nil {
- t.Fatalf("MkdirAll %q (second time): %s", path, err)
- }
-
- // Make file.
- fpath := path + "/file"
- f, err := Create(fpath)
- if err != nil {
- t.Fatalf("create %q: %s", fpath, err)
- }
- defer f.Close()
-
- // Can't make directory named after file.
- err = MkdirAll(fpath, 0777)
- if err == nil {
- t.Fatalf("MkdirAll %q: no error", fpath)
- }
- perr, ok := err.(*PathError)
- if !ok {
- t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
- }
- if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
- t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
- }
-
- // Can't make subdirectory of file.
- ffpath := fpath + "/subdir"
- err = MkdirAll(ffpath, 0777)
- if err == nil {
- t.Fatalf("MkdirAll %q: no error", ffpath)
- }
- perr, ok = err.(*PathError)
- if !ok {
- t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
- }
- if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
- t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
- }
-
- if runtime.GOOS == "windows" {
- path := tmpDir + `\_TestMkdirAll_\dir\.\dir2\`
- err := MkdirAll(path, 0777)
- if err != nil {
- t.Fatalf("MkdirAll %q: %s", path, err)
- }
- }
-}
-
-func TestRemoveAll(t *testing.T) {
- tmpDir := TempDir()
- // Work directory.
- path := tmpDir + "/_TestRemoveAll_"
- fpath := path + "/file"
- dpath := path + "/dir"
-
- // Make directory with 1 file and remove.
- if err := MkdirAll(path, 0777); err != nil {
- t.Fatalf("MkdirAll %q: %s", path, err)
- }
- fd, err := Create(fpath)
- if err != nil {
- t.Fatalf("create %q: %s", fpath, err)
- }
- fd.Close()
- if err = RemoveAll(path); err != nil {
- t.Fatalf("RemoveAll %q (first): %s", path, err)
- }
- if _, err = Lstat(path); err == nil {
- t.Fatalf("Lstat %q succeeded after RemoveAll (first)", path)
- }
-
- // Make directory with file and subdirectory and remove.
- if err = MkdirAll(dpath, 0777); err != nil {
- t.Fatalf("MkdirAll %q: %s", dpath, err)
- }
- fd, err = Create(fpath)
- if err != nil {
- t.Fatalf("create %q: %s", fpath, err)
- }
- fd.Close()
- fd, err = Create(dpath + "/file")
- if err != nil {
- t.Fatalf("create %q: %s", fpath, err)
- }
- fd.Close()
- if err = RemoveAll(path); err != nil {
- t.Fatalf("RemoveAll %q (second): %s", path, err)
- }
- if _, err := Lstat(path); err == nil {
- t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path)
- }
-
- // Determine if we should run the following test.
- testit := true
- if runtime.GOOS == "windows" {
- // Chmod is not supported under windows.
- testit = false
- } else {
- // Test fails as root.
- testit = Getuid() != 0
- }
- if testit {
- // Make directory with file and subdirectory and trigger error.
- if err = MkdirAll(dpath, 0777); err != nil {
- t.Fatalf("MkdirAll %q: %s", dpath, err)
- }
-
- for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} {
- fd, err = Create(s)
- if err != nil {
- t.Fatalf("create %q: %s", s, err)
- }
- fd.Close()
- }
- if err = Chmod(dpath, 0); err != nil {
- t.Fatalf("Chmod %q 0: %s", dpath, err)
- }
-
- // No error checking here: either RemoveAll
- // will or won't be able to remove dpath;
- // either way we want to see if it removes fpath
- // and path/zzz. Reasons why RemoveAll might
- // succeed in removing dpath as well include:
- // * running as root
- // * running on a file system without permissions (FAT)
- RemoveAll(path)
- Chmod(dpath, 0777)
-
- for _, s := range []string{fpath, path + "/zzz"} {
- if _, err = Lstat(s); err == nil {
- t.Fatalf("Lstat %q succeeded after partial RemoveAll", s)
- }
- }
- }
- if err = RemoveAll(path); err != nil {
- t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err)
- }
- if _, err = Lstat(path); err == nil {
- t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path)
- }
-}
-
-func TestMkdirAllWithSymlink(t *testing.T) {
- switch runtime.GOOS {
- case "nacl", "plan9", "windows":
- t.Skipf("skipping on %s", runtime.GOOS)
- }
-
- tmpDir, err := ioutil.TempDir("", "TestMkdirAllWithSymlink-")
- if err != nil {
- t.Fatal(err)
- }
- defer RemoveAll(tmpDir)
-
- dir := tmpDir + "/dir"
- err = Mkdir(dir, 0755)
- if err != nil {
- t.Fatalf("Mkdir %s: %s", dir, err)
- }
-
- link := tmpDir + "/link"
- err = Symlink("dir", link)
- if err != nil {
- t.Fatalf("Symlink %s: %s", link, err)
- }
-
- path := link + "/foo"
- err = MkdirAll(path, 0755)
- if err != nil {
- t.Errorf("MkdirAll %q: %s", path, err)
- }
-}
-
-func TestMkdirAllAtSlash(t *testing.T) {
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
- return
- }
- RemoveAll("/_go_os_test")
- err := MkdirAll("/_go_os_test/dir", 0777)
- if err != nil {
- pathErr, ok := err.(*PathError)
- // common for users not to be able to write to /
- if ok && pathErr.Err == syscall.EACCES {
- return
- }
- t.Fatalf(`MkdirAll "/_go_os_test/dir": %v`, err)
- }
- RemoveAll("/_go_os_test")
-}
diff --git a/src/pkg/os/path_unix.go b/src/pkg/os/path_unix.go
deleted file mode 100644
index 0211107dd..000000000
--- a/src/pkg/os/path_unix.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2011 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package os
-
-const (
- PathSeparator = '/' // OS-specific path separator
- PathListSeparator = ':' // OS-specific path list separator
-)
-
-// IsPathSeparator returns true if c is a directory separator character.
-func IsPathSeparator(c uint8) bool {
- return PathSeparator == c
-}
diff --git a/src/pkg/os/path_windows.go b/src/pkg/os/path_windows.go
deleted file mode 100644
index 61f2ca59f..000000000
--- a/src/pkg/os/path_windows.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2011 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.
-
-package os
-
-const (
- PathSeparator = '\\' // OS-specific path separator
- PathListSeparator = ';' // OS-specific path list separator
-)
-
-// IsPathSeparator returns true if c is a directory separator character.
-func IsPathSeparator(c uint8) bool {
- // NOTE: Windows accept / as path separator.
- return c == '\\' || c == '/'
-}
diff --git a/src/pkg/os/pipe_bsd.go b/src/pkg/os/pipe_bsd.go
deleted file mode 100644
index 3b81ed20f..000000000
--- a/src/pkg/os/pipe_bsd.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd nacl netbsd openbsd solaris
-
-package os
-
-import "syscall"
-
-// Pipe returns a connected pair of Files; reads from r return bytes written to w.
-// It returns the files and an error, if any.
-func Pipe() (r *File, w *File, err error) {
- var p [2]int
-
- // See ../syscall/exec.go for description of lock.
- syscall.ForkLock.RLock()
- e := syscall.Pipe(p[0:])
- if e != nil {
- syscall.ForkLock.RUnlock()
- return nil, nil, NewSyscallError("pipe", e)
- }
- syscall.CloseOnExec(p[0])
- syscall.CloseOnExec(p[1])
- syscall.ForkLock.RUnlock()
-
- return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
-}
diff --git a/src/pkg/os/pipe_linux.go b/src/pkg/os/pipe_linux.go
deleted file mode 100644
index 9bafad84f..000000000
--- a/src/pkg/os/pipe_linux.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013 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.
-
-package os
-
-import "syscall"
-
-// Pipe returns a connected pair of Files; reads from r return bytes written to w.
-// It returns the files and an error, if any.
-func Pipe() (r *File, w *File, err error) {
- var p [2]int
-
- e := syscall.Pipe2(p[0:], syscall.O_CLOEXEC)
- // pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
- // might not be implemented.
- if e == syscall.ENOSYS {
- // See ../syscall/exec.go for description of lock.
- syscall.ForkLock.RLock()
- e = syscall.Pipe(p[0:])
- if e != nil {
- syscall.ForkLock.RUnlock()
- return nil, nil, NewSyscallError("pipe", e)
- }
- syscall.CloseOnExec(p[0])
- syscall.CloseOnExec(p[1])
- syscall.ForkLock.RUnlock()
- } else if e != nil {
- return nil, nil, NewSyscallError("pipe2", e)
- }
-
- return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
-}
diff --git a/src/pkg/os/proc.go b/src/pkg/os/proc.go
deleted file mode 100644
index 38c436ec5..000000000
--- a/src/pkg/os/proc.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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.
-
-// Process etc.
-
-package os
-
-import "syscall"
-
-// Args hold the command-line arguments, starting with the program name.
-var Args []string
-
-// Getuid returns the numeric user id of the caller.
-func Getuid() int { return syscall.Getuid() }
-
-// Geteuid returns the numeric effective user id of the caller.
-func Geteuid() int { return syscall.Geteuid() }
-
-// Getgid returns the numeric group id of the caller.
-func Getgid() int { return syscall.Getgid() }
-
-// Getegid returns the numeric effective group id of the caller.
-func Getegid() int { return syscall.Getegid() }
-
-// Getgroups returns a list of the numeric ids of groups that the caller belongs to.
-func Getgroups() ([]int, error) {
- gids, e := syscall.Getgroups()
- return gids, NewSyscallError("getgroups", e)
-}
-
-// Exit causes the current program to exit with the given status code.
-// Conventionally, code zero indicates success, non-zero an error.
-// The program terminates immediately; deferred functions are
-// not run.
-func Exit(code int) { syscall.Exit(code) }
diff --git a/src/pkg/os/signal/example_test.go b/src/pkg/os/signal/example_test.go
deleted file mode 100644
index 079ee5070..000000000
--- a/src/pkg/os/signal/example_test.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2013 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.
-
-package signal_test
-
-import (
- "fmt"
- "os"
- "os/signal"
-)
-
-func ExampleNotify() {
- // Set up channel on which to send signal notifications.
- // We must use a buffered channel or risk missing the signal
- // if we're not ready to receive when the signal is sent.
- c := make(chan os.Signal, 1)
- signal.Notify(c, os.Interrupt, os.Kill)
-
- // Block until a signal is received.
- s := <-c
- fmt.Println("Got signal:", s)
-}
diff --git a/src/pkg/os/signal/sig.s b/src/pkg/os/signal/sig.s
deleted file mode 100644
index f860924aa..000000000
--- a/src/pkg/os/signal/sig.s
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012 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.
-
-// Assembly to get into package runtime without using exported symbols.
-
-// +build amd64 amd64p32 arm 386
-
-#include "../../../cmd/ld/textflag.h"
-
-#ifdef GOARCH_arm
-#define JMP B
-#endif
-
-TEXT ·signal_disable(SB),NOSPLIT,$0
- JMP runtime·signal_disable(SB)
-
-TEXT ·signal_enable(SB),NOSPLIT,$0
- JMP runtime·signal_enable(SB)
-
-TEXT ·signal_recv(SB),NOSPLIT,$0
- JMP runtime·signal_recv(SB)
-
diff --git a/src/pkg/os/signal/signal.go b/src/pkg/os/signal/signal.go
deleted file mode 100644
index 300427549..000000000
--- a/src/pkg/os/signal/signal.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2012 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.
-
-// Package signal implements access to incoming signals.
-package signal
-
-// BUG(rsc): This package is not yet implemented on Plan 9.
-
-import (
- "os"
- "sync"
-)
-
-var handlers struct {
- sync.Mutex
- m map[chan<- os.Signal]*handler
- ref [numSig]int64
-}
-
-type handler struct {
- mask [(numSig + 31) / 32]uint32
-}
-
-func (h *handler) want(sig int) bool {
- return (h.mask[sig/32]>>uint(sig&31))&1 != 0
-}
-
-func (h *handler) set(sig int) {
- h.mask[sig/32] |= 1 << uint(sig&31)
-}
-
-// Notify causes package signal to relay incoming signals to c.
-// If no signals are listed, all incoming signals will be relayed to c.
-// Otherwise, just the listed signals will.
-//
-// Package signal will not block sending to c: the caller must ensure
-// that c has sufficient buffer space to keep up with the expected
-// signal rate. For a channel used for notification of just one signal value,
-// a buffer of size 1 is sufficient.
-//
-// It is allowed to call Notify multiple times with the same channel:
-// each call expands the set of signals sent to that channel.
-// The only way to remove signals from the set is to call Stop.
-//
-// It is allowed to call Notify multiple times with different channels
-// and the same signals: each channel receives copies of incoming
-// signals independently.
-func Notify(c chan<- os.Signal, sig ...os.Signal) {
- if c == nil {
- panic("os/signal: Notify using nil channel")
- }
-
- handlers.Lock()
- defer handlers.Unlock()
-
- h := handlers.m[c]
- if h == nil {
- if handlers.m == nil {
- handlers.m = make(map[chan<- os.Signal]*handler)
- }
- h = new(handler)
- handlers.m[c] = h
- }
-
- add := func(n int) {
- if n < 0 {
- return
- }
- if !h.want(n) {
- h.set(n)
- if handlers.ref[n] == 0 {
- enableSignal(n)
- }
- handlers.ref[n]++
- }
- }
-
- if len(sig) == 0 {
- for n := 0; n < numSig; n++ {
- add(n)
- }
- } else {
- for _, s := range sig {
- add(signum(s))
- }
- }
-}
-
-// Stop causes package signal to stop relaying incoming signals to c.
-// It undoes the effect of all prior calls to Notify using c.
-// When Stop returns, it is guaranteed that c will receive no more signals.
-func Stop(c chan<- os.Signal) {
- handlers.Lock()
- defer handlers.Unlock()
-
- h := handlers.m[c]
- if h == nil {
- return
- }
- delete(handlers.m, c)
-
- for n := 0; n < numSig; n++ {
- if h.want(n) {
- handlers.ref[n]--
- if handlers.ref[n] == 0 {
- disableSignal(n)
- }
- }
- }
-}
-
-func process(sig os.Signal) {
- n := signum(sig)
- if n < 0 {
- return
- }
-
- handlers.Lock()
- defer handlers.Unlock()
-
- for c, h := range handlers.m {
- if h.want(n) {
- // send but do not block for it
- select {
- case c <- sig:
- default:
- }
- }
- }
-}
diff --git a/src/pkg/os/signal/signal_stub.go b/src/pkg/os/signal/signal_stub.go
deleted file mode 100644
index d0a6935ff..000000000
--- a/src/pkg/os/signal/signal_stub.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2012 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.
-
-// +build plan9
-
-package signal
-
-import "os"
-
-const numSig = 0
-
-func signum(sig os.Signal) int { return -1 }
-
-func disableSignal(int) {}
-
-func enableSignal(int) {}
diff --git a/src/pkg/os/signal/signal_test.go b/src/pkg/os/signal/signal_test.go
deleted file mode 100644
index 076fe3f93..000000000
--- a/src/pkg/os/signal/signal_test.go
+++ /dev/null
@@ -1,208 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package signal
-
-import (
- "flag"
- "io/ioutil"
- "os"
- "os/exec"
- "runtime"
- "strconv"
- "syscall"
- "testing"
- "time"
-)
-
-func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
- select {
- case s := <-c:
- if s != sig {
- t.Fatalf("signal was %v, want %v", s, sig)
- }
- case <-time.After(1 * time.Second):
- t.Fatalf("timeout waiting for %v", sig)
- }
-}
-
-// Test that basic signal handling works.
-func TestSignal(t *testing.T) {
- // Ask for SIGHUP
- c := make(chan os.Signal, 1)
- Notify(c, syscall.SIGHUP)
- defer Stop(c)
-
- // Send this process a SIGHUP
- t.Logf("sighup...")
- syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
- waitSig(t, c, syscall.SIGHUP)
-
- // Ask for everything we can get.
- c1 := make(chan os.Signal, 1)
- Notify(c1)
-
- // Send this process a SIGWINCH
- t.Logf("sigwinch...")
- syscall.Kill(syscall.Getpid(), syscall.SIGWINCH)
- waitSig(t, c1, syscall.SIGWINCH)
-
- // Send two more SIGHUPs, to make sure that
- // they get delivered on c1 and that not reading
- // from c does not block everything.
- t.Logf("sighup...")
- syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
- waitSig(t, c1, syscall.SIGHUP)
- t.Logf("sighup...")
- syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
- waitSig(t, c1, syscall.SIGHUP)
-
- // The first SIGHUP should be waiting for us on c.
- waitSig(t, c, syscall.SIGHUP)
-}
-
-func TestStress(t *testing.T) {
- dur := 3 * time.Second
- if testing.Short() {
- dur = 100 * time.Millisecond
- }
- defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
- done := make(chan bool)
- finished := make(chan bool)
- go func() {
- sig := make(chan os.Signal, 1)
- Notify(sig, syscall.SIGUSR1)
- defer Stop(sig)
- Loop:
- for {
- select {
- case <-sig:
- case <-done:
- break Loop
- }
- }
- finished <- true
- }()
- go func() {
- Loop:
- for {
- select {
- case <-done:
- break Loop
- default:
- syscall.Kill(syscall.Getpid(), syscall.SIGUSR1)
- runtime.Gosched()
- }
- }
- finished <- true
- }()
- time.Sleep(dur)
- close(done)
- <-finished
- <-finished
- // When run with 'go test -cpu=1,2,4' SIGUSR1 from this test can slip
- // into subsequent TestSignal() causing failure.
- // Sleep for a while to reduce the possibility of the failure.
- time.Sleep(10 * time.Millisecond)
-}
-
-var sendUncaughtSighup = flag.Int("send_uncaught_sighup", 0, "send uncaught SIGHUP during TestStop")
-
-// Test that Stop cancels the channel's registrations.
-func TestStop(t *testing.T) {
- sigs := []syscall.Signal{
- syscall.SIGWINCH,
- syscall.SIGHUP,
- }
-
- for _, sig := range sigs {
- // Send the signal.
- // If it's SIGWINCH, we should not see it.
- // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do.
- if sig != syscall.SIGHUP || *sendUncaughtSighup == 1 {
- syscall.Kill(syscall.Getpid(), sig)
- }
- time.Sleep(10 * time.Millisecond)
-
- // Ask for signal
- c := make(chan os.Signal, 1)
- Notify(c, sig)
- defer Stop(c)
-
- // Send this process that signal
- syscall.Kill(syscall.Getpid(), sig)
- waitSig(t, c, sig)
-
- Stop(c)
- select {
- case s := <-c:
- t.Fatalf("unexpected signal %v", s)
- case <-time.After(10 * time.Millisecond):
- // nothing to read - good
- }
-
- // Send the signal.
- // If it's SIGWINCH, we should not see it.
- // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do.
- if sig != syscall.SIGHUP || *sendUncaughtSighup == 2 {
- syscall.Kill(syscall.Getpid(), sig)
- }
-
- select {
- case s := <-c:
- t.Fatalf("unexpected signal %v", s)
- case <-time.After(10 * time.Millisecond):
- // nothing to read - good
- }
- }
-}
-
-// Test that when run under nohup, an uncaught SIGHUP does not kill the program,
-// but a
-func TestNohup(t *testing.T) {
- // Ugly: ask for SIGHUP so that child will not have no-hup set
- // even if test is running under nohup environment.
- // We have no intention of reading from c.
- c := make(chan os.Signal, 1)
- Notify(c, syscall.SIGHUP)
-
- // When run without nohup, the test should crash on an uncaught SIGHUP.
- // When run under nohup, the test should ignore uncaught SIGHUPs,
- // because the runtime is not supposed to be listening for them.
- // Either way, TestStop should still be able to catch them when it wants them
- // and then when it stops wanting them, the original behavior should resume.
- //
- // send_uncaught_sighup=1 sends the SIGHUP before starting to listen for SIGHUPs.
- // send_uncaught_sighup=2 sends the SIGHUP after no longer listening for SIGHUPs.
- //
- // Both should fail without nohup and succeed with nohup.
-
- for i := 1; i <= 2; i++ {
- out, err := exec.Command(os.Args[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv.Itoa(i)).CombinedOutput()
- if err == nil {
- t.Fatalf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i, out)
- }
- }
-
- Stop(c)
-
- // Again, this time with nohup, assuming we can find it.
- _, err := os.Stat("/usr/bin/nohup")
- if err != nil {
- t.Skip("cannot find nohup; skipping second half of test")
- }
-
- for i := 1; i <= 2; i++ {
- os.Remove("nohup.out")
- out, err := exec.Command("/usr/bin/nohup", os.Args[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv.Itoa(i)).CombinedOutput()
-
- data, _ := ioutil.ReadFile("nohup.out")
- os.Remove("nohup.out")
- if err != nil {
- t.Fatalf("ran test with -send_uncaught_sighup=%d under nohup and it failed: expected success.\nError: %v\nOutput:\n%s%s", i, err, out, data)
- }
- }
-}
diff --git a/src/pkg/os/signal/signal_unix.go b/src/pkg/os/signal/signal_unix.go
deleted file mode 100644
index 94b8ab3dd..000000000
--- a/src/pkg/os/signal/signal_unix.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2012 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.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package signal
-
-import (
- "os"
- "syscall"
-)
-
-// In assembly.
-func signal_disable(uint32)
-func signal_enable(uint32)
-func signal_recv() uint32
-
-func loop() {
- for {
- process(syscall.Signal(signal_recv()))
- }
-}
-
-func init() {
- signal_enable(0) // first call - initialize
- go loop()
-}
-
-const (
- numSig = 65 // max across all systems
-)
-
-func signum(sig os.Signal) int {
- switch sig := sig.(type) {
- case syscall.Signal:
- i := int(sig)
- if i < 0 || i >= numSig {
- return -1
- }
- return i
- default:
- return -1
- }
-}
-
-func enableSignal(sig int) {
- signal_enable(uint32(sig))
-}
-
-func disableSignal(sig int) {
- signal_disable(uint32(sig))
-}
diff --git a/src/pkg/os/signal/signal_windows_test.go b/src/pkg/os/signal/signal_windows_test.go
deleted file mode 100644
index f3e6706b7..000000000
--- a/src/pkg/os/signal/signal_windows_test.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2012 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.
-
-package signal
-
-import (
- "bytes"
- "io/ioutil"
- "os"
- "os/exec"
- "path/filepath"
- "syscall"
- "testing"
- "time"
-)
-
-func sendCtrlBreak(t *testing.T, pid int) {
- d, e := syscall.LoadDLL("kernel32.dll")
- if e != nil {
- t.Fatalf("LoadDLL: %v\n", e)
- }
- p, e := d.FindProc("GenerateConsoleCtrlEvent")
- if e != nil {
- t.Fatalf("FindProc: %v\n", e)
- }
- r, _, e := p.Call(syscall.CTRL_BREAK_EVENT, uintptr(pid))
- if r == 0 {
- t.Fatalf("GenerateConsoleCtrlEvent: %v\n", e)
- }
-}
-
-func TestCtrlBreak(t *testing.T) {
- // create source file
- const source = `
-package main
-
-import (
- "log"
- "os"
- "os/signal"
- "time"
-)
-
-
-func main() {
- c := make(chan os.Signal, 10)
- signal.Notify(c)
- select {
- case s := <-c:
- if s != os.Interrupt {
- log.Fatalf("Wrong signal received: got %q, want %q\n", s, os.Interrupt)
- }
- case <-time.After(3 * time.Second):
- log.Fatalf("Timeout waiting for Ctrl+Break\n")
- }
-}
-`
- tmp, err := ioutil.TempDir("", "TestCtrlBreak")
- if err != nil {
- t.Fatal("TempDir failed: ", err)
- }
- defer os.RemoveAll(tmp)
-
- // write ctrlbreak.go
- name := filepath.Join(tmp, "ctlbreak")
- src := name + ".go"
- f, err := os.Create(src)
- if err != nil {
- t.Fatalf("Failed to create %v: %v", src, err)
- }
- defer f.Close()
- f.Write([]byte(source))
-
- // compile it
- exe := name + ".exe"
- defer os.Remove(exe)
- o, err := exec.Command("go", "build", "-o", exe, src).CombinedOutput()
- if err != nil {
- t.Fatalf("Failed to compile: %v\n%v", err, string(o))
- }
-
- // run it
- cmd := exec.Command(exe)
- var b bytes.Buffer
- cmd.Stdout = &b
- cmd.Stderr = &b
- cmd.SysProcAttr = &syscall.SysProcAttr{
- CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
- }
- err = cmd.Start()
- if err != nil {
- t.Fatalf("Start failed: %v", err)
- }
- go func() {
- time.Sleep(1 * time.Second)
- sendCtrlBreak(t, cmd.Process.Pid)
- }()
- err = cmd.Wait()
- if err != nil {
- t.Fatalf("Program exited with error: %v\n%v", err, string(b.Bytes()))
- }
-}
diff --git a/src/pkg/os/stat_darwin.go b/src/pkg/os/stat_darwin.go
deleted file mode 100644
index 0eea52201..000000000
--- a/src/pkg/os/stat_darwin.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- stat1 := fs1.sys.(*syscall.Stat_t)
- stat2 := fs2.sys.(*syscall.Stat_t)
- return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino
-}
-
-func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
- fs := &fileStat{
- name: basename(name),
- size: int64(st.Size),
- modTime: timespecToTime(st.Mtimespec),
- sys: st,
- }
- fs.mode = FileMode(st.Mode & 0777)
- switch st.Mode & syscall.S_IFMT {
- case syscall.S_IFBLK, syscall.S_IFWHT:
- fs.mode |= ModeDevice
- case syscall.S_IFCHR:
- fs.mode |= ModeDevice | ModeCharDevice
- case syscall.S_IFDIR:
- fs.mode |= ModeDir
- case syscall.S_IFIFO:
- fs.mode |= ModeNamedPipe
- case syscall.S_IFLNK:
- fs.mode |= ModeSymlink
- case syscall.S_IFREG:
- // nothing to do
- case syscall.S_IFSOCK:
- fs.mode |= ModeSocket
- }
- if st.Mode&syscall.S_ISGID != 0 {
- fs.mode |= ModeSetgid
- }
- if st.Mode&syscall.S_ISUID != 0 {
- fs.mode |= ModeSetuid
- }
- if st.Mode&syscall.S_ISVTX != 0 {
- fs.mode |= ModeSticky
- }
- return fs
-}
-
-func timespecToTime(ts syscall.Timespec) time.Time {
- return time.Unix(int64(ts.Sec), int64(ts.Nsec))
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return timespecToTime(fi.Sys().(*syscall.Stat_t).Atimespec)
-}
diff --git a/src/pkg/os/stat_dragonfly.go b/src/pkg/os/stat_dragonfly.go
deleted file mode 100644
index 605c1d9b6..000000000
--- a/src/pkg/os/stat_dragonfly.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- stat1 := fs1.sys.(*syscall.Stat_t)
- stat2 := fs2.sys.(*syscall.Stat_t)
- return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino
-}
-
-func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
- fs := &fileStat{
- name: basename(name),
- size: int64(st.Size),
- modTime: timespecToTime(st.Mtim),
- sys: st,
- }
- fs.mode = FileMode(st.Mode & 0777)
- switch st.Mode & syscall.S_IFMT {
- case syscall.S_IFBLK:
- fs.mode |= ModeDevice
- case syscall.S_IFCHR:
- fs.mode |= ModeDevice | ModeCharDevice
- case syscall.S_IFDIR:
- fs.mode |= ModeDir
- case syscall.S_IFIFO:
- fs.mode |= ModeNamedPipe
- case syscall.S_IFLNK:
- fs.mode |= ModeSymlink
- case syscall.S_IFREG:
- // nothing to do
- case syscall.S_IFSOCK:
- fs.mode |= ModeSocket
- }
- if st.Mode&syscall.S_ISGID != 0 {
- fs.mode |= ModeSetgid
- }
- if st.Mode&syscall.S_ISUID != 0 {
- fs.mode |= ModeSetuid
- }
- if st.Mode&syscall.S_ISVTX != 0 {
- fs.mode |= ModeSticky
- }
- return fs
-}
-
-func timespecToTime(ts syscall.Timespec) time.Time {
- return time.Unix(int64(ts.Sec), int64(ts.Nsec))
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return timespecToTime(fi.Sys().(*syscall.Stat_t).Atim)
-}
diff --git a/src/pkg/os/stat_freebsd.go b/src/pkg/os/stat_freebsd.go
deleted file mode 100644
index 2ffb60fe2..000000000
--- a/src/pkg/os/stat_freebsd.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- stat1 := fs1.sys.(*syscall.Stat_t)
- stat2 := fs2.sys.(*syscall.Stat_t)
- return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino
-}
-
-func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
- fs := &fileStat{
- name: basename(name),
- size: int64(st.Size),
- modTime: timespecToTime(st.Mtimespec),
- sys: st,
- }
- fs.mode = FileMode(st.Mode & 0777)
- switch st.Mode & syscall.S_IFMT {
- case syscall.S_IFBLK:
- fs.mode |= ModeDevice
- case syscall.S_IFCHR:
- fs.mode |= ModeDevice | ModeCharDevice
- case syscall.S_IFDIR:
- fs.mode |= ModeDir
- case syscall.S_IFIFO:
- fs.mode |= ModeNamedPipe
- case syscall.S_IFLNK:
- fs.mode |= ModeSymlink
- case syscall.S_IFREG:
- // nothing to do
- case syscall.S_IFSOCK:
- fs.mode |= ModeSocket
- }
- if st.Mode&syscall.S_ISGID != 0 {
- fs.mode |= ModeSetgid
- }
- if st.Mode&syscall.S_ISUID != 0 {
- fs.mode |= ModeSetuid
- }
- if st.Mode&syscall.S_ISVTX != 0 {
- fs.mode |= ModeSticky
- }
- return fs
-}
-
-func timespecToTime(ts syscall.Timespec) time.Time {
- return time.Unix(int64(ts.Sec), int64(ts.Nsec))
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return timespecToTime(fi.Sys().(*syscall.Stat_t).Atimespec)
-}
diff --git a/src/pkg/os/stat_linux.go b/src/pkg/os/stat_linux.go
deleted file mode 100644
index 605c1d9b6..000000000
--- a/src/pkg/os/stat_linux.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- stat1 := fs1.sys.(*syscall.Stat_t)
- stat2 := fs2.sys.(*syscall.Stat_t)
- return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino
-}
-
-func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
- fs := &fileStat{
- name: basename(name),
- size: int64(st.Size),
- modTime: timespecToTime(st.Mtim),
- sys: st,
- }
- fs.mode = FileMode(st.Mode & 0777)
- switch st.Mode & syscall.S_IFMT {
- case syscall.S_IFBLK:
- fs.mode |= ModeDevice
- case syscall.S_IFCHR:
- fs.mode |= ModeDevice | ModeCharDevice
- case syscall.S_IFDIR:
- fs.mode |= ModeDir
- case syscall.S_IFIFO:
- fs.mode |= ModeNamedPipe
- case syscall.S_IFLNK:
- fs.mode |= ModeSymlink
- case syscall.S_IFREG:
- // nothing to do
- case syscall.S_IFSOCK:
- fs.mode |= ModeSocket
- }
- if st.Mode&syscall.S_ISGID != 0 {
- fs.mode |= ModeSetgid
- }
- if st.Mode&syscall.S_ISUID != 0 {
- fs.mode |= ModeSetuid
- }
- if st.Mode&syscall.S_ISVTX != 0 {
- fs.mode |= ModeSticky
- }
- return fs
-}
-
-func timespecToTime(ts syscall.Timespec) time.Time {
- return time.Unix(int64(ts.Sec), int64(ts.Nsec))
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return timespecToTime(fi.Sys().(*syscall.Stat_t).Atim)
-}
diff --git a/src/pkg/os/stat_nacl.go b/src/pkg/os/stat_nacl.go
deleted file mode 100644
index a503b59fa..000000000
--- a/src/pkg/os/stat_nacl.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- stat1 := fs1.sys.(*syscall.Stat_t)
- stat2 := fs2.sys.(*syscall.Stat_t)
- return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino
-}
-
-func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
- fs := &fileStat{
- name: basename(name),
- size: int64(st.Size),
- modTime: timespecToTime(st.Mtime, st.MtimeNsec),
- sys: st,
- }
- fs.mode = FileMode(st.Mode & 0777)
- switch st.Mode & syscall.S_IFMT {
- case syscall.S_IFBLK:
- fs.mode |= ModeDevice
- case syscall.S_IFCHR:
- fs.mode |= ModeDevice | ModeCharDevice
- case syscall.S_IFDIR:
- fs.mode |= ModeDir
- case syscall.S_IFIFO:
- fs.mode |= ModeNamedPipe
- case syscall.S_IFLNK:
- fs.mode |= ModeSymlink
- case syscall.S_IFREG:
- // nothing to do
- case syscall.S_IFSOCK:
- fs.mode |= ModeSocket
- }
- if st.Mode&syscall.S_ISGID != 0 {
- fs.mode |= ModeSetgid
- }
- if st.Mode&syscall.S_ISUID != 0 {
- fs.mode |= ModeSetuid
- }
- if st.Mode&syscall.S_ISVTX != 0 {
- fs.mode |= ModeSticky
- }
- return fs
-}
-
-func timespecToTime(sec, nsec int64) time.Time {
- return time.Unix(sec, nsec)
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- st := fi.Sys().(*syscall.Stat_t)
- return timespecToTime(st.Atime, st.AtimeNsec)
-}
diff --git a/src/pkg/os/stat_netbsd.go b/src/pkg/os/stat_netbsd.go
deleted file mode 100644
index 2ffb60fe2..000000000
--- a/src/pkg/os/stat_netbsd.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- stat1 := fs1.sys.(*syscall.Stat_t)
- stat2 := fs2.sys.(*syscall.Stat_t)
- return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino
-}
-
-func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
- fs := &fileStat{
- name: basename(name),
- size: int64(st.Size),
- modTime: timespecToTime(st.Mtimespec),
- sys: st,
- }
- fs.mode = FileMode(st.Mode & 0777)
- switch st.Mode & syscall.S_IFMT {
- case syscall.S_IFBLK:
- fs.mode |= ModeDevice
- case syscall.S_IFCHR:
- fs.mode |= ModeDevice | ModeCharDevice
- case syscall.S_IFDIR:
- fs.mode |= ModeDir
- case syscall.S_IFIFO:
- fs.mode |= ModeNamedPipe
- case syscall.S_IFLNK:
- fs.mode |= ModeSymlink
- case syscall.S_IFREG:
- // nothing to do
- case syscall.S_IFSOCK:
- fs.mode |= ModeSocket
- }
- if st.Mode&syscall.S_ISGID != 0 {
- fs.mode |= ModeSetgid
- }
- if st.Mode&syscall.S_ISUID != 0 {
- fs.mode |= ModeSetuid
- }
- if st.Mode&syscall.S_ISVTX != 0 {
- fs.mode |= ModeSticky
- }
- return fs
-}
-
-func timespecToTime(ts syscall.Timespec) time.Time {
- return time.Unix(int64(ts.Sec), int64(ts.Nsec))
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return timespecToTime(fi.Sys().(*syscall.Stat_t).Atimespec)
-}
diff --git a/src/pkg/os/stat_openbsd.go b/src/pkg/os/stat_openbsd.go
deleted file mode 100644
index 605c1d9b6..000000000
--- a/src/pkg/os/stat_openbsd.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- stat1 := fs1.sys.(*syscall.Stat_t)
- stat2 := fs2.sys.(*syscall.Stat_t)
- return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino
-}
-
-func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
- fs := &fileStat{
- name: basename(name),
- size: int64(st.Size),
- modTime: timespecToTime(st.Mtim),
- sys: st,
- }
- fs.mode = FileMode(st.Mode & 0777)
- switch st.Mode & syscall.S_IFMT {
- case syscall.S_IFBLK:
- fs.mode |= ModeDevice
- case syscall.S_IFCHR:
- fs.mode |= ModeDevice | ModeCharDevice
- case syscall.S_IFDIR:
- fs.mode |= ModeDir
- case syscall.S_IFIFO:
- fs.mode |= ModeNamedPipe
- case syscall.S_IFLNK:
- fs.mode |= ModeSymlink
- case syscall.S_IFREG:
- // nothing to do
- case syscall.S_IFSOCK:
- fs.mode |= ModeSocket
- }
- if st.Mode&syscall.S_ISGID != 0 {
- fs.mode |= ModeSetgid
- }
- if st.Mode&syscall.S_ISUID != 0 {
- fs.mode |= ModeSetuid
- }
- if st.Mode&syscall.S_ISVTX != 0 {
- fs.mode |= ModeSticky
- }
- return fs
-}
-
-func timespecToTime(ts syscall.Timespec) time.Time {
- return time.Unix(int64(ts.Sec), int64(ts.Nsec))
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return timespecToTime(fi.Sys().(*syscall.Stat_t).Atim)
-}
diff --git a/src/pkg/os/stat_plan9.go b/src/pkg/os/stat_plan9.go
deleted file mode 100644
index 25c9a8c14..000000000
--- a/src/pkg/os/stat_plan9.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2011 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- a := fs1.sys.(*syscall.Dir)
- b := fs2.sys.(*syscall.Dir)
- return a.Qid.Path == b.Qid.Path && a.Type == b.Type && a.Dev == b.Dev
-}
-
-func fileInfoFromStat(d *syscall.Dir) FileInfo {
- fs := &fileStat{
- name: d.Name,
- size: int64(d.Length),
- modTime: time.Unix(int64(d.Mtime), 0),
- sys: d,
- }
- fs.mode = FileMode(d.Mode & 0777)
- if d.Mode&syscall.DMDIR != 0 {
- fs.mode |= ModeDir
- }
- if d.Mode&syscall.DMAPPEND != 0 {
- fs.mode |= ModeAppend
- }
- if d.Mode&syscall.DMEXCL != 0 {
- fs.mode |= ModeExclusive
- }
- if d.Mode&syscall.DMTMP != 0 {
- fs.mode |= ModeTemporary
- }
- return fs
-}
-
-// arg is an open *File or a path string.
-func dirstat(arg interface{}) (*syscall.Dir, error) {
- var name string
-
- // This is big enough for most stat messages
- // and rounded to a multiple of 128 bytes.
- size := (syscall.STATFIXLEN + 16*4 + 128) &^ 128
-
- for i := 0; i < 2; i++ {
- buf := make([]byte, size)
-
- var n int
- var err error
- switch a := arg.(type) {
- case *File:
- name = a.name
- n, err = syscall.Fstat(a.fd, buf)
- case string:
- name = a
- n, err = syscall.Stat(a, buf)
- default:
- panic("phase error in dirstat")
- }
- if err != nil {
- return nil, &PathError{"stat", name, err}
- }
- if n < syscall.STATFIXLEN {
- return nil, &PathError{"stat", name, syscall.ErrShortStat}
- }
-
- // Pull the real size out of the stat message.
- size = int(uint16(buf[0]) | uint16(buf[1])<<8)
-
- // If the stat message is larger than our buffer we will
- // go around the loop and allocate one that is big enough.
- if size > n {
- continue
- }
-
- d, err := syscall.UnmarshalDir(buf[:n])
- if err != nil {
- return nil, &PathError{"stat", name, err}
- }
- return d, nil
- }
- return nil, &PathError{"stat", name, syscall.ErrBadStat}
-}
-
-// Stat returns a FileInfo describing the named file.
-// If there is an error, it will be of type *PathError.
-func Stat(name string) (fi FileInfo, err error) {
- d, err := dirstat(name)
- if err != nil {
- return nil, err
- }
- return fileInfoFromStat(d), nil
-}
-
-// Lstat returns a FileInfo describing the named file.
-// If the file is a symbolic link, the returned FileInfo
-// describes the symbolic link. Lstat makes no attempt to follow the link.
-// If there is an error, it will be of type *PathError.
-func Lstat(name string) (fi FileInfo, err error) {
- return Stat(name)
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return time.Unix(int64(fi.Sys().(*syscall.Dir).Atime), 0)
-}
diff --git a/src/pkg/os/stat_solaris.go b/src/pkg/os/stat_solaris.go
deleted file mode 100644
index 605c1d9b6..000000000
--- a/src/pkg/os/stat_solaris.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-func sameFile(fs1, fs2 *fileStat) bool {
- stat1 := fs1.sys.(*syscall.Stat_t)
- stat2 := fs2.sys.(*syscall.Stat_t)
- return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino
-}
-
-func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
- fs := &fileStat{
- name: basename(name),
- size: int64(st.Size),
- modTime: timespecToTime(st.Mtim),
- sys: st,
- }
- fs.mode = FileMode(st.Mode & 0777)
- switch st.Mode & syscall.S_IFMT {
- case syscall.S_IFBLK:
- fs.mode |= ModeDevice
- case syscall.S_IFCHR:
- fs.mode |= ModeDevice | ModeCharDevice
- case syscall.S_IFDIR:
- fs.mode |= ModeDir
- case syscall.S_IFIFO:
- fs.mode |= ModeNamedPipe
- case syscall.S_IFLNK:
- fs.mode |= ModeSymlink
- case syscall.S_IFREG:
- // nothing to do
- case syscall.S_IFSOCK:
- fs.mode |= ModeSocket
- }
- if st.Mode&syscall.S_ISGID != 0 {
- fs.mode |= ModeSetgid
- }
- if st.Mode&syscall.S_ISUID != 0 {
- fs.mode |= ModeSetuid
- }
- if st.Mode&syscall.S_ISVTX != 0 {
- fs.mode |= ModeSticky
- }
- return fs
-}
-
-func timespecToTime(ts syscall.Timespec) time.Time {
- return time.Unix(int64(ts.Sec), int64(ts.Nsec))
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return timespecToTime(fi.Sys().(*syscall.Stat_t).Atim)
-}
diff --git a/src/pkg/os/stat_windows.go b/src/pkg/os/stat_windows.go
deleted file mode 100644
index 6dc386685..000000000
--- a/src/pkg/os/stat_windows.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "unsafe"
-)
-
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (file *File) Stat() (fi FileInfo, err error) {
- if file == nil {
- return nil, ErrInvalid
- }
- if file == nil || file.fd < 0 {
- return nil, syscall.EINVAL
- }
- if file.isdir() {
- // I don't know any better way to do that for directory
- return Stat(file.name)
- }
- if file.name == DevNull {
- return &devNullStat, nil
- }
- var d syscall.ByHandleFileInformation
- e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
- if e != nil {
- return nil, &PathError{"GetFileInformationByHandle", file.name, e}
- }
- return &fileStat{
- name: basename(file.name),
- sys: syscall.Win32FileAttributeData{
- FileAttributes: d.FileAttributes,
- CreationTime: d.CreationTime,
- LastAccessTime: d.LastAccessTime,
- LastWriteTime: d.LastWriteTime,
- FileSizeHigh: d.FileSizeHigh,
- FileSizeLow: d.FileSizeLow,
- },
- vol: d.VolumeSerialNumber,
- idxhi: d.FileIndexHigh,
- idxlo: d.FileIndexLow,
- }, nil
-}
-
-// Stat returns a FileInfo structure describing the named file.
-// If there is an error, it will be of type *PathError.
-func Stat(name string) (fi FileInfo, err error) {
- if len(name) == 0 {
- return nil, &PathError{"Stat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
- }
- if name == DevNull {
- return &devNullStat, nil
- }
- fs := &fileStat{name: basename(name)}
- namep, e := syscall.UTF16PtrFromString(name)
- if e != nil {
- return nil, &PathError{"Stat", name, e}
- }
- e = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fs.sys)))
- if e != nil {
- return nil, &PathError{"GetFileAttributesEx", name, e}
- }
- fs.path = name
- if !isAbs(fs.path) {
- cwd, _ := Getwd()
- fs.path = cwd + `\` + fs.path
- }
- return fs, nil
-}
-
-// Lstat returns the FileInfo structure describing the named file.
-// If the file is a symbolic link, the returned FileInfo
-// describes the symbolic link. Lstat makes no attempt to follow the link.
-// If there is an error, it will be of type *PathError.
-func Lstat(name string) (fi FileInfo, err error) {
- // No links on Windows
- return Stat(name)
-}
-
-// basename removes trailing slashes and the leading
-// directory name and drive letter from path name.
-func basename(name string) string {
- // Remove drive letter
- if len(name) == 2 && name[1] == ':' {
- name = "."
- } else if len(name) > 2 && name[1] == ':' {
- name = name[2:]
- }
- i := len(name) - 1
- // Remove trailing slashes
- for ; i > 0 && (name[i] == '/' || name[i] == '\\'); i-- {
- name = name[:i]
- }
- // Remove leading directory name
- for i--; i >= 0; i-- {
- if name[i] == '/' || name[i] == '\\' {
- name = name[i+1:]
- break
- }
- }
- return name
-}
-
-func isSlash(c uint8) bool {
- return c == '\\' || c == '/'
-}
-
-func isAbs(path string) (b bool) {
- v := volumeName(path)
- if v == "" {
- return false
- }
- path = path[len(v):]
- if path == "" {
- return false
- }
- return isSlash(path[0])
-}
-
-func volumeName(path string) (v string) {
- if len(path) < 2 {
- return ""
- }
- // with drive letter
- c := path[0]
- if path[1] == ':' &&
- ('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
- 'A' <= c && c <= 'Z') {
- return path[:2]
- }
- // is it UNC
- if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
- !isSlash(path[2]) && path[2] != '.' {
- // first, leading `\\` and next shouldn't be `\`. its server name.
- for n := 3; n < l-1; n++ {
- // second, next '\' shouldn't be repeated.
- if isSlash(path[n]) {
- n++
- // third, following something characters. its share name.
- if !isSlash(path[n]) {
- if path[n] == '.' {
- break
- }
- for ; n < l; n++ {
- if isSlash(path[n]) {
- break
- }
- }
- return path[:n]
- }
- break
- }
- }
- }
- return ""
-}
diff --git a/src/pkg/os/str.go b/src/pkg/os/str.go
deleted file mode 100644
index e3606b61e..000000000
--- a/src/pkg/os/str.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-
-// +build plan9
-
-package os
-
-func itoa(val int) string { // do it here rather than with fmt to avoid dependency
- if val < 0 {
- return "-" + itoa(-val)
- }
- var buf [32]byte // big enough for int64
- i := len(buf) - 1
- for val >= 10 {
- buf[i] = byte(val%10 + '0')
- i--
- val /= 10
- }
- buf[i] = byte(val + '0')
- return string(buf[i:])
-}
diff --git a/src/pkg/os/sys_bsd.go b/src/pkg/os/sys_bsd.go
deleted file mode 100644
index 8ad5e2183..000000000
--- a/src/pkg/os/sys_bsd.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd nacl netbsd openbsd
-
-// os code shared between *BSD systems including OS X (Darwin)
-// and FreeBSD.
-
-package os
-
-import "syscall"
-
-func hostname() (name string, err error) {
- name, err = syscall.Sysctl("kern.hostname")
- if err != nil {
- return "", NewSyscallError("sysctl kern.hostname", err)
- }
- return name, nil
-}
diff --git a/src/pkg/os/sys_darwin.go b/src/pkg/os/sys_darwin.go
deleted file mode 100644
index 7a8330abb..000000000
--- a/src/pkg/os/sys_darwin.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 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.
-
-package os
-
-import "syscall"
-
-// supportsCloseOnExec reports whether the platform supports the
-// O_CLOEXEC flag.
-var supportsCloseOnExec bool
-
-func init() {
- // Seems like kern.osreldate is veiled on latest OS X. We use
- // kern.osrelease instead.
- osver, err := syscall.Sysctl("kern.osrelease")
- if err != nil {
- return
- }
- var i int
- for i = range osver {
- if osver[i] != '.' {
- continue
- }
- }
- // The O_CLOEXEC flag was introduced in OS X 10.7 (Darwin
- // 11.0.0). See http://support.apple.com/kb/HT1633.
- if i > 2 || i == 2 && osver[0] >= '1' && osver[1] >= '1' {
- supportsCloseOnExec = true
- }
-}
diff --git a/src/pkg/os/sys_freebsd.go b/src/pkg/os/sys_freebsd.go
deleted file mode 100644
index 273c2df1c..000000000
--- a/src/pkg/os/sys_freebsd.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 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.
-
-package os
-
-import "syscall"
-
-// supportsCloseOnExec reports whether the platform supports the
-// O_CLOEXEC flag.
-var supportsCloseOnExec bool
-
-func init() {
- osrel, err := syscall.SysctlUint32("kern.osreldate")
- if err != nil {
- return
- }
- // The O_CLOEXEC flag was introduced in FreeBSD 8.3.
- // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
- if osrel >= 803000 {
- supportsCloseOnExec = true
- }
-}
diff --git a/src/pkg/os/sys_linux.go b/src/pkg/os/sys_linux.go
deleted file mode 100644
index 76cdf5043..000000000
--- a/src/pkg/os/sys_linux.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.
-
-// Linux-specific
-
-package os
-
-func hostname() (name string, err error) {
- f, err := Open("/proc/sys/kernel/hostname")
- if err != nil {
- return "", err
- }
- defer f.Close()
-
- var buf [512]byte // Enough for a DNS name.
- n, err := f.Read(buf[0:])
- if err != nil {
- return "", err
- }
-
- if n > 0 && buf[n-1] == '\n' {
- n--
- }
- return string(buf[0:n]), nil
-}
diff --git a/src/pkg/os/sys_nacl.go b/src/pkg/os/sys_nacl.go
deleted file mode 100644
index 07907c847..000000000
--- a/src/pkg/os/sys_nacl.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2014 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.
-
-package os
-
-// supportsCloseOnExec reports whether the platform supports the
-// O_CLOEXEC flag.
-const supportsCloseOnExec = false
diff --git a/src/pkg/os/sys_plan9.go b/src/pkg/os/sys_plan9.go
deleted file mode 100644
index 07a7905f4..000000000
--- a/src/pkg/os/sys_plan9.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2011 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.
-
-// Plan 9-specific
-
-package os
-
-func hostname() (name string, err error) {
- f, err := Open("#c/sysname")
- if err != nil {
- return "", err
- }
- defer f.Close()
-
- var buf [128]byte
- n, err := f.Read(buf[:len(buf)-1])
-
- if err != nil {
- return "", err
- }
- if n > 0 {
- buf[n] = 0
- }
- return string(buf[0:n]), nil
-}
diff --git a/src/pkg/os/sys_solaris.go b/src/pkg/os/sys_solaris.go
deleted file mode 100644
index 917e8f2b0..000000000
--- a/src/pkg/os/sys_solaris.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2013 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.
-
-package os
-
-import "syscall"
-
-func hostname() (name string, err error) {
- return syscall.Gethostname()
-}
diff --git a/src/pkg/os/sys_unix.go b/src/pkg/os/sys_unix.go
deleted file mode 100644
index 39c20dc73..000000000
--- a/src/pkg/os/sys_unix.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 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.
-
-// +build dragonfly linux netbsd openbsd solaris
-
-package os
-
-// supportsCloseOnExec reports whether the platform supports the
-// O_CLOEXEC flag.
-const supportsCloseOnExec = true
diff --git a/src/pkg/os/sys_windows.go b/src/pkg/os/sys_windows.go
deleted file mode 100644
index 92617de5e..000000000
--- a/src/pkg/os/sys_windows.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-package os
-
-import "syscall"
-
-func hostname() (name string, err error) {
- s, e := syscall.ComputerName()
- if e != nil {
- return "", NewSyscallError("ComputerName", e)
- }
- return s, nil
-}
diff --git a/src/pkg/os/types.go b/src/pkg/os/types.go
deleted file mode 100644
index 473d431d4..000000000
--- a/src/pkg/os/types.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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.
-
-package os
-
-import (
- "syscall"
- "time"
-)
-
-// Getpagesize returns the underlying system's memory page size.
-func Getpagesize() int { return syscall.Getpagesize() }
-
-// A FileInfo describes a file and is returned by Stat and Lstat.
-type FileInfo interface {
- Name() string // base name of the file
- Size() int64 // length in bytes for regular files; system-dependent for others
- Mode() FileMode // file mode bits
- ModTime() time.Time // modification time
- IsDir() bool // abbreviation for Mode().IsDir()
- Sys() interface{} // underlying data source (can return nil)
-}
-
-// A FileMode represents a file's mode and permission bits.
-// The bits have the same definition on all systems, so that
-// information about files can be moved from one system
-// to another portably. Not all bits apply to all systems.
-// The only required bit is ModeDir for directories.
-type FileMode uint32
-
-// The defined file mode bits are the most significant bits of the FileMode.
-// The nine least-significant bits are the standard Unix rwxrwxrwx permissions.
-// The values of these bits should be considered part of the public API and
-// may be used in wire protocols or disk representations: they must not be
-// changed, although new bits might be added.
-const (
- // The single letters are the abbreviations
- // used by the String method's formatting.
- ModeDir FileMode = 1 << (32 - 1 - iota) // d: is a directory
- ModeAppend // a: append-only
- ModeExclusive // l: exclusive use
- ModeTemporary // T: temporary file (not backed up)
- ModeSymlink // L: symbolic link
- ModeDevice // D: device file
- ModeNamedPipe // p: named pipe (FIFO)
- ModeSocket // S: Unix domain socket
- ModeSetuid // u: setuid
- ModeSetgid // g: setgid
- ModeCharDevice // c: Unix character device, when ModeDevice is set
- ModeSticky // t: sticky
-
- // Mask for the type bits. For regular files, none will be set.
- ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice
-
- ModePerm FileMode = 0777 // permission bits
-)
-
-func (m FileMode) String() string {
- const str = "dalTLDpSugct"
- var buf [32]byte // Mode is uint32.
- w := 0
- for i, c := range str {
- if m&(1<<uint(32-1-i)) != 0 {
- buf[w] = byte(c)
- w++
- }
- }
- if w == 0 {
- buf[w] = '-'
- w++
- }
- const rwx = "rwxrwxrwx"
- for i, c := range rwx {
- if m&(1<<uint(9-1-i)) != 0 {
- buf[w] = byte(c)
- } else {
- buf[w] = '-'
- }
- w++
- }
- return string(buf[:w])
-}
-
-// IsDir reports whether m describes a directory.
-// That is, it tests for the ModeDir bit being set in m.
-func (m FileMode) IsDir() bool {
- return m&ModeDir != 0
-}
-
-// IsRegular reports whether m describes a regular file.
-// That is, it tests that no mode type bits are set.
-func (m FileMode) IsRegular() bool {
- return m&ModeType == 0
-}
-
-// Perm returns the Unix permission bits in m.
-func (m FileMode) Perm() FileMode {
- return m & ModePerm
-}
-
-func (fs *fileStat) Name() string { return fs.name }
-func (fs *fileStat) IsDir() bool { return fs.Mode().IsDir() }
-
-// SameFile reports whether fi1 and fi2 describe the same file.
-// For example, on Unix this means that the device and inode fields
-// of the two underlying structures are identical; on other systems
-// the decision may be based on the path names.
-// SameFile only applies to results returned by this package's Stat.
-// It returns false in other cases.
-func SameFile(fi1, fi2 FileInfo) bool {
- fs1, ok1 := fi1.(*fileStat)
- fs2, ok2 := fi2.(*fileStat)
- if !ok1 || !ok2 {
- return false
- }
- return sameFile(fs1, fs2)
-}
diff --git a/src/pkg/os/types_notwin.go b/src/pkg/os/types_notwin.go
deleted file mode 100644
index ea1a07393..000000000
--- a/src/pkg/os/types_notwin.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-// +build !windows
-
-package os
-
-import (
- "time"
-)
-
-// A fileStat is the implementation of FileInfo returned by Stat and Lstat.
-type fileStat struct {
- name string
- size int64
- mode FileMode
- modTime time.Time
- sys interface{}
-}
-
-func (fs *fileStat) Size() int64 { return fs.size }
-func (fs *fileStat) Mode() FileMode { return fs.mode }
-func (fs *fileStat) ModTime() time.Time { return fs.modTime }
-func (fs *fileStat) Sys() interface{} { return fs.sys }
diff --git a/src/pkg/os/types_windows.go b/src/pkg/os/types_windows.go
deleted file mode 100644
index 38901681e..000000000
--- a/src/pkg/os/types_windows.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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.
-
-package os
-
-import (
- "sync"
- "syscall"
- "time"
-)
-
-// A fileStat is the implementation of FileInfo returned by Stat and Lstat.
-type fileStat struct {
- name string
- sys syscall.Win32FileAttributeData
-
- // used to implement SameFile
- sync.Mutex
- path string
- vol uint32
- idxhi uint32
- idxlo uint32
-}
-
-func (fs *fileStat) Size() int64 {
- return int64(fs.sys.FileSizeHigh)<<32 + int64(fs.sys.FileSizeLow)
-}
-
-func (fs *fileStat) Mode() (m FileMode) {
- if fs == &devNullStat {
- return ModeDevice | ModeCharDevice | 0666
- }
- if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- m |= ModeDir | 0111
- }
- if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 {
- m |= 0444
- } else {
- m |= 0666
- }
- return m
-}
-
-func (fs *fileStat) ModTime() time.Time {
- return time.Unix(0, fs.sys.LastWriteTime.Nanoseconds())
-}
-
-// Sys returns syscall.Win32FileAttributeData for file fs.
-func (fs *fileStat) Sys() interface{} { return &fs.sys }
-
-func (fs *fileStat) loadFileId() error {
- fs.Lock()
- defer fs.Unlock()
- if fs.path == "" {
- // already done
- return nil
- }
- pathp, err := syscall.UTF16PtrFromString(fs.path)
- if err != nil {
- return err
- }
- h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
- if err != nil {
- return err
- }
- defer syscall.CloseHandle(h)
- var i syscall.ByHandleFileInformation
- err = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
- if err != nil {
- return err
- }
- fs.path = ""
- fs.vol = i.VolumeSerialNumber
- fs.idxhi = i.FileIndexHigh
- fs.idxlo = i.FileIndexLow
- return nil
-}
-
-// devNullStat is fileStat structure describing DevNull file ("NUL").
-var devNullStat = fileStat{
- name: DevNull,
- // hopefully this will work for SameFile
- vol: 0,
- idxhi: 0,
- idxlo: 0,
-}
-
-func sameFile(fs1, fs2 *fileStat) bool {
- e := fs1.loadFileId()
- if e != nil {
- return false
- }
- e = fs2.loadFileId()
- if e != nil {
- return false
- }
- return fs1.vol == fs2.vol && fs1.idxhi == fs2.idxhi && fs1.idxlo == fs2.idxlo
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return time.Unix(0, fi.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
-}
diff --git a/src/pkg/os/user/lookup.go b/src/pkg/os/user/lookup.go
deleted file mode 100644
index 09f00c7bd..000000000
--- a/src/pkg/os/user/lookup.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2011 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.
-
-package user
-
-// Current returns the current user.
-func Current() (*User, error) {
- return current()
-}
-
-// Lookup looks up a user by username. If the user cannot be found, the
-// returned error is of type UnknownUserError.
-func Lookup(username string) (*User, error) {
- return lookup(username)
-}
-
-// LookupId looks up a user by userid. If the user cannot be found, the
-// returned error is of type UnknownUserIdError.
-func LookupId(uid string) (*User, error) {
- return lookupId(uid)
-}
diff --git a/src/pkg/os/user/lookup_plan9.go b/src/pkg/os/user/lookup_plan9.go
deleted file mode 100644
index f7ef3482b..000000000
--- a/src/pkg/os/user/lookup_plan9.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 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.
-
-package user
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "syscall"
-)
-
-// Partial os/user support on Plan 9.
-// Supports Current(), but not Lookup()/LookupId().
-// The latter two would require parsing /adm/users.
-const (
- userFile = "/dev/user"
-)
-
-func current() (*User, error) {
- ubytes, err := ioutil.ReadFile(userFile)
- if err != nil {
- return nil, fmt.Errorf("user: %s", err)
- }
-
- uname := string(ubytes)
-
- u := &User{
- Uid: uname,
- Gid: uname,
- Username: uname,
- Name: uname,
- HomeDir: os.Getenv("home"),
- }
-
- return u, nil
-}
-
-func lookup(username string) (*User, error) {
- return nil, syscall.EPLAN9
-}
-
-func lookupId(uid string) (*User, error) {
- return nil, syscall.EPLAN9
-}
diff --git a/src/pkg/os/user/lookup_stubs.go b/src/pkg/os/user/lookup_stubs.go
deleted file mode 100644
index 86f0e6e64..000000000
--- a/src/pkg/os/user/lookup_stubs.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2011 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.
-
-// +build !cgo,!windows,!plan9
-
-package user
-
-import (
- "fmt"
- "runtime"
-)
-
-func init() {
- implemented = false
-}
-
-func current() (*User, error) {
- return nil, fmt.Errorf("user: Current not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
-
-func lookup(username string) (*User, error) {
- return nil, fmt.Errorf("user: Lookup not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
-
-func lookupId(uid string) (*User, error) {
- return nil, fmt.Errorf("user: LookupId not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
diff --git a/src/pkg/os/user/lookup_unix.go b/src/pkg/os/user/lookup_unix.go
deleted file mode 100644
index f2baf05bb..000000000
--- a/src/pkg/os/user/lookup_unix.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2011 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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-// +build cgo
-
-package user
-
-import (
- "fmt"
- "runtime"
- "strconv"
- "strings"
- "syscall"
- "unsafe"
-)
-
-/*
-#include <unistd.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <stdlib.h>
-
-static int mygetpwuid_r(int uid, struct passwd *pwd,
- char *buf, size_t buflen, struct passwd **result) {
- return getpwuid_r(uid, pwd, buf, buflen, result);
-}
-*/
-import "C"
-
-func current() (*User, error) {
- return lookupUnix(syscall.Getuid(), "", false)
-}
-
-func lookup(username string) (*User, error) {
- return lookupUnix(-1, username, true)
-}
-
-func lookupId(uid string) (*User, error) {
- i, e := strconv.Atoi(uid)
- if e != nil {
- return nil, e
- }
- return lookupUnix(i, "", false)
-}
-
-func lookupUnix(uid int, username string, lookupByName bool) (*User, error) {
- var pwd C.struct_passwd
- var result *C.struct_passwd
-
- var bufSize C.long
- if runtime.GOOS == "dragonfly" || runtime.GOOS == "freebsd" {
- // DragonFly and FreeBSD do not have _SC_GETPW_R_SIZE_MAX
- // and just return -1. So just use the same
- // size that Linux returns.
- bufSize = 1024
- } else {
- bufSize = C.sysconf(C._SC_GETPW_R_SIZE_MAX)
- if bufSize <= 0 || bufSize > 1<<20 {
- return nil, fmt.Errorf("user: unreasonable _SC_GETPW_R_SIZE_MAX of %d", bufSize)
- }
- }
- buf := C.malloc(C.size_t(bufSize))
- defer C.free(buf)
- var rv C.int
- if lookupByName {
- nameC := C.CString(username)
- defer C.free(unsafe.Pointer(nameC))
- rv = C.getpwnam_r(nameC,
- &pwd,
- (*C.char)(buf),
- C.size_t(bufSize),
- &result)
- if rv != 0 {
- return nil, fmt.Errorf("user: lookup username %s: %s", username, syscall.Errno(rv))
- }
- if result == nil {
- return nil, UnknownUserError(username)
- }
- } else {
- // mygetpwuid_r is a wrapper around getpwuid_r to
- // to avoid using uid_t because C.uid_t(uid) for
- // unknown reasons doesn't work on linux.
- rv = C.mygetpwuid_r(C.int(uid),
- &pwd,
- (*C.char)(buf),
- C.size_t(bufSize),
- &result)
- if rv != 0 {
- return nil, fmt.Errorf("user: lookup userid %d: %s", uid, syscall.Errno(rv))
- }
- if result == nil {
- return nil, UnknownUserIdError(uid)
- }
- }
- u := &User{
- Uid: strconv.Itoa(int(pwd.pw_uid)),
- Gid: strconv.Itoa(int(pwd.pw_gid)),
- Username: C.GoString(pwd.pw_name),
- Name: C.GoString(pwd.pw_gecos),
- HomeDir: C.GoString(pwd.pw_dir),
- }
- // The pw_gecos field isn't quite standardized. Some docs
- // say: "It is expected to be a comma separated list of
- // personal data where the first item is the full name of the
- // user."
- if i := strings.Index(u.Name, ","); i >= 0 {
- u.Name = u.Name[:i]
- }
- return u, nil
-}
diff --git a/src/pkg/os/user/lookup_windows.go b/src/pkg/os/user/lookup_windows.go
deleted file mode 100644
index 99c325ff0..000000000
--- a/src/pkg/os/user/lookup_windows.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2012 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.
-
-package user
-
-import (
- "fmt"
- "syscall"
- "unsafe"
-)
-
-func isDomainJoined() (bool, error) {
- var domain *uint16
- var status uint32
- err := syscall.NetGetJoinInformation(nil, &domain, &status)
- if err != nil {
- return false, err
- }
- syscall.NetApiBufferFree((*byte)(unsafe.Pointer(domain)))
- return status == syscall.NetSetupDomainName, nil
-}
-
-func lookupFullNameDomain(domainAndUser string) (string, error) {
- return syscall.TranslateAccountName(domainAndUser,
- syscall.NameSamCompatible, syscall.NameDisplay, 50)
-}
-
-func lookupFullNameServer(servername, username string) (string, error) {
- s, e := syscall.UTF16PtrFromString(servername)
- if e != nil {
- return "", e
- }
- u, e := syscall.UTF16PtrFromString(username)
- if e != nil {
- return "", e
- }
- var p *byte
- e = syscall.NetUserGetInfo(s, u, 10, &p)
- if e != nil {
- return "", e
- }
- defer syscall.NetApiBufferFree(p)
- i := (*syscall.UserInfo10)(unsafe.Pointer(p))
- if i.FullName == nil {
- return "", nil
- }
- name := syscall.UTF16ToString((*[1024]uint16)(unsafe.Pointer(i.FullName))[:])
- return name, nil
-}
-
-func lookupFullName(domain, username, domainAndUser string) (string, error) {
- joined, err := isDomainJoined()
- if err == nil && joined {
- name, err := lookupFullNameDomain(domainAndUser)
- if err == nil {
- return name, nil
- }
- }
- name, err := lookupFullNameServer(domain, username)
- if err == nil {
- return name, nil
- }
- // domain worked neigher as a domain nor as a server
- // could be domain server unavailable
- // pretend username is fullname
- return username, nil
-}
-
-func newUser(usid *syscall.SID, gid, dir string) (*User, error) {
- username, domain, t, e := usid.LookupAccount("")
- if e != nil {
- return nil, e
- }
- if t != syscall.SidTypeUser {
- return nil, fmt.Errorf("user: should be user account type, not %d", t)
- }
- domainAndUser := domain + `\` + username
- uid, e := usid.String()
- if e != nil {
- return nil, e
- }
- name, e := lookupFullName(domain, username, domainAndUser)
- if e != nil {
- return nil, e
- }
- u := &User{
- Uid: uid,
- Gid: gid,
- Username: domainAndUser,
- Name: name,
- HomeDir: dir,
- }
- return u, nil
-}
-
-func current() (*User, error) {
- t, e := syscall.OpenCurrentProcessToken()
- if e != nil {
- return nil, e
- }
- defer t.Close()
- u, e := t.GetTokenUser()
- if e != nil {
- return nil, e
- }
- pg, e := t.GetTokenPrimaryGroup()
- if e != nil {
- return nil, e
- }
- gid, e := pg.PrimaryGroup.String()
- if e != nil {
- return nil, e
- }
- dir, e := t.GetUserProfileDirectory()
- if e != nil {
- return nil, e
- }
- return newUser(u.User.Sid, gid, dir)
-}
-
-// BUG(brainman): Lookup and LookupId functions do not set
-// Gid and HomeDir fields in the User struct returned on windows.
-
-func newUserFromSid(usid *syscall.SID) (*User, error) {
- // TODO(brainman): do not know where to get gid and dir fields
- gid := "unknown"
- dir := "Unknown directory"
- return newUser(usid, gid, dir)
-}
-
-func lookup(username string) (*User, error) {
- sid, _, t, e := syscall.LookupSID("", username)
- if e != nil {
- return nil, e
- }
- if t != syscall.SidTypeUser {
- return nil, fmt.Errorf("user: should be user account type, not %d", t)
- }
- return newUserFromSid(sid)
-}
-
-func lookupId(uid string) (*User, error) {
- sid, e := syscall.StringToSid(uid)
- if e != nil {
- return nil, e
- }
- return newUserFromSid(sid)
-}
diff --git a/src/pkg/os/user/user.go b/src/pkg/os/user/user.go
deleted file mode 100644
index e8680fe54..000000000
--- a/src/pkg/os/user/user.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2011 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.
-
-// Package user allows user account lookups by name or id.
-package user
-
-import (
- "strconv"
-)
-
-var implemented = true // set to false by lookup_stubs.go's init
-
-// User represents a user account.
-//
-// On posix systems Uid and Gid contain a decimal number
-// representing uid and gid. On windows Uid and Gid
-// contain security identifier (SID) in a string format.
-// On Plan 9, Uid, Gid, Username, and Name will be the
-// contents of /dev/user.
-type User struct {
- Uid string // user id
- Gid string // primary group id
- Username string
- Name string
- HomeDir string
-}
-
-// UnknownUserIdError is returned by LookupId when
-// a user cannot be found.
-type UnknownUserIdError int
-
-func (e UnknownUserIdError) Error() string {
- return "user: unknown userid " + strconv.Itoa(int(e))
-}
-
-// UnknownUserError is returned by Lookup when
-// a user cannot be found.
-type UnknownUserError string
-
-func (e UnknownUserError) Error() string {
- return "user: unknown user " + string(e)
-}
diff --git a/src/pkg/os/user/user_test.go b/src/pkg/os/user/user_test.go
deleted file mode 100644
index 9d9420e80..000000000
--- a/src/pkg/os/user/user_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2011 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.
-
-package user
-
-import (
- "runtime"
- "testing"
-)
-
-func check(t *testing.T) {
- if !implemented {
- t.Skip("user: not implemented; skipping tests")
- }
-}
-
-func TestCurrent(t *testing.T) {
- check(t)
-
- u, err := Current()
- if err != nil {
- t.Fatalf("Current: %v", err)
- }
- if u.HomeDir == "" {
- t.Errorf("didn't get a HomeDir")
- }
- if u.Username == "" {
- t.Errorf("didn't get a username")
- }
-}
-
-func compare(t *testing.T, want, got *User) {
- if want.Uid != got.Uid {
- t.Errorf("got Uid=%q; want %q", got.Uid, want.Uid)
- }
- if want.Username != got.Username {
- t.Errorf("got Username=%q; want %q", got.Username, want.Username)
- }
- if want.Name != got.Name {
- t.Errorf("got Name=%q; want %q", got.Name, want.Name)
- }
- // TODO(brainman): fix it once we know how.
- if runtime.GOOS == "windows" {
- t.Skip("skipping Gid and HomeDir comparisons")
- }
- if want.Gid != got.Gid {
- t.Errorf("got Gid=%q; want %q", got.Gid, want.Gid)
- }
- if want.HomeDir != got.HomeDir {
- t.Errorf("got HomeDir=%q; want %q", got.HomeDir, want.HomeDir)
- }
-}
-
-func TestLookup(t *testing.T) {
- check(t)
-
- if runtime.GOOS == "plan9" {
- t.Skipf("Lookup not implemented on %q", runtime.GOOS)
- }
-
- want, err := Current()
- if err != nil {
- t.Fatalf("Current: %v", err)
- }
- got, err := Lookup(want.Username)
- if err != nil {
- t.Fatalf("Lookup: %v", err)
- }
- compare(t, want, got)
-}
-
-func TestLookupId(t *testing.T) {
- check(t)
-
- if runtime.GOOS == "plan9" {
- t.Skipf("LookupId not implemented on %q", runtime.GOOS)
- }
-
- want, err := Current()
- if err != nil {
- t.Fatalf("Current: %v", err)
- }
- got, err := LookupId(want.Uid)
- if err != nil {
- t.Fatalf("LookupId: %v", err)
- }
- compare(t, want, got)
-}