let watch_and_insert ?(on_end=fun() -> ()) ic insert =
  let gchan = GMain.Io.channel_of_descr (Unix.descr_of_in_channel ic) in
  let buf_size = 512 in
  let buf = String.create buf_size in
  let rec f_read l =
    try
      if List.mem `IN l then
        begin
          let n = GMain.Io.read gchan ~buf ~pos: 0 ~len: buf_size in
          (
           (
            try insert (String.sub buf 0 n)
            with _ -> ()
           );
           (n < buf_size) || (f_read l)
          )
        end
      else
        if List.mem `HUP l then
          (
           on_end ();
           false
          )
        else
          true
    with
      e -> prerr_endline (Printexc.to_string e); true
  in
  GMain.Io.add_watch
    ~prio: 0
    ~cond: [ `IN ; `HUP ]
    ~callback: f_read gchan