


## posix-process.pkg
# Compiled by:
# src/lib/std/src/standard-core.sublib# Posix-specific process support.
# This is a subpackage of the POSIX 1003.1 based
# 'Posix' package
#
# src/lib/std/src/posix-1003.1b/posix-1003-1b.pkg# An alternative higher-level unix 'spawn' interface
# is defined and implemented (respectively) in:
#
# src/lib/std/src/posix/spawn.api# src/lib/std/src/posix/spawn.pkg# A portable (cross-platform) process interface
# is defined and implemented (respectively) in:
#
# src/lib/std/src/winix/winix-process.api# src/lib/std/src/posix/winix-process.pkg### "I wanted to separate data from programs,
### because data and instructions are very different."
###
### -- Ken Thompson
### "The Hobbits named it the Shire, as the region
### of the authority of their Thain, and a district
### of well-ordered business; and there in that
### pleasant corner of the world they plied their
### well-ordered business of living, and they heeded
### less and less the world outside where dark things
### moved, until they came to think that peace and
### plenty were the rule in Middle-earth and the right
### of all sensible folk.
###
### "They forgot or ignored what little they had
### ever known of the Guardians, and of the labours of
### those that made possible the long peace of the Shire.
### They were, in fact, sheltered, but they had ceased
### to remember it."
###
### -- J R R Tolkien
stipulate
package host_unt= host_unt_guts; # host_unt_guts is from src/lib/std/src/bind-sysword-32.pkg package u1b = one_byte_unt_guts; # one_byte_unt_guts is from src/lib/std/src/one-byte-unt-guts.pkg package time = time_guts; # time_guts is from src/lib/std/src/time-guts.pkg package int = int_guts; # int_guts is from src/lib/std/src/bind-int-32.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 posix_process {
#
package sig = posix_signal; # posix_signal is from src/lib/std/src/posix-1003.1b/posix-signal.pkg Unt = host_unt::Unt;
Sy_Int = host_int::Int;
Signal = sig::Signal;
Process_Id = PID Sy_Int;
fun pid_to_unt (PID i)
=
host_unt::from_int i;
fun unt_to_pid w
=
PID (host_unt::to_int w);
fun cfun fun_name
=
ci::find_c_function { lib_name => "posix_process", fun_name }; # "posix_process" def in src/c/lib/posix-process/cfun-list.h
my osval: String -> Sy_Int
=
cfun "osval"; # osval def in src/c/lib/posix-process/osval.c
w_osval = host_unt::from_int o osval;
my sysconf: String -> host_unt::Unt
= # "posix_process_environment" def in src/c/lib/posix-process-environment/cfun-list.h
ci::find_c_function { lib_name => "posix_process_environment", fun_name => "sysconf" }; # sysconf def in src/c/lib/posix-process-environment/sysconf.c
my fork' : Void -> Sy_Int
=
cfun "fork"; # fork def in src/c/lib/posix-process/fork.c
fun fork ()
=
case (fork' ())
#
0 => NULL;
child_pid => THE (PID child_pid);
esac;
#
# This is essentially the unix-level fork().
# For a higher-level fork() see fork_process() in
#
# src/lib/std/src/posix/spawn.api # src/lib/std/src/posix/spawn.pkg fun exec (x: (String, List( String )) ) : X = cfun "exec" x; # exec def in src/c/lib/posix-process/exec.c
fun exece (x: (String, List( String ), List( String )) ) : X = cfun "exece" x; # exece def in src/c/lib/posix-process/exece.c
fun execp (x: (String, List( String )) ): X = cfun "execp" x; # execp def in src/c/lib/posix-process/execp.c
Waitpid_Arg
#
= W_ANY_CHILD
| W_CHILD Process_Id
| W_GROUP Process_Id
| W_SAME_GROUP
;
Killpid_Arg
#
= K_PROC Process_Id
| K_GROUP Process_Id
| K_SAME_GROUP
;
Exit_Status
#
= W_EXITED
| W_EXITSTATUS u1b::Unt
| W_SIGNALED Signal
| W_STOPPED Signal
;
# (pid', status, status_val) = waitpid' (pid, options)
my waitpid' : (Sy_Int, Unt) -> (Sy_Int, Sy_Int, Sy_Int)
=
cfun "waitpid"; # waidpid def in src/c/lib/posix-process/waitpid.c
fun arg_to_int W_ANY_CHILD => -1;
arg_to_int (W_CHILD (PID pid)) => pid;
arg_to_int (W_SAME_GROUP) => 0;
arg_to_int (W_GROUP (PID pid)) => -pid;
end;
# The exit status from wait is encoded as a pair of integers.
# If the first integer is 0, the child exited normally, and
# the second integer gives its exit value.
# If the first integer is 1, the child exited due to an uncaught
# signal, and the second integer gives the signal value.
# Otherwise, the child is stopped and the second integer
# gives the signal value that caused the child to stop.
fun make_exit_status (0, 0) => W_EXITED;
make_exit_status (0, v) => W_EXITSTATUS (u1b::from_int v);
make_exit_status (1, s) => W_SIGNALED (sig::SIGNAL s);
make_exit_status (_, s) => W_STOPPED (sig::SIGNAL s);
end;
fun from_status s
=
make_exit_status (int::quot (s, 256), int::rem (s, 256));
package w {
stipulate
package w0 = bit_flags_g ();
herein
include w0;
end;
untraced
=
from_unt ({ sysconf "JOB_CONTROL"; w_osval "WUNTRACED";}
except _ = 0u0);
};
wnohang = w::from_unt (w_osval "WNOHANG");
fun waitpid (arg, flags)
=
{ (waitpid' (arg_to_int arg, w::to_unt (w::flags flags)))
->
(pid, status, sv);
(PID pid, make_exit_status (status, sv));
};
fun waitpid_nh (arg, flags) # "_nh" == "nohang"
=
case (waitpid' (arg_to_int arg, w::to_unt (w::flags (wnohang ! flags))))
#
(0, _, _) => NULL;
(pid, status, sv) => THE (PID pid, make_exit_status (status, sv));
esac;
fun wait ()
=
waitpid (W_ANY_CHILD,[]);
fun exit (x: u1b::Unt) : X
=
cfun "exit" x; # exit def in src/c/lib/posix-process/exit.c
my kill' : (Sy_Int, Sy_Int) -> Void
=
cfun "kill"; # kill def in src/c/lib/posix-process/kill.c
fun kill (K_PROC (PID pid), sig::SIGNAL s) => kill' (pid, s); # "Kill me to-morrow; let me live to-night!" -- William Shakespeare, "Othello"
kill (K_SAME_GROUP, sig::SIGNAL s) => kill' (-1, s);
kill (K_GROUP (PID pid), sig::SIGNAL s) => kill' (-pid, s);
end;
stipulate
fun wrap f t
=
time::from_seconds (int::to_multiword_int (f(int::from_multiword_int (time::to_seconds t))));
my alarm' : Int -> Int = cfun "alarm";
my sleep' : Int -> Int = cfun "sleep"; # sleep def in src/c/lib/posix-process/sleep.c
#
# From the manpage:
#
# BUGS
# sleep() may be implemented using SIGALRM; mixing calls to alarm(2) and
# sleep() is a bad idea.
herein
alarm = wrap alarm';
sleep = wrap sleep';
#
# Note that you can sleep with sub-second resolution
# via winix::process::sleep or winix::io::poll.
end;
my pause: Void -> Void
=
cfun "pause"; # pause def in src/c/lib/posix-process/pause.c
}; # package posix_process
end;


