// 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 (
	"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 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) (n 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
}

// 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.
// EOF is signaled by a zero count with err set to EOF.
// ReadAt always returns a non-nil Error when n != len(b).
func (file *File) ReadAt(b []byte, off int64) (n int, err Error) {
	if file == nil {
		return 0, EINVAL;
	}
	for len(b) > 0 {
		m, e := syscall.Pread(file.fd, b, off);
		n += m;
		if e != 0 {
			err = &PathError{"read", file.name, Errno(e)};
			break;
		}
		b = b[m:len(b)];
		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 (file *File) Write(b []byte) (n 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 {
			Exit(syscall.EPIPE);
		}
	} else {
		file.nepipe = 0;
	}
	if e != 0 {
		err = &PathError{"write", file.name, Errno(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 (file *File) WriteAt(b []byte, off int64) (n int, err Error) {
	if file == nil {
		return 0, EINVAL;
	}
	for len(b) > 0 {
		m, e := syscall.Pwrite(file.fd, b, off);
		n += m;
		if e != 0 {
			err = &PathError{"write", file.name, Errno(e)};
			break;
		}
		b = b[m:len(b)];
		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 (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
}

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

