package sys

import (
	
	

	experimentalsys 
	
	
	
)

// StdinFile is a fs.ModeDevice file for use implementing FdStdin.
// This is safer than reading from os.DevNull as it can never overrun
// operating system file descriptors.
type StdinFile struct {
	noopStdinFile
	io.Reader
}

// Read implements the same method as documented on sys.File
func ( *StdinFile) ( []byte) (int, experimentalsys.Errno) {
	,  := .Reader.Read()
	return , experimentalsys.UnwrapOSError()
}

type writerFile struct {
	noopStdoutFile

	w io.Writer
}

// Write implements the same method as documented on sys.File
func ( *writerFile) ( []byte) (int, experimentalsys.Errno) {
	,  := .w.Write()
	return , experimentalsys.UnwrapOSError()
}

// noopStdinFile is a fs.ModeDevice file for use implementing FdStdin. This is
// safer than reading from os.DevNull as it can never overrun operating system
// file descriptors.
type noopStdinFile struct {
	noopStdioFile
}

// Read implements the same method as documented on sys.File
func (noopStdinFile) ([]byte) (int, experimentalsys.Errno) {
	return 0, 0 // Always EOF
}

// Poll implements the same method as documented on fsapi.File
func (noopStdinFile) ( fsapi.Pflag,  int32) ( bool,  experimentalsys.Errno) {
	if  != fsapi.POLLIN {
		return false, experimentalsys.ENOTSUP
	}
	return true, 0 // always ready to read nothing
}

// noopStdoutFile is a fs.ModeDevice file for use implementing FdStdout and
// FdStderr.
type noopStdoutFile struct {
	noopStdioFile
}

// Write implements the same method as documented on sys.File
func (noopStdoutFile) ( []byte) (int, experimentalsys.Errno) {
	return len(), 0 // same as io.Discard
}

type noopStdioFile struct {
	experimentalsys.UnimplementedFile
}

// Stat implements the same method as documented on sys.File
func (noopStdioFile) () (sys.Stat_t, experimentalsys.Errno) {
	return sys.Stat_t{Mode: modeDevice, Nlink: 1}, 0
}

// IsDir implements the same method as documented on sys.File
func (noopStdioFile) () (bool, experimentalsys.Errno) {
	return false, 0
}

// Close implements the same method as documented on sys.File
func (noopStdioFile) () ( experimentalsys.Errno) { return }

// IsNonblock implements the same method as documented on fsapi.File
func (noopStdioFile) () bool {
	return false
}

// SetNonblock implements the same method as documented on fsapi.File
func (noopStdioFile) (bool) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

// Poll implements the same method as documented on fsapi.File
func (noopStdioFile) (fsapi.Pflag, int32) ( bool,  experimentalsys.Errno) {
	return false, experimentalsys.ENOSYS
}

func stdinFileEntry( io.Reader) (*FileEntry, error) {
	if  == nil {
		return &FileEntry{Name: "stdin", IsPreopen: true, File: &noopStdinFile{}}, nil
	} else if ,  := .(*os.File);  {
		if ,  := sysfs.NewStdioFile(true, );  != nil {
			return nil, 
		} else {
			return &FileEntry{Name: "stdin", IsPreopen: true, File: }, nil
		}
	} else {
		return &FileEntry{Name: "stdin", IsPreopen: true, File: &StdinFile{Reader: }}, nil
	}
}

func stdioWriterFileEntry( string,  io.Writer) (*FileEntry, error) {
	if  == nil {
		return &FileEntry{Name: , IsPreopen: true, File: &noopStdoutFile{}}, nil
	} else if ,  := .(*os.File);  {
		if ,  := sysfs.NewStdioFile(false, );  != nil {
			return nil, 
		} else {
			return &FileEntry{Name: , IsPreopen: true, File: }, nil
		}
	} else {
		return &FileEntry{Name: , IsPreopen: true, File: &writerFile{w: }}, nil
	}
}