// 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.

// The os package provides a platform-independent interface to operating
// system functionality.  The design is Unix-like.
package os

import (
	"os";
	"syscall";
)

// 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.
}

// File represents an open file descriptor.
type File struct {
	fd int;
	name	string;
	dirinfo	*dirInfo;	// nil unless directory being read
	nepipe	int;	// number of consecutive EPIPE in Write
}

// Fd returns the integer Unix file descriptor referencing the open file.
func (file *File) Fd() int {
	return file.fd
}

// Name returns the name of the file as presented to Open.
func (file *File) Name() string {
	return file.name
}

// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd int, name string) *File {
	if fd < 0 {
		return nil
	}
	return &File{fd, name, nil, 0}
}

// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
// standard output, and standard error file descriptors.
var (
	Stdin  = NewFile(0, "/dev/stdin");
	Stdout = NewFile(1, "/dev/stdout");
	Stderr = NewFile(2, "/dev/stderr");
)

// Flags to Open wrapping those of the underlying system. Not all flags
// may be implemented on a given system.
const (
	O_RDONLY = syscall.O_RDONLY;	// open the file read-only.
	O_WRONLY = syscall.O_WRONLY;	// open the file write-only.
	O_RDWR = syscall.O_RDWR;	// open the file read-write.
	O_APPEND = syscall.O_APPEND;	// open the file append-only.
	O_ASYNC = syscall.O_ASYNC;	// generate a signal when I/O is available.
	O_CREAT = syscall.O_CREAT;	// create a new file if none exists.
	O_NOCTTY = syscall.O_NOCTTY;	// do not make file the controlling tty.
	O_NONBLOCK = syscall.O_NONBLOCK;	// open in non-blocking mode.
	O_NDELAY = O_NONBLOCK;		// synonym for O_NONBLOCK
	O_SYNC = syscall.O_SYNC;	// open for synchronous I/O.
	O_TRUNC = syscall.O_TRUNC;	// if possible, truncate file when opened.
)

// Open 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 Open(name string, flag int, perm int) (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;
}

// 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 EINVAL
	}
	var err os.Error;
	if e := syscall.Close(file.fd); e != 0 {
		err = &PathError{"close", file.name, Errno(e)};
	}
	file.fd = -1;  // so it can't be closed again
	return err;
}

type eofError int
func (eofError) String() string {
	return "EOF"
}

// EOF is the Error returned by Read when no more input is available.
// Functions should return EOF only to signal a graceful end of input.
// If the EOF occurs unexpectedly in a structured data stream,
// the appropriate error is either io.ErrUnexpectedEOF or some other error
// giving more detail.
var EOF Error = eofError(0)

// 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 EOF.
// TODO(r): Add Pread, Pwrite (maybe ReadAt, WriteAt).
func (file *File) Read(b []byte) (ret int, err Error) {
	if file == nil {
		return 0, EINVAL
	}
	n, e := syscall.Read(file.fd, b);
	if n < 0 {
		n = 0;
	}
	if n == 0 && e == 0 {
		return 0, EOF
	}
	if e != 0 {
		err = &PathError{"read", file.name, Errno(e)};
	}
	return n, err
}

// Write writes len(b) bytes to the File.
// It returns the number of bytes written and an Error, if any.
// If the byte count differs from len(b), it usually implies an error occurred.
func (file *File) Write(b []byte) (ret int, err Error) {
	if file == nil {
		return 0, EINVAL
	}
	n, e := syscall.Write(file.fd, b);
	if n < 0 {
		n = 0
	}
	if e == syscall.EPIPE {
		file.nepipe++;
		if file.nepipe >= 10 {
			os.Exit(syscall.EPIPE);
		}
	} else {
		file.nepipe = 0;
	}
	if e != 0 {
		err = &PathError{"write", file.name, Errno(e)};
	}
	return n, err
}

// 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 (file *File) Seek(offset int64, whence int) (ret int64, err Error) {
	r, e := syscall.Seek(file.fd, offset, whence);
	if e == 0 && file.dirinfo != nil && r != 0 {
		e = syscall.EISDIR;
	}
	if e != 0 {
		return 0, &PathError{"seek", file.name, Errno(e)};
	}
	return r, nil
}

// WriteString is like Write, but writes the contents of string s rather than
// an array of bytes.
func (file *File) WriteString(s string) (ret int, err Error) {
	if file == nil {
		return 0, EINVAL
	}
	b := syscall.StringByteSlice(s);
	b = b[0:len(b)-1];
	return file.Write(b);
}

// 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);
	if e != 0 {
		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
}

// Mkdir creates a new directory with the specified name and permission bits.
// It returns an error, if any.
func Mkdir(name string, perm int) Error {
	e := syscall.Mkdir(name, perm);
	if e != 0 {
		return &PathError{"mkdir", name, Errno(e)};
	}
	return nil;
}

// Stat returns a Dir structure describing the named file and an error, if any.
// If name names a valid symbolic link, the returned Dir describes
// the file pointed at by the link and has dir.FollowedSymlink set to true.
// If name names an invalid symbolic link, the returned Dir describes
// the link itself and has dir.FollowedSymlink set to false.
func Stat(name string) (dir *Dir, err Error) {
	var lstat, stat syscall.Stat_t;
	e := syscall.Lstat(name, &lstat);
	if e != 0 {
		return nil, &PathError{"stat", name, Errno(e)};
	}
	statp := &lstat;
	if lstat.Mode & syscall.S_IFMT == syscall.S_IFLNK {
		e := syscall.Stat(name, &stat);
		if e == 0 {
			statp = &stat;
		}
	}
	return dirFromStat(name, new(Dir), &lstat, statp), nil
}

