let readlink fln =
  let ctst = 
    compile_filter Is_link
  in
  let rec readlink_aux already_read fln = 
    let newly_read = 
      prevent_recursion already_read fln
    in
    let dirs = 
      all_upper_dir fln
    in    
      try 
        let src_link = 
          List.find ctst (List.rev dirs)
        in
        let dst_link = 
          Unix.readlink src_link 
        in
        let real_link = 
          if is_relative dst_link then
            reduce (concat (dirname src_link) dst_link)
          else
            reduce dst_link
        in
          readlink_aux newly_read (reparent src_link real_link fln)
      with Not_found ->
        fln
  in 
    readlink_aux SetFilename.empty (make_absolute (pwd ()) fln)