commit 8b1ca348725ccecce1b95cf12170f54e8e54ea56
parent 5893c49443b70fb649836b1da6a0caf4fe274249
Author: Sebastian <sebastian@sebsite.pw>
Date: Tue, 5 Sep 2023 22:07:05 -0400
rt: print unknown errno number in strerror/errname
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
6 files changed, 85 insertions(+), 8 deletions(-)
diff --git a/rt/+freebsd/errno.ha b/rt/+freebsd/errno.ha
@@ -17,7 +17,7 @@ fn wrap_return(r: u64) (errno | u64) = {
};
// Obtains a human-friendly reading of an [[errno]] (e.g. "Operation not
-// permitted").
+// permitted"). The return value may be statically allocated.
export fn strerror(err: errno) str = {
switch (err: int) {
case EPERM =>
@@ -213,11 +213,12 @@ export fn strerror(err: errno) str = {
case ERPCMISMATCH =>
return "RPC version wrong";
case =>
- return "[unknown errno]"; // TODO: snprintf to add errno?
+ return unknown_errno(err);
};
};
-// Gets the programmer-friendly name for an [[errno]] (e.g. EPERM).
+// Gets the programmer-friendly name for an [[errno]] (e.g. EPERM). The return
+// value may be statically allocated.
export fn errname(err: errno) str = {
switch (err: int) {
case EPERM =>
@@ -413,7 +414,7 @@ export fn errname(err: errno) str = {
case ERPCMISMATCH =>
return "ERPCMISMATCH";
case =>
- return "[unknown errno]"; // TODO: snprintf to add errno?
+ return unknown_errno(err);
};
};
diff --git a/rt/+linux/errno.ha b/rt/+linux/errno.ha
@@ -18,7 +18,7 @@ fn wrap_return(r: u64) (errno | u64) = {
};
// Obtains a human-friendly reading of an [[errno]] (e.g. "Operation not
-// permitted").
+// permitted"). The return value may be statically allocated.
export fn strerror(err: errno) str = {
switch (err: int) {
case EPERM =>
@@ -284,11 +284,12 @@ export fn strerror(err: errno) str = {
case EHWPOISON =>
return "Memory page has hardware error";
case =>
- return "[unknown errno]"; // TODO: snprintf to add errno?
+ return unknown_errno(err);
};
};
-// Gets the programmer-friendly name for an [[errno]] (e.g. EPERM).
+// Gets the programmer-friendly name for an [[errno]] (e.g. EPERM). The return
+// value may be statically allocated.
export fn errname(err: errno) str = {
switch (err: int) {
case EPERM =>
@@ -554,7 +555,7 @@ export fn errname(err: errno) str = {
case EHWPOISON =>
return "EHWPOISON";
case =>
- return "[unknown errno]"; // TODO: snprintf to add errno?
+ return unknown_errno(err);
};
};
diff --git a/rt/unknown_errno.ha b/rt/unknown_errno.ha
@@ -0,0 +1,26 @@
+fn unknown_errno(err: errno) str = {
+ static let buf: [27]u8 = [0...];
+ const s = *(&"[unknown errno ": *[]u8);
+ buf[..len(s)] = s;
+ if (err < 0) {
+ buf[len(s)] = '-';
+ const s2 = &ztos(-err: size): *string;
+ buf[len(s) + 1..s2.length + len(s) + 1] = s2.data[..s2.length];
+ buf[s2.length + len(s) + 1] = ']';
+ return *(&buf[..s2.length + len(s) + 2]: *str);
+ } else {
+ const s2 = &ztos(err: size): *string;
+ buf[len(s)..s2.length + len(s)] = s2.data[..s2.length];
+ buf[s2.length + len(s)] = ']';
+ return *(&buf[..s2.length + len(s) + 1]: *str);
+ };
+};
+
+@test fn unknown_errno() void = {
+ let err: errno = -1;
+ assert(strerror(err) == "[unknown errno -1]");
+ err = 0;
+ assert(strerror(err) == "[unknown errno 0]");
+ err = 2147483647;
+ assert(strerror(err) == "[unknown errno 2147483647]");
+};
diff --git a/rt/ztos.ha b/rt/ztos.ha
@@ -0,0 +1,37 @@
+fn bytes_reverse(b: []u8) void = {
+ if (len(b) == 0) {
+ return;
+ };
+ for (let s = 0z, e = len(b) - 1; s < e) {
+ let x = b[s];
+ b[s] = b[e];
+ b[e] = x;
+ s += 1;
+ e -= 1;
+ };
+};
+
+fn ztos(u: size) const str = {
+ static let buf: [20]u8 = [0...];
+ buf = [0...];
+
+ let s = struct {
+ b: *[*]u8 = &buf,
+ l: size = 0,
+ c: size = 0,
+ };
+
+ if (u == 0) {
+ s.b[s.l] = '0';
+ s.l += 1;
+ };
+
+ for (u > 0) {
+ s.b[s.l] = '0' + (u % 10): u8;
+ s.l += 1;
+ u /= 10;
+ };
+
+ bytes_reverse(s.b[..s.l]);
+ return *(&s: *str);
+};
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -43,6 +43,8 @@ gensrcs_rt() {
memmove.ha \
memset.ha \
strcmp.ha \
+ unknown_errno.ha \
+ ztos.ha \
$*
gen_srcs -pfreebsd rt \
+freebsd/platform_abort.ha \
@@ -67,6 +69,8 @@ gensrcs_rt() {
memmove.ha \
memset.ha \
strcmp.ha \
+ unknown_errno.ha \
+ ztos.ha \
$*
}
diff --git a/stdlib.mk b/stdlib.mk
@@ -27,6 +27,8 @@ stdlib_rt_linux_srcs = \
$(STDLIB)/rt/memmove.ha \
$(STDLIB)/rt/memset.ha \
$(STDLIB)/rt/strcmp.ha \
+ $(STDLIB)/rt/unknown_errno.ha \
+ $(STDLIB)/rt/ztos.ha \
$(STDLIB)/rt/abort.ha \
$(STDLIB)/rt/start.ha
@@ -54,6 +56,8 @@ stdlib_rt_freebsd_srcs = \
$(STDLIB)/rt/memmove.ha \
$(STDLIB)/rt/memset.ha \
$(STDLIB)/rt/strcmp.ha \
+ $(STDLIB)/rt/unknown_errno.ha \
+ $(STDLIB)/rt/ztos.ha \
$(STDLIB)/rt/abort.ha \
$(STDLIB)/rt/start.ha
@@ -2427,6 +2431,8 @@ testlib_rt_linux_srcs = \
$(STDLIB)/rt/memmove.ha \
$(STDLIB)/rt/memset.ha \
$(STDLIB)/rt/strcmp.ha \
+ $(STDLIB)/rt/unknown_errno.ha \
+ $(STDLIB)/rt/ztos.ha \
$(STDLIB)/rt/abort+test.ha \
$(STDLIB)/rt/start+test.ha \
$(STDLIB)/rt/+test/signal_test.ha
@@ -2455,6 +2461,8 @@ testlib_rt_freebsd_srcs = \
$(STDLIB)/rt/memmove.ha \
$(STDLIB)/rt/memset.ha \
$(STDLIB)/rt/strcmp.ha \
+ $(STDLIB)/rt/unknown_errno.ha \
+ $(STDLIB)/rt/ztos.ha \
$(STDLIB)/rt/abort+test.ha \
$(STDLIB)/rt/start+test.ha \
$(STDLIB)/rt/+test/signal_test.ha