


## winix-io.pkg
# Compiled by:
# src/lib/std/src/standard-core.sublib# A subpackage of winix_guts:
#
# src/lib/std/src/posix/winix-guts.pkgstipulate
package unt = unt_guts; # unt_guts is from src/lib/std/src/bind-unt-guts.pkg package i1w = one_word_int_guts; # one_word_int_guts is from src/lib/std/src/one-word-int-guts.pkg package int = int_guts; # int_guts is from src/lib/std/src/bind-int-32.pkg package psx = posix_1003_1b; # posix_1003_1b is from src/lib/std/src/posix-1003.1b/posix-1003-1b.pkg package ci = mythryl_callable_c_library_interface; # mythryl_callable_c_library_interface is from src/lib/std/src/unsafe/mythryl-callable-c-library-interface.pkgherein
package winix_io
: (weak) Winix_Io # Winix_Io is from src/lib/std/src/winix/winix-io.api {
# An Io_Descriptor is an abstract descriptor
# for an OS chunk that supports I/O
# (e.g., file, tty device, socket, ...).
#
Io_Descriptor
=
winix_types::io::Io_Descriptor;
Io_Descriptor_Kind
=
KIND String;
# Return a hash value for the I/O descriptor:
#
fun hash fd
=
unt::from_int (winix_types::io::iod_to_fd fd);
# Compare two I/O descriptors:
#
fun compare (fd1, fd2)
=
int::compare
( winix_types::io::iod_to_fd fd1,
winix_types::io::iod_to_fd fd2
);
package kind {
#
file = KIND "FILE";
dir = KIND "DIR";
symlink = KIND "LINK";
tty = KIND "TTY";
pipe = KIND "PIPE";
socket = KIND "SOCKET";
device = KIND "DEV";
};
# Return the kind of I/O descriptor:
fun kind io_descriptor
=
{
i = winix_types::io::iod_to_fd io_descriptor;
fd = psx::int_to_fd i;
stat = psx::fstat fd;
if (psx::stat::is_file stat) kind::file;
elif (psx::stat::is_directory stat) kind::dir;
elif (psx::stat::is_char_dev stat) kind::tty;
elif (psx::stat::is_block_dev stat) kind::device; # ??
elif (psx::stat::is_symlink stat) kind::symlink;
elif (psx::stat::is_pipe stat) kind::pipe;
elif (psx::stat::is_socket stat) kind::socket;
else KIND "UNKNOWN";
fi;
};
Wait_Request
=
{ io_descriptor: Io_Descriptor,
readable: Bool,
writable: Bool,
oobdable: Bool # Out-Of-Band-Data available on socket or PTY.
};
# Public representation of a polling operation on
# an I/O descriptor.
Wait_Result = Wait_Request; # A synonym to clarify declarations.
exception BAD_WAIT_REQUEST;
# 'wait_for_io_opportunity' tests which fds
# (of a given set)
# are ready for I/O:
#
stipulate
poll' = ci::find_c_function { lib_name => "posix_os", fun_name => "poll" } # poll def in src/c/lib/posix-os/poll.c
:
( (List( (Int, Unt) ), # (fd, flags) pairs where 'flags' has three bits: readable/writable/oobdable
Null_Or( (i1w::Int, Int) )) # NULL or (THE timeout), where 'timeout' is a (seconds, microseconds) pair.
)
->
List( (Int, Unt) ) # Result list of (fd, flags) pairs, where 'flags' is nonzero (if zero, the pair is dropped from the result list).
;
fun conditional_bit_or (FALSE, _, accumulator) => accumulator;
conditional_bit_or (TRUE, bit, accumulator) => unt::bitwise_or (accumulator, bit);
end;
fun test (word, bit)
=
(unt::bitwise_and (word, bit) != 0u0);
readable_bit = 0u1;
writable_bit = 0u2;
oobdable_bit = 0u4;
fun from_wait_request { io_descriptor, readable, writable, oobdable }
=
( winix_types::io::iod_to_fd io_descriptor,
conditional_bit_or
(
readable,
readable_bit,
conditional_bit_or
(
writable,
writable_bit,
conditional_bit_or
(
oobdable,
oobdable_bit,
0u0
)
)
)
);
fun to_poll_result (fd, w)
=
{ io_descriptor => winix_types::io::int_to_iod fd,
readable => test (w, readable_bit),
writable => test (w, writable_bit),
oobdable => test (w, oobdable_bit)
};
herein
fun wait_for_io_opportunity { wait_requests, timeout }
=
{
timeout
=
case timeout
#
THE time
=>
{
usec = time_guts::to_microseconds time;
#
(multiword_int_guts::div_mod (usec, 1000000))
->
(sec, usec);
THE (i1w::from_multiword_int sec, int::from_multiword_int usec);
};
NULL =>
{
NULL;
};
esac;
raw_results = poll' (list::map from_wait_request wait_requests, timeout);
list::map
to_poll_result
raw_results;
};
select = wait_for_io_opportunity;
#
# Deprecated synonym for 'wait_for_io_opportunity', mainly so
# that unix folks looking for 'select' in the function index
# will get led here.
end; # stipulate
}; # package winix_io
end;


