let readlinkcmd =
  let cache = Hashtbl.create 32 in
  fun x ->
    try Hashtbl.find cache x
    with Not_found ->
      run_and_open (Printf.sprintf "readlink %s" (Filename.quote x)) begin fun ic ->
        let y = String.chomp (input_line ic) in
        Hashtbl.replace cache x y; y
      end