]> Cypherpunks repositories - gostls13.git/commitdiff
os: consolidate files
authorHiroshi Ioka <hirochachacha@gmail.com>
Sun, 14 Aug 2016 16:39:00 +0000 (01:39 +0900)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 16 Aug 2016 00:15:36 +0000 (00:15 +0000)
Code movement only.

If someone finds function 'foo' in "foo_linux.go",
they will expect that the Window version of 'foo' exists in "foo_windows.go".

Current code doesn't follow this manner.

For example, 'sameFile' exists in "file_unix.go",
"stat_plan9.go" and "types_windows.go".

The CL address that problem by following rules:

* readdir family => dir.go, dir_$GOOS.go
* stat family => stat.go, stat_$GOOS.go
* path-functions => path_$GOOS.go
* sameFile => types.go, types_$GOOS.go
* process-functions => exec.go, exec_$GOOS.go
* hostname => sys.go, sys_$GOOS.go

Change-Id: Ic3c64663ce0b2a364d7a414351cd3c772e70187b
Reviewed-on: https://go-review.googlesource.com/27035
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
15 files changed:
src/os/dir.go [new file with mode: 0644]
src/os/dir_unix.go
src/os/dir_windows.go
src/os/doc.go [deleted file]
src/os/exec.go
src/os/file_unix.go
src/os/file_windows.go
src/os/path_unix.go
src/os/path_windows.go
src/os/stat_plan9.go
src/os/stat_unix.go [new file with mode: 0644]
src/os/stat_windows.go
src/os/sys.go [new file with mode: 0644]
src/os/types_plan9.go
src/os/types_unix.go

diff --git a/src/os/dir.go b/src/os/dir.go
new file mode 100644 (file)
index 0000000..6c54456
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2016 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
+
+// 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) ([]FileInfo, 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)
+}
index 589db85274077b2e09ddd1596be40cd2f9d1ebbc..cfa70a141e5f8ea87c0e967674068048c0488fe5 100644 (file)
@@ -15,6 +15,28 @@ const (
        blockSize = 4096
 )
 
