staload "libc/sys/SATS/types.sats"
staload "libc/sys/SATS/wait.sats"
staload "libc/SATS/fcntl.sats"
staload "libc/SATS/stdlib.sats" staload "libc/SATS/unistd.sats"
staload "utils/errinfo.sats"
fun errinfo_report_wloc
(loc: string): void = let
var ei: errinfo_t
val () = errinfo_set_wloc (ei, loc)
val () = fprint_errinfo (stderr_ref, ei)
val () = errinfo_clear (ei)
in
end
fun who2wc (): void = let
exception ERROR of (int)
macdef errptexit (status) = let
val () = errinfo_report_wloc (#LOCATION) in $raise ERROR (,(status))
end fun who2wc_main (): void = let
var fd1: int and fd2: int
val (pfopt | err) = pipe (fd1, fd2)
in
if err = 0 then let
prval Some_v @(pf1, pf2) = pfopt
val pid1 = fork_err ()
val ipid = int_of_pid (pid1)
val () = (case+ 0 of
| _ when ipid > 0 => let
val pid2 = fork_err ()
val ipid = int_of_pid (pid2)
val () = (case+ 0 of
| _ when ipid > 0 => let
val () = close_exn (pf1 | fd1)
val () = close_exn (pf2 | fd2)
var status: int?
in
if int_of_pid(waitpid (pid2, status, WNONE)) < 0 then errptexit (EXIT_FAILURE)
end | _ when ipid = 0 => let prval () = STDIN_FILENO_gtez ()
val (pf1_ | ()) = stdin_fildes_view_get ()
val [i:int] err = dup2 (pf1, pf1_ | fd1, STDIN_FILENO)
val () = stdin_fildes_view_set (pf1_ | )
val () = (if (err < 0) then errptexit (EXIT_FAILURE) else ()): void
val () = close_exn (pf1 | fd1)
val () = close_exn (pf2 | fd2)
val _ = execlp ("wc", "wc", "-l", null) where {
extern fun execlp
(_: string, _: string, _: string, _: ptr null): int = "#atslib_execlp"
} val () = errptexit (EXIT_FAILURE)
in
end | _ => let
val () = close_exn (pf1 | fd1)
val () = close_exn (pf2 | fd2)
in
errptexit (EXIT_FAILURE)
end ) : void var status: int?
in
if int_of_pid(waitpid (pid1, status, WNONE)) < 0 then errptexit (EXIT_FAILURE)
end | _ when ipid = 0 => let prval () = STDOUT_FILENO_gtez ()
val (pf2_ | ()) = stdout_fildes_view_get ()
val [i:int] err = dup2 (pf2, pf2_ | fd2, STDOUT_FILENO)
val () = stdout_fildes_view_set (pf2_ | )
val () = (if (err < 0) then errptexit (EXIT_FAILURE) else ()): void
val () = close_exn (pf1 | fd1)
val () = close_exn (pf2 | fd2)
val _ = execlp ("who", "who", null) where {
extern fun execlp
(_: string, _: string, _: ptr null): int = "#atslib_execlp"
} val () = errptexit (EXIT_FAILURE)
in
end | _ => let
val () = close_exn (pf1 | fd1)
val () = close_exn (pf2 | fd2)
in
errptexit (EXIT_FAILURE)
end ) : void in
end else let
prval None_v () = pfopt in errptexit (EXIT_FAILURE)
end end in
try who2wc_main () with ~ERROR (status) => exit (status)
end
implement main () = () where {
val () = who2wc ()
val () = printf ("who2wc is finished.\n", @())
}