Skip to content

Commit 0383910

Browse files
committed
0.6.0 --- adopt openkal 0.9, and ask this machine what its page is
⚠️⚠️ THE ALLOCATOR ASSUMED A FOUR-KILOBYTE PAGE ON A SYSTEM WITH TWO. `kPage' was the constant 4096, and this system's own hardware pages are four kilobytes on one architecture and SIXTEEN on the other. Allocation appeared to work, because a mapping rounded to four kilobytes is rounded up again by the kernel --- while `kal_free' unmapped a range SHORTER than the one mapped, and the remainder was never returned. The page is now asked for once, through `hw.pagesize', and `kal_memory_granularity' reports it. The rest follows the specification: * `kal_fs_props' takes the directory and consults the format the volume is, which this kernel names in words. A word per implementation could state none of its positions honestly here: the volume this system is ordinarily installed on compares names without regard to case and a volume attached to the same machine may not, and both are reachable through the preopen this implementation supplies; * asking now resolves a link, because opening always did; * transfers return one signed word; the parameters and names are copied into the caller's buffer and the length reported is the value's own; * `kal_node_info' carries its own size, reports what was filled, and carries the device and inode as an opaque identity; * `kal_fs_link_create' and `kal_fs_link_read' over symlinkat and readlinkat; * `kal_fs_max_name'; typed stream handles; `kal_version' and `kal_interfaces'. Ninety-five names are exported and none other, checked against SURFACE.txt.
1 parent 04fba62 commit 0383910

16 files changed

Lines changed: 349 additions & 111 deletions

mcpp.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
namespace = "mcpplibs"
33
name = "openkal-macos"
4-
version = "0.5.0"
4+
version = "0.6.0"
55
description = "An implementation of openkal for macOS, written on the kernel's own calls. Its purpose is as much to test the specification as to be used."
66
license = "Apache-2.0"
77

@@ -18,7 +18,7 @@ authors = ["mcpplibs"]
1818
repo = "https://github.com/mcpplibs/openkal-macos"
1919

2020
[dependencies]
21-
openkal = "0.8.0"
21+
openkal = "0.9.0"
2222

2323
[build]
2424
# The flags are attached to this package's own sources rather than to the whole

src/datagram.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ int kal_datagram_local(kal_datagram d, kal_endpoint* out) {
7272
return okm::from_kernel(ss, *out);
7373
}
7474

