Signed-off-by: Sebastian <sebastian@sebsite.pw>
---
io/+freebsd/file.ha | 46 +++++++++++++++++++++++++++++++++----
io/+linux/file.ha | 56 +++++++++++++++++++++++++++++++++++++++++----
2 files changed, 93 insertions(+), 9 deletions(-)
diff --git a/io/+freebsd/file.ha b/io/+freebsd/file.ha
index 81b2c93f..b2a66a6d 100644
--- a/io/+freebsd/file.ha
+++ b/io/+freebsd/file.ha
@@ -21,7 +21,18 @@ export fn fdopen(fd: int) file = fd;
fn fd_read(fd: file, buf: []u8) (size | EOF | error) = {
match (rt::read(fd, buf: *[*]u8, len(buf))) {
case let err: rt::errno =>
- return errors::errno(err);
+ switch (err) {
+ case rt::EAGAIN =>
+ return errors::again;
+ case rt::EINTR =>
+ return errors::interrupted;
+ case rt::EINVAL =>
+ return errors::invalid;
+ case rt::EISDIR =>
+ return errors::unsupported;
+ case =>
+ return errors::errno(err);
+ };
case let n: size =>
switch (n) {
case 0 =>
@@ -35,7 +46,20 @@ fn fd_read(fd: file, buf: []u8) (size | EOF | error) = {
fn fd_write(fd: file, buf: const []u8) (size | error) = {
match (rt::write(fd, buf: *const [*]u8, len(buf))) {
case let err: rt::errno =>
- return errors::errno(err);
+ switch (err) {
+ case rt::EAGAIN =>
+ return errors::again;
+ case rt::EINTR =>
+ return errors::interrupted;
+ case rt::EINVAL =>
+ return errors::invalid;
+ case rt::EPERM =>
+ return errors::noaccess;
+ case rt::EPIPE =>
+ return errors::unsupported;
+ case =>
+ return errors::errno(err);
+ };
case let n: size =>
return n;
};
@@ -45,7 +69,12 @@ fn fd_close(fd: file) (void | error) = {
match (rt::close(fd)) {
case void => void;
case let err: rt::errno =>
- return errors::errno(err);
+ switch (err) {
+ case rt::EINTR =>
+ return errors::interrupted;
+ case =>
+ return errors::errno(err);
+ };
};
};
@@ -56,7 +85,16 @@ fn fd_seek(
) (off | error) = {
match (rt::lseek(fd, offs: i64, whence: uint)) {
case let err: rt::errno =>
- return errors::errno(err);
+ switch (err) {
+ case rt::EINVAL =>
+ return errors::invalid;
+ case rt::EOVERFLOW =>
+ return errors::overflow;
+ case rt::ESPIPE =>
+ return errors::unsupported;
+ case =>
+ return errors::errno(err);
+ };
case let n: i64 =>
return n: off;
};
diff --git a/io/+linux/file.ha b/io/+linux/file.ha
index f2564e17..399342a3 100644
--- a/io/+linux/file.ha
+++ b/io/+linux/file.ha
@@ -22,7 +22,18 @@ export fn fdopen(fd: int) file = fd;
fn fd_read(fd: file, buf: []u8) (size | EOF | error) = {
match (rt::read(fd, buf: *[*]u8, len(buf))) {
case let err: rt::errno =>
- return errors::errno(err);
+ switch (err) {
+ case rt::EAGAIN =>
+ return errors::again;
+ case rt::EINTR =>
+ return errors::interrupted;
+ case rt::EINVAL =>
+ return errors::invalid;
+ case rt::EISDIR =>
+ return errors::unsupported;
+ case =>
+ return errors::errno(err);
+ };
case let n: size =>
switch (n) {
case 0 =>
@@ -36,7 +47,20 @@ fn fd_read(fd: file, buf: []u8) (size | EOF | error) = {
fn fd_write(fd: file, buf: const []u8) (size | error) = {
match (rt::write(fd, buf: *const [*]u8, len(buf))) {
case let err: rt::errno =>
- return errors::errno(err);
+ switch (err) {
+ case rt::EAGAIN =>
+ return errors::again;
+ case rt::EINTR =>
+ return errors::interrupted;
+ case rt::EINVAL =>
+ return errors::invalid;
+ case rt::EPERM =>
+ return errors::noaccess;
+ case rt::EPIPE =>
+ return errors::unsupported;
+ case =>
+ return errors::errno(err);
+ };
case let n: size =>
return n;
};
@@ -46,7 +70,12 @@ fn fd_close(fd: file) (void | error) = {
match (rt::close(fd)) {
case void => void;
case let err: rt::errno =>
- return errors::errno(err);
+ switch (err) {
+ case rt::EINTR =>
+ return errors::interrupted;
+ case =>
+ return errors::errno(err);
+ };
};
};
@@ -57,7 +86,16 @@ fn fd_seek(
) (off | error) = {
match (rt::lseek(fd, offs: i64, whence: uint)) {
case let err: rt::errno =>
- return errors::errno(err);
+ switch (err) {
+ case rt::EINVAL =>
+ return errors::invalid;
+ case rt::EOVERFLOW =>
+ return errors::overflow;
+ case rt::ESPIPE =>
+ return errors::unsupported;
+ case =>
+ return errors::errno(err);
+ };
case let n: i64 =>
return n: off;
};
@@ -71,11 +109,19 @@ fn fd_copy(to: file, from: file) (size | error) = {
let n = match (rt::sendfile(to, from, null, SENDFILE_MAX)) {
case let err: rt::errno =>
switch (err) {
+ case rt::EAGAIN =>
+ return errors::again;
case rt::EINVAL =>
if (sum == 0) {
return errors::unsupported;
};
- return errors::errno(err);
+ return errors::invalid;
+ case rt::ENOMEM =>
+ return errors::nomem;
+ case rt::EOVERFLOW =>
+ return errors::overflow;
+ case rt::ESPIPE =>
+ return errors::unsupported;
case =>
return errors::errno(err);
};
--
2.36.1