summaryrefslogtreecommitdiff
path: root/src/pkg/os/file_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/os/file_windows.go')
-rw-r--r--src/pkg/os/file_windows.go317
1 files changed, 0 insertions, 317 deletions
diff --git a/src/pkg/os/file_windows.go b/src/pkg/os/file_windows.go
deleted file mode 100644
index 70dd6e241..000000000
--- a/src/pkg/os/file_windows.go
+++ /dev/null
@@ -1,317 +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"
- "syscall"
-)
-
-// File represents an open file descriptor.
-type File struct {
- fd syscall.Handle
- name string
- dirinfo *dirInfo // nil unless directory being read
- nepipe int // number of consecutive EPIPE in Write
- l sync.Mutex // used to implement windows pread/pwrite
-}
-
-// Fd returns the Windows handle referencing the open file.
-func (file *File) Fd() syscall.Handle {
- if file == nil {
- return syscall.InvalidHandle
- }
- return file.fd
-}
-
-// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd syscall.Handle, name string) *File {
- if fd < 0 {
- return nil
- }
- f := &File{fd: fd, name: name}
- runtime.SetFinalizer(f, (*File).Close)
- return f
-}
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
- stat syscall.Stat_t
- usefirststat bool
-}
-
-const DevNull = "NUL"
-
-func (file *File) isdir() bool { return file != nil && file.dirinfo != nil }
-
-func openFile(name string, flag int, perm uint32) (file *File, err Error) {
- r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, perm)
- if e != 0 {
- return nil, &PathError{"open", name, Errno(e)}
- }
-
- // There's a race here with fork/exec, which we are
- // content to live with. See ../syscall/exec.go
- if syscall.O_CLOEXEC == 0 { // O_CLOEXEC not supported
- syscall.CloseOnExec(r)
- }
-
- return NewFile(r, name), nil
-}
-
-func openDir(name string) (file *File, err Error) {
- d := new(dirInfo)
- r, e := syscall.FindFirstFile(syscall.StringToUTF16Ptr(name+"\\*"), &d.stat.Windata)
- if e != 0 {
- return nil, &PathError{"open", name, Errno(e)}
- }
- f := NewFile(r, name)
- d.usefirststat = true
- 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.
-// It returns the File and an Error, if any.
-func OpenFile(name string, flag int, perm uint32) (file *File, err Error) {
- // TODO(brainman): not sure about my logic of assuming it is dir first, then fall back to file
- r, e := openDir(name)
- if e == nil {
- if flag&O_WRONLY != 0 || flag&O_RDWR != 0 {
- r.Close()
- return nil, &PathError{"open", name, EISDIR}
- }
- return r, nil
- }
- r, e = openFile(name, flag, perm)
- if e == nil {
- return r, nil
- }
- // Imitating Unix behavior by replacing syscall.ERROR_PATH_NOT_FOUND with
- // os.ENOTDIR. Not sure if we should go into that.
- if e2, ok := e.(*PathError); ok {
- if e3, ok := e2.Error.(Errno); ok {
- if e3 == Errno(syscall.ERROR_PATH_NOT_FOUND) {
- return nil, &PathError{"open", name, ENOTDIR}
- }
- }
- }
- return nil, e
-}
-
-// Close closes the File, rendering it unusable for I/O.
-// It returns an Error, if any.
-func (file *File) Close() Error {
- if file == nil || file.fd < 0 {
- return EINVAL
- }
- var e int
- if file.isdir() {
- e = syscall.FindClose(syscall.Handle(file.fd))
- } else {
- e = syscall.CloseHandle(syscall.Handle(file.fd))
- }
- var err Error
- if e != 0 {
- err = &PathError{"close", file.name, Errno(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) statFile(name string) (fi *FileInfo, err Error) {
- var stat syscall.ByHandleFileInformation
- e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &stat)
- if e != 0 {
- return nil, &PathError{"stat", file.name, Errno(e)}
- }
- return fileInfoFromByHandleInfo(new(FileInfo), file.name, &stat), nil
-}
-
-// Stat returns the FileInfo structure describing file.
-// It returns the FileInfo and an error, if any.
-func (file *File) Stat() (fi *FileInfo, err Error) {
- if file == nil || file.fd < 0 {
- return nil, EINVAL
- }
- if file.isdir() {
- // I don't know any better way to do that for directory
- return Stat(file.name)
- }
- return file.statFile(file.name)
-}
-
-// Readdir reads the contents of the directory associated with file and
-// returns an array of up to n FileInfo structures, 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 os.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 os.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 (file *File) Readdir(n int) (fi []FileInfo, err Error) {
- if file == nil || file.fd < 0 {
- return nil, EINVAL
- }
- if !file.isdir() {
- return nil, &PathError{"Readdir", file.name, ENOTDIR}
- }
- di := file.dirinfo
- wantAll := n <= 0
- size := n
- if wantAll {
- n = -1
- size = 100
- }
- fi = make([]FileInfo, 0, size) // Empty with room to grow.
- for n != 0 {
- if di.usefirststat {
- di.usefirststat = false
- } else {
- e := syscall.FindNextFile(syscall.Handle(file.fd), &di.stat.Windata)
- if e != 0 {
- if e == syscall.ERROR_NO_MORE_FILES {
- break
- } else {
- err = &PathError{"FindNextFile", file.name, Errno(e)}
- if !wantAll {
- fi = nil
- }
- return
- }
- }
- }
- var f FileInfo
- fileInfoFromWin32finddata(&f, &di.stat.Windata)
- if f.Name == "." || f.Name == ".." { // Useless names
- continue
- }
- n--
- fi = append(fi, f)
- }
- if !wantAll && len(fi) == 0 {
- return fi, EOF
- }
- return fi, 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 int) {
- f.l.Lock()
- defer f.l.Unlock()
- 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 int) {
- f.l.Lock()
- defer f.l.Unlock()
- curoffset, e := syscall.Seek(f.fd, 0, 1)
- if e != 0 {
- 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 != 0 {
- return 0, e
- }
- return int(done), 0
-}
-
-// 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 int) {
- f.l.Lock()
- defer f.l.Unlock()
- 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 int) {
- f.l.Lock()
- defer f.l.Unlock()
- curoffset, e := syscall.Seek(f.fd, 0, 1)
- if e != 0 {
- 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 != 0 {
- return 0, e
- }
- return int(done), 0
-}
-
-// 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 int) {
- 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
-}
-
-// 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 iserror(e) {
- syscall.ForkLock.RUnlock()
- return nil, nil, NewSyscallError("pipe", e)
- }
- syscall.CloseOnExec(p[0])
- syscall.CloseOnExec(p[1])
- syscall.ForkLock.RUnlock()
-
- return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
-}