+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
+}
+
 func (f *File) readdirnames(n int) (names []string, err error) {
        // If this file has no dirinfo, create one.
        if f.dirinfo == nil {
index 931316048bce2f976204fab9ae3bf50cd2b1f7a5..76024fc1e3fd92f9fb91cce0ca7b42e133aa2dab 100644 (file)
@@ -4,6 +4,70 @@
 
 package os
 
+import (
+       "io"
+       "syscall"
+)
+
+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(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 := 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
+}
+
 func (file *File) readdirnames(n int) (names []string, err error) {
        fis, err := file.Readdir(n)
        names = make([]string, len(fis))
diff --git a/src/os/doc.go b/src/os/doc.go
deleted file mode 100644 (file)
index 0313eac..0000000
+++ /dev/null
@@ -1,139 +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.
-//
-// On Unix systems, FindProcess always succeeds and returns a Process
-// for the given pid, regardless of whether the process exists.
-func FindProcess(pid int) (*Process, 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) ([]FileInfo, 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)
-}
index bf3249864d33e3f847835d94010e8f0d015fd0e5..8a53e5dd1ee05fb0fa803c54cf5d280eee017cfe 100644 (file)
@@ -9,6 +9,7 @@ import (
        "sync"
        "sync/atomic"
        "syscall"
+       "time"
 )
 
 // Process stores the information about a process created by StartProcess.
@@ -70,3 +71,89 @@ func Getpid() int { return syscall.Getpid() }
 
 // Getppid returns the process id of the caller's parent.
 func Getppid() int { return syscall.Getppid() }
+
+// 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.
+//
+// On Unix systems, FindProcess always succeeds and returns a Process
+// for the given pid, regardless of whether the process exists.
+func FindProcess(pid int) (*Process, 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()
+}
index 9b64f216500fd5f96d635c853b5ac85ff1a98702..5bc2b1162277aa2af20dc52fe119ce3df5b72b7b 100644 (file)
@@ -11,10 +11,6 @@ import (
        "syscall"
 )
 
-func sameFile(fs1, fs2 *fileStat) bool {
-       return fs1.sys.Dev == fs2.sys.Dev && fs1.sys.Ino == fs2.sys.Ino
-}
-
 func rename(oldname, newname string) error {
        e := syscall.Rename(oldname, newname)
        if e != nil {
@@ -147,69 +143,6 @@ func (file *file) close() error {
        return err
 }
 
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Stat() (FileInfo, error) {
-       if f == nil {
-               return nil, ErrInvalid
-       }
-       var fs fileStat
-       err := syscall.Fstat(f.fd, &fs.sys)
-       if err != nil {
-               return nil, &PathError{"stat", f.name, err}
-       }
-       fillFileStatFromSys(&fs, f.name)
-       return &fs, nil
-}
-
-// Stat returns a FileInfo describing the named file.
-// If there is an error, it will be of type *PathError.
-func Stat(name string) (FileInfo, error) {
-       var fs fileStat
-       err := syscall.Stat(name, &fs.sys)
-       if err != nil {
-               return nil, &PathError{"stat", name, err}
-       }
-       fillFileStatFromSys(&fs, name)
-       return &fs, 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) (FileInfo, error) {
-       var fs fileStat
-       err := syscall.Lstat(name, &fs.sys)
-       if err != nil {
-               return nil, &PathError{"lstat", name, err}
-       }
-       fillFileStatFromSys(&fs, name)
-       return &fs, 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
@@ -324,24 +257,6 @@ func Remove(name string) error {
        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")
index f470fc4315cc2b987fab3518beeb88226bf12cf2..722d4d0823b553cf3c88b3f8fdde8804c40e9b03 100644 (file)
@@ -196,65 +196,6 @@ func (file *file) close() error {
        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(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 := 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.
@@ -586,42 +527,3 @@ func Symlink(oldname, newname string) error {
        }
        return nil
 }
-
-func fromSlash(path string) string {
-       // Replace each '/' with '\\' if present
-       var pathbuf []byte
-       var lastSlash int
-       for i, b := range path {
-               if b == '/' {
-                       if pathbuf == nil {
-                               pathbuf = make([]byte, len(path))
-                       }
-                       copy(pathbuf[lastSlash:], path[lastSlash:i])
-                       pathbuf[i] = '\\'
-                       lastSlash = i + 1
-               }
-       }
-       if pathbuf == nil {
-               return path
-       }
-
-       copy(pathbuf[lastSlash:], path[lastSlash:])
-       return string(pathbuf)
-}
-
-func dirname(path string) string {
-       vol := volumeName(path)
-       i := len(path) - 1
-       for i >= len(vol) && !IsPathSeparator(path[i]) {
-               i--
-       }
-       dir := path[len(vol) : i+1]
-       last := len(dir) - 1
-       if last > 0 && IsPathSeparator(dir[last]) {
-               dir = dir[:last]
-       }
-       if dir == "" {
-               dir = "."
-       }
-       return vol + dir
-}
index 36f8e61bf92ed5d77a751e84a8f521accbb487ee..ecf098c46125c882eac7f2821b26a09b8d08f2c1 100644 (file)
@@ -15,3 +15,21 @@ const (
 func IsPathSeparator(c uint8) bool {
        return PathSeparator == c
 }
+
+// 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
+}
index c96f1376860cf78e6e925e496f64e32135ae376f..ced28c3f0f9c920d5ee166ef20ecbe9c41c4b7f5 100644 (file)
@@ -14,3 +14,116 @@ func IsPathSeparator(c uint8) bool {
        // NOTE: Windows accept / as path separator.
        return c == '\\' || c == '/'
 }
+
+// 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 isAbs(path string) (b bool) {
+       v := volumeName(path)
+       if v == "" {
+               return false
+       }
+       path = path[len(v):]
+       if path == "" {
+               return false
+       }
+       return IsPathSeparator(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 && IsPathSeparator(path[0]) && IsPathSeparator(path[1]) &&
+               !IsPathSeparator(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 IsPathSeparator(path[n]) {
+                               n++
+                               // third, following something characters. its share name.
+                               if !IsPathSeparator(path[n]) {
+                                       if path[n] == '.' {
+                                               break
+                                       }
+                                       for ; n < l; n++ {
+                                               if IsPathSeparator(path[n]) {
+                                                       break
+                                               }
+                                       }
+                                       return path[:n]
+                               }
+                               break
+                       }
+               }
+       }
+       return ""
+}
+
+func fromSlash(path string) string {
+       // Replace each '/' with '\\' if present
+       var pathbuf []byte
+       var lastSlash int
+       for i, b := range path {
+               if b == '/' {
+                       if pathbuf == nil {
+                               pathbuf = make([]byte, len(path))
+                       }
+                       copy(pathbuf[lastSlash:], path[lastSlash:i])
+                       pathbuf[i] = '\\'
+                       lastSlash = i + 1
+               }
+       }
+       if pathbuf == nil {
+               return path
+       }
+
+       copy(pathbuf[lastSlash:], path[lastSlash:])
+       return string(pathbuf)
+}
+
+func dirname(path string) string {
+       vol := volumeName(path)
+       i := len(path) - 1
+       for i >= len(vol) && !IsPathSeparator(path[i]) {
+               i--
+       }
+       dir := path[len(vol) : i+1]
+       last := len(dir) - 1
+       if last > 0 && IsPathSeparator(dir[last]) {
+               dir = dir[:last]
+       }
+       if dir == "" {
+               dir = "."
+       }
+       return vol + dir
+}
index 96f056c1117b5e7d7525d6d9f2919923083db682..1ae165807f864408c2447772fd157e9c8b0e2a8a 100644 (file)
@@ -11,12 +11,6 @@ import (
 
 const _BIT16SZ = 2
 
-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,
diff --git a/src/os/stat_unix.go b/src/os/stat_unix.go
new file mode 100644 (file)
index 0000000..1733d3f
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2016 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"
+)
+
+// Stat returns the FileInfo structure describing file.
+// If there is an error, it will be of type *PathError.
+func (f *File) Stat() (FileInfo, error) {
+       if f == nil {
+               return nil, ErrInvalid
+       }
+       var fs fileStat
+       err := syscall.Fstat(f.fd, &fs.sys)
+       if err != nil {
+               return nil, &PathError{"stat", f.name, err}
+       }
+       fillFileStatFromSys(&fs, f.name)
+       return &fs, nil
+}
+
+// Stat returns a FileInfo describing the named file.
+// If there is an error, it will be of type *PathError.
+func Stat(name string) (FileInfo, error) {
+       var fs fileStat
+       err := syscall.Stat(name, &fs.sys)
+       if err != nil {
+               return nil, &PathError{"stat", name, err}
+       }
+       fillFileStatFromSys(&fs, name)
+       return &fs, 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) (FileInfo, error) {
+       var fs fileStat
+       err := syscall.Lstat(name, &fs.sys)
+       if err != nil {
+               return nil, &PathError{"lstat", name, err}
+       }
+       fillFileStatFromSys(&fs, name)
+       return &fs, nil
+}
index e55eeb0fdd67be5fdce25999d4c5db01871ac6e6..3c433b1579b75cca02dd720ee14a2638ddb4c2f0 100644 (file)
@@ -105,77 +105,3 @@ func Lstat(name string) (FileInfo, error) {
        }
        return fs, nil
 }
-
-// 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 isAbs(path string) (b bool) {
-       v := volumeName(path)
-       if v == "" {
-               return false
-       }
-       path = path[len(v):]
-       if path == "" {
-               return false
-       }
-       return IsPathSeparator(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 && IsPathSeparator(path[0]) && IsPathSeparator(path[1]) &&
-               !IsPathSeparator(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 IsPathSeparator(path[n]) {
-                               n++
-                               // third, following something characters. its share name.
-                               if !IsPathSeparator(path[n]) {
-                                       if path[n] == '.' {
-                                               break
-                                       }
-                                       for ; n < l; n++ {
-                                               if IsPathSeparator(path[n]) {
-                                                       break
-                                               }
-                                       }
-                                       return path[:n]
-                               }
-                               break
-                       }
-               }
-       }
-       return ""
-}
diff --git a/src/os/sys.go b/src/os/sys.go
new file mode 100644 (file)
index 0000000..28b0f6b
--- /dev/null
@@ -0,0 +1,10 @@
+// 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
+
+// Hostname returns the host name reported by the kernel.
+func Hostname() (name string, err error) {
+       return hostname()
+}
index 6d46ca9dd3d52a090d69aaedd60fa0e5951d0026..5fccc4f09a9e5052dcfb4e5128a2d8fc4895c9b2 100644 (file)
@@ -4,7 +4,10 @@
 
 package os
 
-import "time"
+import (
+       "syscall"
+       "time"
+)
 
 // A fileStat is the implementation of FileInfo returned by Stat and Lstat.
 type fileStat struct {
@@ -19,3 +22,9 @@ 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 }
+
+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
+}
index 056220c09b6bc4d4c9a159062023c66dc654f59c..c0259ae0e8411f791fadfd3a57ed3f6d9c44620b 100644 (file)
@@ -25,3 +25,7 @@ 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 }
+
+func sameFile(fs1, fs2 *fileStat) bool {
+       return fs1.sys.Dev == fs2.sys.Dev && fs1.sys.Ino == fs2.sys.Ino
+}