-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathmodule.ae
More file actions
110 lines (101 loc) · 3.76 KB
/
Copy pathmodule.ae
File metadata and controls
110 lines (101 loc) · 3.76 KB
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
// std.file - File Operations (alias for std.fs)
//
// This is a convenience module that re-exports file functions from std.fs.
// The implementations are in std/fs/aether_fs.c.
//
// API shape:
// - Raw externs end in `_raw` and return ptr/int in the old C-style
// convention. Use them only for low-level access.
// - Aether-native wrappers (below) use Go-style `(value, err)` tuple
// returns and are the idiomatic way to call file operations.
exports(
file_open_raw, file_close, file_read_all_raw, file_write_raw,
file_exists, file_delete_raw, file_size_raw, file_fd_raw,
open, read, write, delete, size, fd
)
// Raw ptr/int externs (escape hatch).
extern file_open_raw(path: string, mode: string) -> ptr
extern file_close(file: ptr) -> int
extern file_read_all_raw(file: ptr) -> string
extern file_write_raw(file: ptr, data: string, length: int) -> int
extern file_exists(path: string) -> int
extern file_delete_raw(path: string) -> int
// Size in bytes, as `long` (#1021): the old int surface wrapped files
// >= 2 GiB to a negative value. Returns -1 on stat failure.
extern file_size_raw(path: string) -> long
extern file_fd_raw(file: ptr) -> int
// string_concat used to duplicate borrowed strings across free boundaries.
extern string_concat(a: string, b: string) -> string
extern string_length(str: string) -> int
// Open a file. Returns (handle, "") on success, (null, error) on failure.
open(path: string, mode: string) -> {
handle = file_open_raw(path, mode)
if handle == null {
return null, "cannot open file"
}
return handle, ""
}
// Read the entire contents of a file at `path`. Opens, reads, closes.
// Returns (content, "") on success, ("", error) on failure.
// This is the convenience form most callers want.
read(path: string) -> {
handle = file_open_raw(path, "r")
if handle == 0 {
return "", "cannot open file"
}
content = file_read_all_raw(handle)
if content == 0 {
file_close(handle)
return "", "cannot read file"
}
content_copy = string_concat(content, "")
file_close(handle)
return content_copy, ""
}
// Write `content` to a file at `path`. Opens in write mode, writes, closes.
// Returns "" on success, error string on failure.
write(path: string, content: string) -> {
handle = file_open_raw(path, "w")
if handle == 0 {
return "cannot open file for writing"
}
length = string_length(content)
ok = file_write_raw(handle, content, length)
file_close(handle)
if ok == 0 {
return "write failed"
}
return ""
}
// Delete the file at `path`. Returns "" on success, error on failure.
delete(path: string) -> {
ok = file_delete_raw(path)
if ok == 0 {
return "cannot delete file"
}
return ""
}
// Return the size of the file at `path` in bytes, as `long` (#1021 —
// files >= 2 GiB used to wrap negative through the old int surface).
// Returns (size, "") on success, (0, error) on failure.
//
// The success arm returns FIRST: the first `return` statement pins the
// inferred tuple slot types, so the `long`-typed arm must come before
// the int-literal error arm or the size slot narrows back to int.
size(path: string) -> {
s = file_size_raw(path)
if s >= 0 {
return s, ""
}
return 0, "cannot stat file"
}
// The OS-level file descriptor inside an open handle, or -1 on a
// null handle (#1003). Exists for capability plumbing: open through
// the stdlib, then narrow the descriptor with
// capsicum.rights_limit(file.fd(handle), ...) before capsicum.enter().
// The fd is owned by the handle — do not close it directly; it is
// released by file_close, which also frees the handle itself, so
// never call fd() on a handle that has been closed.
fd(handle: ptr) -> int {
return file_fd_raw(handle)
}