Landin library reference discuss source

hosted/blocking/delegated.ldn

1--  What does not wait, handed to the hosted/system handle this provider
2--  is built over: the environment, directories, the rest of the file
3--  system and terminals, entropy and the wall clock.  Each entry is the
4--  system's, so a program over this provider meets the same behaviour,
5--  errno and all, as one over the system alone.  Running programs is
6--  programs.ldn's, which only starts a child through the system (D479).
7
8import core/io
9import core/text
10import core/time
11
12blocking_variable_count: (self: host) -> (count: usize) =
13    count = io.variable_count(self.services)
14end blocking_variable_count
15
16blocking_variable_at: (self: host, index: usize)
17                      -> (item: io.variable from self) ! io.no_variable =
18    item = try io.variable_at(self.services, index)
19end blocking_variable_at
20
21blocking_variable_named: (self: host, name: text.host_string)
22                         -> (value: text.host_string from self)
23                         ! io.no_variable =
24    value = try io.variable_named(self.services, name)
25end blocking_variable_named
26
27host is io.environment
28    (variable_count: blocking_variable_count,
29     variable_at: blocking_variable_at,
30     variable_named: blocking_variable_named)
31
32blocking_open_directory: (self: host, path: text.host_string,
33                          buffer: []mut u8)
34                         -> (opened: io.directory from buffer)
35                         ! io.not_found | io.no_access | io.io_failed =
36    opened = try io.open_directory(self.services, path, buffer)
37end blocking_open_directory
38
39blocking_read_entry: (self: host, inout opened: io.directory)
40                     -> (item: io.entry from opened) ! io.io_failed =
41    item = try io.read_entry(self.services, opened)
42end blocking_read_entry
43
44blocking_entry_size: (self: host, opened: io.directory,
45                      name: text.host_string)
46                     -> (size: u64)
47                     ! io.not_found | io.no_access | io.io_failed =
48    size = try io.entry_size(self.services, opened, name)
49end blocking_entry_size
50
51blocking_close_directory: (self: host, sink opened: io.directory)
52                          -> none ! io.io_failed =
53    try io.close_directory(self.services, opened)
54end blocking_close_directory
55
56blocking_make_directory: (self: host, path: text.host_string)
57                         -> none ! io.already_exists | io.not_found
58                                 | io.no_access | io.io_failed =
59    try io.make_directory(self.services, path)
60end blocking_make_directory
61
62blocking_remove_file: (self: host, path: text.host_string)
63                      -> none ! io.not_found | io.no_access | io.io_failed =
64    try io.remove_file(self.services, path)
65end blocking_remove_file
66
67blocking_remove_directory: (self: host, path: text.host_string)
68                           -> none
69                           ! io.not_found | io.no_access | io.io_failed =
70    try io.remove_directory(self.services, path)
71end blocking_remove_directory
72
73host is io.directories
74    (open_directory: blocking_open_directory,
75     read_entry: blocking_read_entry, entry_size: blocking_entry_size,
76     close_directory: blocking_close_directory,
77     make_directory: blocking_make_directory,
78     remove_file: blocking_remove_file,
79     remove_directory: blocking_remove_directory)
80
81blocking_open_file: (self: host, path: text.host_string,
82                     options: io.open_options)
83                    -> (opened: io.file)
84                    ! io.already_exists | io.not_found | io.no_access
85                    | io.io_failed =
86    opened = try io.open_file(self.services, path, options)
87end blocking_open_file
88
89blocking_rename: (self: host, old: text.host_string, new: text.host_string)
90                 -> none ! io.not_found | io.no_access | io.io_failed =
91    try io.rename(self.services, old, new)
92end blocking_rename
93
94blocking_status_of: (self: host, path: text.host_string,
95                     links: io.link_handling)
96                    -> (found: io.status)
97                    ! io.not_found | io.no_access | io.io_failed =
98    found = try io.status_of(self.services, path, links)
99end blocking_status_of
100
101blocking_status_of_file: (self: host, opened: io.file)
102                         -> (found: io.status) ! io.io_failed =
103    found = try io.status_of_file(self.services, opened)
104end blocking_status_of_file
105
106blocking_set_read_only: (self: host, path: text.host_string,
107                         read_only: bool)
108                        -> none ! io.not_found | io.no_access | io.io_failed =
109    try io.set_read_only(self.services, path, read_only)
110end blocking_set_read_only
111
112blocking_synchronize: (self: host, opened: io.file,
113                       writing: io.synchronizing) -> none ! io.io_failed =
114    try io.synchronize(self.services, opened, writing)
115end blocking_synchronize
116
117blocking_truncate: (self: host, opened: io.file, size: u64)
118                   -> none ! io.io_failed =
119    try io.truncate(self.services, opened, size)
120end blocking_truncate
121
122--  A regular file's data is read and written at an offset at once on
123--  every hosted system, which no readiness says otherwise of, so these are
124--  the system's too.
125blocking_read_at: (self: host, opened: io.file, offset: u64,
126                   into: []mut u8) -> (count: usize) ! io.io_failed =
127    count = try io.read_at(self.services, opened, offset, into)
128end blocking_read_at
129
130blocking_write_at: (self: host, opened: io.file, offset: u64, bytes: []u8)
131                   -> none ! io.io_failed =
132    try io.write_at(self.services, opened, offset, bytes)
133end blocking_write_at
134
135--  core/io's own `make_temporary` erases a concrete source of names, and
136--  this one has an erased source already, which it hands on as it is.
137temporary_over: (provider: type is io.file_system, services: provider,
138                 directory: text.host_string, names: any io.entropy,
139                 into: []mut u8)
140                -> (made: io.temporary from into)
141                ! io.not_found | io.no_access | io.io_failed =
142    made = try provider.make_temporary(services, directory, names, into)
143end temporary_over
144
145blocking_make_temporary: (self: host, directory: text.host_string,
146                          names: any io.entropy, into: []mut u8)
147                         -> (made: io.temporary from into)
148                         ! io.not_found | io.no_access | io.io_failed =
149    made = try temporary_over(self.services, directory, names, into)
150end blocking_make_temporary
151
152blocking_current_directory: (self: host, into: []mut u8)
153                            -> (path: text.host_string from into)
154                            ! io.io_failed =
155    path = try io.current_directory(self.services, into)
156end blocking_current_directory
157
158host is io.file_system
159    (open_file: blocking_open_file, rename: blocking_rename,
160     status_of: blocking_status_of, status_of_file: blocking_status_of_file,
161     set_read_only: blocking_set_read_only,
162     synchronize: blocking_synchronize, truncate: blocking_truncate,
163     read_at: blocking_read_at, write_at: blocking_write_at,
164     make_temporary: blocking_make_temporary,
165     current_directory: blocking_current_directory)
166
167blocking_is_terminal: (self: host, stream: io.file) -> (yes: bool) =
168    yes = io.is_terminal(self.services, stream)
169end blocking_is_terminal
170
171blocking_window_size: (self: host, stream: io.file) -> (size: io.window)
172                      ! io.not_a_terminal | io.io_failed =
173    size = try io.window_size(self.services, stream)
174end blocking_window_size
175
176host is io.terminals
177    (is_terminal: blocking_is_terminal, window_size: blocking_window_size)
178
179blocking_fill_random: (self: host, into: []mut u8) -> none ! io.io_failed =
180    try io.fill_random(self.services, into)
181end blocking_fill_random
182
183host is io.entropy (fill_random: blocking_fill_random)
184
185blocking_wall_now: (self: host) -> (at: time.wall_time) =
186    at = time.wall_now(self.services)
187end blocking_wall_now
188
189host is time.wall_clock (wall_now: blocking_wall_now)