aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/os/file_other.go
blob: 977fcac12d0c852091a3d147c516b2a23a96f3ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//go:build baremetal || (tinygo.wasm && !wasip1 && !wasip2)

package os

import (
	_ "unsafe"
)

// 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")
)

const DevNull = "/dev/null"

// isOS indicates whether we're running on a real operating system with
// filesystem support.
const isOS = false

// stdioFileHandle represents one of stdin, stdout, or stderr depending on the
// number. It implements the FileHandle interface.
type stdioFileHandle uint8

// file is the real representation of *File.
// The extra level of indirection ensures that no clients of os
// can overwrite this data, which could cause the finalizer
// to close the wrong file descriptor.
type file struct {
	handle     FileHandle
	name       string
	appendMode bool
}

func (f *file) close() error {
	return f.handle.Close()
}

func NewFile(fd uintptr, name string) *File {
	return &File{&file{handle: stdioFileHandle(fd), name: name}}
}

// Rename renames (moves) oldpath to newpath.
// If newpath already exists and is not a directory, Rename replaces it.
// OS-specific restrictions may apply when oldpath and newpath are in different directories.
// If there is an error, it will be of type *LinkError.
func Rename(oldpath, newpath string) error {
	return ErrNotImplemented
}

// Read reads up to len(b) bytes from machine.Serial.
// It returns the number of bytes read and any error encountered.
func (f stdioFileHandle) Read(b []byte) (n int, err error) {
	if len(b) == 0 {
		return 0, nil
	}

	size := buffered()
	for size == 0 {
		gosched()
		size = buffered()
	}

	if size > len(b) {
		size = len(b)
	}
	for i := 0; i < size; i++ {
		b[i] = getchar()
	}
	return size, nil
}

func (f stdioFileHandle) ReadAt(b []byte, off int64) (n int, err error) {
	return 0, ErrNotImplemented
}

func (f stdioFileHandle) WriteAt(b []byte, off int64) (n int, err error) {
	return 0, ErrNotImplemented
}

// Write writes len(b) bytes to the output. It returns the number of bytes
// written or an error if this file is not stdout or stderr.
func (f stdioFileHandle) Write(b []byte) (n int, err error) {
	switch f {
	case 1, 2: // stdout, stderr
		for _, c := range b {
			putchar(c)
		}
		return len(b), nil
	default:
		return 0, ErrUnsupported
	}
}

// Close is unsupported on this system.
func (f stdioFileHandle) Close() error {
	return ErrUnsupported
}

// Seek wraps syscall.Seek.
func (f stdioFileHandle) Seek(offset int64, whence int) (int64, error) {
	return -1, ErrUnsupported
}

func (f stdioFileHandle) Sync() error {
	return ErrUnsupported
}

func (f stdioFileHandle) Fd() uintptr {
	return uintptr(f)
}

//go:linkname putchar runtime.putchar
func putchar(c byte)

//go:linkname getchar runtime.getchar
func getchar() byte

//go:linkname buffered runtime.buffered
func buffered() int

//go:linkname gosched runtime.Gosched
func gosched() int

func Pipe() (r *File, w *File, err error) {
	return nil, nil, ErrNotImplemented
}

func Readlink(name string) (string, error) {
	return "", ErrNotImplemented
}

func tempDir() string {
	return "/tmp"
}

// Truncate is unsupported on this system.
func Truncate(filename string, size int64) (err error) {
	return ErrUnsupported
}

// Truncate is unsupported on this system.
func (f *File) Truncate(size int64) (err error) {
	if f.handle == nil {
		return ErrClosed
	}

	return Truncate(f.name, size)
}