75-
kal_io_result kal_datagram_send_to(kal_datagram d, const void* buf, kal_uintptr len,
76-
const kal_endpoint* to) {
75+
kal_intptr kal_datagram_send_to(kal_datagram d, const void* buf, kal_uintptr len,
76+
const kal_endpoint* to) {
7777
const int fd = fd_of(d);
78-
if (fd < 0 || to == nullptr) return { 0, kal_err_invalid };
78+
if (fd < 0 || to == nullptr) return -kal_err_invalid;
7979

8080
okm::ksockaddr_storage ss{};
8181
okm_u32 addrlen = 0;
8282
if (const int rc = okm::to_kernel(*to, ss, addrlen); rc != kal_ok)
83-
return { 0, rc };
83+
return -rc;
8484

8585
for (;;) {
8686
const okm_long r = okm::sys(okm::nr_sendto, fd,
@@ -89,7 +89,7 @@ kal_io_result kal_datagram_send_to(kal_datagram d, const void* buf, kal_uintptr
8989
reinterpret_cast<okm_long>(&ss),
9090
static_cast<okm_long>(addrlen));
9191
if (okm::interrupted(r)) continue;
92-
if (okm::failed(r)) return { 0, okm::translate(r) };
92+
if (okm::failed(r)) return -okm::translate(r);
9393

9494
// A MESSAGE IS SENT WHOLE OR NOT AT ALL, which is what this interface
9595
// states. The kernel reports a count anyway; a count short of the length
@@ -98,14 +98,14 @@ kal_io_result kal_datagram_send_to(kal_datagram d, const void* buf, kal_uintptr
9898
// a caller a partial send this interface says cannot occur, so it is
9999
// reported as a failure of the medium instead.
100100
const kal_uintptr n = static_cast<kal_uintptr>(r);
101-
return { n, n == len ? kal_ok : kal_err_io };
101+
return n == len ? static_cast<kal_intptr>(n) : -kal_err_io;
102102
}
103103
}
104104

105-
kal_io_result kal_datagram_recv_from(kal_datagram d, void* buf, kal_uintptr len,
106-
kal_endpoint* from) {
105+
kal_intptr kal_datagram_recv_from(kal_datagram d, void* buf, kal_uintptr len,
106+
kal_endpoint* from) {
107107
const int fd = fd_of(d);
108-
if (fd < 0) return { 0, kal_err_invalid };
108+
if (fd < 0) return -kal_err_invalid;
109109

110110
okm::ksockaddr_storage ss{};
111111
okm_u32 addrlen = static_cast<okm_u32>(sizeof ss);
@@ -117,7 +117,7 @@ kal_io_result kal_datagram_recv_from(kal_datagram d, void* buf, kal_uintptr len,
117117
reinterpret_cast<okm_long>(&ss),
118118
reinterpret_cast<okm_long>(&addrlen));
119119
if (okm::interrupted(r)) continue;
120-
if (okm::failed(r)) return { 0, okm::translate(r) };
120+
if (okm::failed(r)) return -okm::translate(r);
121121

122122
// THE COUNT REPORTED IS WHAT WAS PLACED IN THE BUFFER, not what was
123123
// sent. Without MSG_TRUNC the kernel already reports the former, which
@@ -133,7 +133,7 @@ kal_io_result kal_datagram_recv_from(kal_datagram d, void* buf, kal_uintptr len,
133133
from->port = 0;
134134
}
135135
}
136-
return { static_cast<kal_uintptr>(r), kal_ok };
136+
return static_cast<kal_intptr>(r);
137137
}
138138
}
139139

@@ -148,6 +148,6 @@ void kal_datagram_close(kal_datagram d) {
148148
// been set, and this interface has no operation that would set it; a word
149149
// claiming a facility no operation reaches is the disagreement clause 6.2 exists
150150
// to prevent.
151-
const kal_uintptr kal_datagram_props = KAL_DGRAM_PROP_IPV6;
151+
kal_uintptr kal_datagram_props(void) { return KAL_DGRAM_PROP_IPV6; }
152152

153153
} // extern "C"

src/env.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,46 +27,56 @@ extern "C" {
2727

2828
kal_uintptr kal_env_arg_count(void) { return static_cast<kal_uintptr>(okm::g_argc); }
2929

30-
const char* kal_env_arg(kal_uintptr index, kal_uintptr* len) {
31-
if (index >= static_cast<kal_uintptr>(okm::g_argc)) { if (len) *len = 0; return nullptr; }
30+
// EVERY VALUE IS COPIED INTO THE CALLER'S BUFFER. These answered with a pointer
31+
// into this implementation's own storage, which is meaningful only while the
32+
// implementation shares the caller's address space. Each reports the length the
33+
// value HAS, so a caller with a large enough buffer is done in one call and one
34+
// that wants to size first passes a capacity of zero.
35+
namespace {
36+
kal_intptr give(const char* v, kal_uintptr n, char* out, kal_uintptr cap) {
37+
if (out != nullptr && cap != 0) okm::copy(out, v, n < cap ? n : cap);
38+
return static_cast<kal_intptr>(n);
39+
}
40+
} // namespace
41+
42+
kal_intptr kal_env_arg(kal_uintptr index, char* out, kal_uintptr cap) {
43+
if (index >= static_cast<kal_uintptr>(okm::g_argc)) return -kal_err_not_found;
3244
const char* s = okm::g_argv[index];
33-
if (len) *len = okm::length(s);
34-
return s;
45+
return give(s, okm::length(s), out, cap);
3546
}
3647

37-
const char* kal_env_var(const char* name, kal_uintptr name_len, kal_uintptr* value_len) {
48+
kal_intptr kal_env_var(const char* name, kal_uintptr name_len,
49+
char* out, kal_uintptr cap) {
50+
if (name == nullptr) return -kal_err_invalid;
3851
for (char** e = okm::g_envp; e && *e; ++e) {
3952
const char* entry = *e;
4053
kal_uintptr i = 0;
4154
while (i < name_len && entry[i] != '\0' && entry[i] == name[i]) ++i;
4255
if (i == name_len && entry[i] == '=') {
4356
const char* v = entry + name_len + 1;
44-
if (value_len) *value_len = okm::length(v);
45-
return v;
57+
return give(v, okm::length(v), out, cap);
4658
}
4759
}
48-
if (value_len) *value_len = 0;
49-
return nullptr;
60+
// A name that is not there is distinct from one whose value is empty.
61+
return -kal_err_not_found;
5062
}
5163

5264
kal_uintptr kal_env_var_count(void) {
5365
kal_uintptr n = 0; for (char** e = okm::g_envp; e && *e; ++e) ++n; return n;
5466
}
5567

56-
const char* kal_env_var_at(kal_uintptr index, kal_uintptr* name_len,
57-
const char** value, kal_uintptr* value_len) {
68+
// The NAME at a position. The value is then obtained by kal_env_var: an
69+
// operation answering both needs two buffers, two capacities and two lengths,
70+
// and its second half is kal_env_var written again.
71+
kal_intptr kal_env_var_at(kal_uintptr index, char* out, kal_uintptr cap) {
5872
kal_uintptr n = 0;
5973
for (char** e = okm::g_envp; e && *e; ++e, ++n) {
6074
if (n != index) continue;
6175
const char* entry = *e;
6276
kal_uintptr i = 0; while (entry[i] != '\0' && entry[i] != '=') ++i;
63-
if (name_len) *name_len = i;
64-
const char* v = entry[i] == '=' ? entry + i + 1 : entry + i;
65-
if (value) *value = v;
66-
if (value_len) *value_len = okm::length(v);
67-
return entry;
77+
return give(entry, i, out, cap);
6878
}
69-
return nullptr;
79+
return -kal_err_not_found;
7080
}
7181

7282
}

src/exec.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ void kal_exec_free(void* p, kal_uintptr size) {
120120
// interface separates the two states; a caller that must change published bytes
121121
// reserves a second region and abandons the first, which is what the header
122122
// says a zero here means.
123-
const kal_uintptr kal_exec_props = 0;
123+
// Executable memory on this system is granted only to an artifact produced
124+
// with the entitlement for it, which is a decision made after the link. The
125+
// interface is provided and the position reports whether this artifact may use
126+
// it --- clause 6.5's answer at dependency resolution cannot serve an artifact
127+
// produced once and run in many environments.
128+
kal_uintptr kal_exec_props(void) { return 0; }
124129

125130
} // extern "C"

0 commit comments

Comments
 (0)