let file_info ?(follow_symlink=false) path =     let stat_fun =       if follow_symlink then Lwt_unix.stat else Lwt_unix.lstat in     (* eprintf "(l)stat %s? \n%!" path; *)     Lwt.catch       Lwt.(fun () -> stat_fun path >>= fun s -> return (`Ok (`Unix_stats s)))       begin function       | Unix.Unix_error (Unix.ENOENT, cmd, arg)  -> return `Absent       | e -> fail_sys (`File_info path, `Exn e)       end     >>= fun m ->     let open Lwt_unix in     begin match m with     | `Absent -> return `Absent     | `Unix_stats stats ->       begin match stats.st_kind with       | S_DIR -> return (`Directory)       | S_REG -> return (`Regular_file (stats.st_size))       | S_LNK ->         (* eprintf "readlink %s? \n%!" path; *)         begin           catch_deferred (fun () -> lwt_unix_readlink path)           >>< begin function           | `Ok s -> return s           | `Error e -> fail (`System (`File_info path, `Exn e))           end         end         >>= fun destination ->         (* eprintf "readlink %s worked \n%!" path; *)         return (`Symlink destination)       | S_CHR -> return (`Character_device)       | S_BLK -> return (`Block_device)       | S_FIFO -> return (`Fifo)       | S_SOCK -> return (`Socket)       end     end