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
|
use sys
use "types"
use "errno"
use "cstrconv"
use "strfind"
pkg std =
const nanosleep : (nsecs : uint64 -> errno)
$noret const exit : (status : int -> void)
pkglocal const bgetcwd : (buf : byte[:] -> errno)
pkglocal const lasterr : (-> errno)
;;
const nanosleep = {nsecs
if sys.sleep((nsecs/1_000_000 : uint32)) < 0
-> lasterr()
;;
-> 0
}
const bgetcwd = {buf
var fd
fd = sys.open(".", sys.Ordonly)
if fd < 0
-> (fd : errno)
;;
if sys.fd2path(fd, buf) == 0
/*
Because we don't return the size, the best we can do is
assume that if the buffer is completely full, we have
truncated it. Since we truncate at utf8 characters, we
can have at most 3 bytes truncated (4 bytes will fit
any utf8 char), and one byte for the nul terminator.
*/
if cstrlen(buf) + 5 == buf.len
-> Erange
else
-> (cstrlen(buf) : errno)
;;
;;
-> Emisc
}
const digitchars = "0123456789"
const exit = {status
var buf : byte[32] /* big enough for exit status numbers */
var n, i
if status == 0
sys.exits("")
else
status &= 255
i = 100
n = 0
while i > 0
if status >= i
buf[n++] = digitchars[(status/i)%10]
;;
i /= 10
;;
sys.exits(buf[:n])
;;
}
const lasterr = {
var errbuf : byte[sys.Maxerr]
var err
sys.errstr(errbuf[:])
err = cstrconv(errbuf[:])
if strhas(err, "no error")
-> Enone
elif strhas(err, "already exists")
-> Eexist
elif strhas(err, "read or write too large")
-> Erange
elif strhas(err, "read or write too small")
-> Erange
elif strhas(err, "i/o error")
-> Eio
elif strhas(err, "fd out of range or not open")
-> Ebadf
else
-> Emisc
;;
}
|