123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110moduleFile_kind=structtypet=Unix.file_kind=|S_REG|S_DIR|S_CHR|S_BLK|S_LNK|S_FIFO|S_SOCKmoduleOption=struct[@@@warning"-37"](* The values are constructed on the C-side *)typet=|S_REG|S_DIR|S_CHR|S_BLK|S_LNK|S_FIFO|S_SOCK|UNKNOWNletelim~none~somet=matchtwith|S_REG->some(S_REG:Unix.file_kind)|S_DIR->someS_DIR|S_CHR->someS_CHR|S_BLK->someS_BLK|S_LNK->someS_LNK|S_FIFO->someS_FIFO|S_SOCK->someS_SOCK|UNKNOWN->none()endendmoduleReaddir_result=struct[@@@warning"-37"](* The values are constructed on the C-side *)typet=|End_of_directory|Entryofstring*File_kind.Option.tendexternalreaddir_with_kind_if_available_unix:Unix.dir_handle->Readdir_result.t="caml__dune_filesystem_stubs__readdir"letreaddir_with_kind_if_available_win32:Unix.dir_handle->Readdir_result.t=fundir->(* Windows also gives us the information about file kind and it's discarded by
[readdir]. We could do better here, but the Windows code is more
complicated. (there's an additional OCaml abstraction layer) *)matchUnix.readdirdirwith|exceptionEnd_of_file->Readdir_result.End_of_directory|entry->Entry(entry,UNKNOWN)letreaddir_with_kind_if_available:Unix.dir_handle->Readdir_result.t=ifStdlib.Sys.win32thenreaddir_with_kind_if_available_win32elsereaddir_with_kind_if_available_unixletread_directory_with_kinds_exndir_path=letdir=Unix.opendirdir_pathinFun.protect~finally:(fun()->Unix.closedirdir)(fun()->letrecloopacc=matchreaddir_with_kind_if_availabledirwith|Entry(("."|".."),_)->loopacc|End_of_directory->acc|Entry(base,kind)->letkkind=loop((base,kind)::acc)inletskip()=loopaccinFile_kind.Option.elimkind~none:(fun()->matchUnix.lstat(Filename.concatdir_pathbase)with|exception_->(* File disappeared between readdir & lstat system calls. Handle
as if readdir never told us about it *)skip()|stat->kstat.st_kind)~some:kinloop[])letcatch_unix_errorfx=matchfxwith|exceptionUnix.Unix_error(error,_,_)->Errorerror|res->Okresletread_directory_with_kindsdir_path=catch_unix_errorread_directory_with_kinds_exndir_pathletread_directory_exndir_path=letdir=Unix.opendirdir_pathinFun.protect~finally:(fun()->Unix.closedirdir)(fun()->letrecloopacc=matchreaddir_with_kind_if_availabledirwith|Entry(("."|".."),_)->loopacc|End_of_directory->acc|Entry(base,_)->loop(base::acc)inloop[])letread_directorydir_path=catch_unix_errorread_directory_exndir_path