open Unix

(*
 * Simple Unix utilities
 *)


(* If execvp fails in one of our children, it may be dangerous to leave
   the program running, since we don't know how Tk would react *)
let execvp s args =
  try 
    execvp s args
  with
    Unix_error(e, _, _) ->
       Printf.eprintf "%s\n" (Unix.error_message e);
       flush Pervasives.stderr;
       exit 1

(* Wrapping of Sys.command with arg quoting *)
let system cmd args back =
  let b = Ebuffer.create 128 in
   Ebuffer.output_string b cmd;
   List.iter (fun s ->
      	      Ebuffer.output_string b " '"; 
	      for i = 0 to String.length s - 1 do
		match s.[i] with
		  '\'' -> Ebuffer.output_string b "'\\''"
		| c -> Ebuffer.output_char b c
	      done;
	      Ebuffer.output_char b '\'')
           args;
   if back then Ebuffer.output_string b " &";
   Sys.command (Ebuffer.get b)


let write_string fd s =
  write fd s 0 (String.length s); ()

(*
 * Read a line (terminated by \n or \r\n).
 *   strips terminator !
 *)
let read_line fd =
  let rec read_rec buf bufsize offs =
    let n = Low.read fd buf offs 1 in
      if n = 0 then raise End_of_file
      else if buf.[offs] = '\n'
           then (* strips \n and possibly \r  *)
             let len = if offs >= 1 & buf.[offs-1] = '\r' then offs-1 
                       else offs in
               String.sub buf 0 len
           else let offs = succ offs in
                  if offs = bufsize 
                  then read_rec (buf ^ String.create 128) (bufsize + 128) offs
                  else read_rec buf bufsize offs in
  read_rec (String.create 128) 128 0 


let full_random_init () =
  try 
    let env = environment () in
    let vect =
      Array.append (Array.map Hashtbl.hash env)
		   [| getpid(); time(); getuid(); getgid();
		      Hashtbl.hash (getlogin()) |] in
    Random.full_init vect
  with
    _ -> ()

