95 lines · 2.8 KB · Standard ML
RawDownload
(* Unix -- SML Basis Library *) (* sestoft@dina.kvl.dk 1999-11-07 version 0.2 *) (* Type safety depends on the representation of TextIO.instream and   TextIO.outstream, and of Process.status *) structure Unix :> Unix =struct type signal = Signal.signal type proc = { syspid : int, ins : TextIO.instream, outs : TextIO.outstream } local     open Dynlib    val hdl  = dlopen {lib = "libmunix.so",		       flag = RTLD_LAZY, global = false}    val symb = Dynlib.dlsym hdl    fun app1 name = Dynlib.app1 (symb ("unix_"^name))    fun app2 name = Dynlib.app2 (symb ("unix_"^name))    fun app3 name = Dynlib.app3 (symb ("unix_"^name))    fun app4 name = Dynlib.app4 (symb ("unix_"^name))    fun app5 name = Dynlib.app5 (symb ("unix_"^name)) (* Caml Light "channels" *) prim_type in_channel and out_channel;prim_val open_descriptor_in  : int -> in_channel  = 1 "open_descriptor";prim_val open_descriptor_out : int -> out_channel = 1 "open_descriptor"; fun raiseIo fcn nam exn =     raise Io {function = "Unix." ^ fcn, name = nam, cause = exn}; (* From Caml Light "channels" to SML instreams and outstreams: *) fun openInPipe fcn infd : TextIO.instream =    Obj.magic (ref {closed=false, 		    ic=open_descriptor_in infd, 		    name = "<inpipe>"})    handle exn as SysErr _ => raiseIo fcn "<inpipe>" exn; fun openOutPipe fcn outfd : TextIO.outstream =    Obj.magic (ref {closed=false, 		    oc=open_descriptor_out outfd, 		    name="<outpipe>"})    handle exn as SysErr _ => raiseIo fcn "<outpipe>" exn; in  val kill_ : int -> int -> unit = app2 "kill" fun killpid (s : signal) (syspid : int) : unit =     kill_ syspid (Word.toInt (Signal.toWord s)) fun kill ({ syspid, ... } : proc, s : signal) : unit =     killpid s syspid    handle Fail s => raise Fail ("Unix.kill: " ^ s) val execute_ : string -> string vector -> string vector option               -> int * int * int = app3 "execute" fun executewrap fcn cmd args envOpt : proc =    let val argvec = Vector.fromList (cmd :: args)	val envvec = Option.map Vector.fromList envOpt	val (syspid, infd, outfd) = execute_ cmd argvec envvec	val ins  = openInPipe fcn infd	val outs = openOutPipe fcn outfd    in	{ syspid = syspid, ins = ins, outs = outs }     end    handle Fail s => raise Fail ("Unix." ^ fcn ^ ": " ^ s) fun executeInEnv (cmd, args, env) : proc =     executewrap "executeInEnv" cmd args (SOME env) fun execute (cmd, args) : proc =    executewrap "execute" cmd args NONE fun streamsOf ({ syspid, ins, outs } : proc)     : TextIO.instream * TextIO.outstream = (ins, outs) val waitpid_ : int -> int = app1 "waitpid" fun reap ({ syspid, ins, outs } : proc) : Process.status =     let val status_ = waitpid_ syspid : int    in 	TextIO.closeIn ins; 	TextIO.closeOut outs; 	Obj.magic status_     end    handle Fail s => raise Fail ("Unix.reap: " ^ s)endend