// Stat returns the Dir structure describing file.
// It returns the Dir and an error, if any.
func (file *File) Stat() (dir *Dir, err Error) {
	var stat syscall.Stat_t;
	e := syscall.Fstat(file.fd, &stat);
	if e != 0 {
		return nil, &PathError{"stat", file.name, Errno(e)};
	}
	return dirFromStat(file.name, new(Dir), &stat, &stat), nil
}

// Lstat returns the Dir structure describing the named file and an error, if any.
// If the file is a symbolic link, the returned Dir describes the
// symbolic link.  Lstat makes no attempt to follow the link.
func Lstat(name string) (dir *Dir, err Error) {
	var stat syscall.Stat_t;
	e := syscall.Lstat(name, &stat);
	if e != 0 {
		return nil, &PathError{"lstat", name, Errno(e)};
	}
	return dirFromStat(name, new(Dir), &stat, &stat), nil
}

// Readdirnames reads the contents of the directory associated with file and
// returns an array of up to count names, in directory order.  Subsequent
// calls on the same file will yield further names.
// A negative count means to read until EOF.
// Readdirnames returns the array and an Error, if any.
func (file *File) Readdirnames(count int) (names []string, err Error)

// Readdir reads the contents of the directory associated with file and
// returns an array of up to count Dir structures, as would be returned
// by Stat, in directory order.  Subsequent calls on the same file will yield further Dirs.
// A negative count means to read until EOF.
// Readdir returns the array and an Error, if any.
func (file *File) Readdir(count int) (dirs []Dir, err Error) {
	dirname := file.name;
	if dirname == "" {
		dirname = ".";
	}
	dirname += "/";
	names, err1 := file.Readdirnames(count);
	if err1 != nil {
		return nil, err1
	}
	dirs = make([]Dir, len(names));
	for i, filename := range names {
		dirp, err := Stat(dirname + filename);
		if dirp ==  nil || err != nil {
			dirs[i].Name = filename	// rest is already zeroed out
		} else {
			dirs[i] = *dirp
		}
	}
	return
}

// Chdir changes the current working directory to the named directory.
func Chdir(dir string) Error {
	if e := syscall.Chdir(dir); e != 0 {
		return &PathError{"chdir", dir, Errno(e)};
	}
	return nil;
}

// Chdir changes the current working directory to the file,
// which must be a directory.
func (f *File) Chdir() Error {
	if e := syscall.Fchdir(f.fd); e != 0 {
		return &PathError{"chdir", f.name, Errno(e)};
	}
	return nil;
}

// Remove removes the named file or directory.
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 == 0 {
		return nil;
	}
	e1 := syscall.Rmdir(name);
	if e1 == 0 {
		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, Errno(e)};
}

// LinkError records an error during a link or symlink
// system call and the paths that caused it.
type LinkError struct {
	Op string;
	Old string;
	New string;
	Error Error;
}

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

// Link creates a hard link.
func Link(oldname, newname string) Error {
	e := syscall.Link(oldname, newname);
	if e != 0 {
		return &LinkError{"link", oldname, newname, Errno(e)};
	}
	return nil;
}

// Symlink creates a symbolic link.
func Symlink(oldname, newname string) Error {
	e := syscall.Symlink(oldname, newname);
	if e != 0 {
		return &LinkError{"symlink", oldname, newname, Errno(e)};
	}
	return nil;
}

// Readlink reads the contents of a symbolic link: the destination of
// the link.  It returns the contents and an Error, if any.
func Readlink(name string) (string, Error) {
	for len := 128; ; len *= 2 {
		b := make([]byte, len);
		n, e := syscall.Readlink(name, b);
		if e != 0 {
			return "", &PathError{"readlink", name, Errno(e)};
		}
		if n < len {
			return string(b[0:n]), nil;
		}
	}
	// Silence 6g.
	return "", nil;
}

// Chmod changes the mode of the named file to mode.
// If the file is a symbolic link, it changes the uid and gid of the link's target.
func Chmod(name string, mode int) Error {
	if e := syscall.Chmod(name, mode); e != 0 {
		return &PathError{"chmod", name, Errno(e)};
	}
	return nil;
}

// Chmod changes the mode of the file to mode.
func (f *File) Chmod(mode int) Error {
	if e := syscall.Fchmod(f.fd, mode); e != 0 {
		return &PathError{"chmod", f.name, Errno(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.
func Chown(name string, uid, gid int) Error {
	if e := syscall.Chown(name, uid, gid); e != 0 {
		return &PathError{"chown", name, Errno(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.
func Lchown(name string, uid, gid int) Error {
	if e := syscall.Lchown(name, uid, gid); e != 0 {
		return &PathError{"lchown", name, Errno(e)};
	}
	return nil;
}

// Chown changes the numeric uid and gid of the named file.
func (f *File) Chown(uid, gid int) Error {
	if e := syscall.Fchown(f.fd, uid, gid); e != 0 {
		return &PathError{"chown", f.name, Errno(e)};
	}
	return nil;
}

// 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 {
	if e := syscall.Truncate(name, size); e != 0 {
		return &PathError{"truncate", name, Errno(e)};
	}
	return nil;
}

// Truncate changes the size of the file.
// It does not change the I/O offset.
func (f *File) Truncate(size int64) Error {
	if e := syscall.Ftruncate(f.fd, size); e != 0 {
		return &PathError{"truncate", f.name, Errno(e)};
	}
	return nil;
}

