123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319moduleUnix_error=structtypet=Unix.error(* CR-someday amokhov: It would be nice to derive this instead. For now let's
trust I haven't messed this up. *)letequal(x:t)(y:t)=matchx,ywith|E2BIG,E2BIG->true|E2BIG,_|_,E2BIG->false|EACCES,EACCES->true|EACCES,_|_,EACCES->false|EAGAIN,EAGAIN->true|EAGAIN,_|_,EAGAIN->false|EBADF,EBADF->true|EBADF,_|_,EBADF->false|EBUSY,EBUSY->true|EBUSY,_|_,EBUSY->false|ECHILD,ECHILD->true|ECHILD,_|_,ECHILD->false|EDEADLK,EDEADLK->true|EDEADLK,_|_,EDEADLK->false|EDOM,EDOM->true|EDOM,_|_,EDOM->false|EEXIST,EEXIST->true|EEXIST,_|_,EEXIST->false|EFAULT,EFAULT->true|EFAULT,_|_,EFAULT->false|EFBIG,EFBIG->true|EFBIG,_|_,EFBIG->false|EINTR,EINTR->true|EINTR,_|_,EINTR->false|EINVAL,EINVAL->true|EINVAL,_|_,EINVAL->false|EIO,EIO->true|EIO,_|_,EIO->false|EISDIR,EISDIR->true|EISDIR,_|_,EISDIR->false|EMFILE,EMFILE->true|EMFILE,_|_,EMFILE->false|EMLINK,EMLINK->true|EMLINK,_|_,EMLINK->false|ENAMETOOLONG,ENAMETOOLONG->true|ENAMETOOLONG,_|_,ENAMETOOLONG->false|ENFILE,ENFILE->true|ENFILE,_|_,ENFILE->false|ENODEV,ENODEV->true|ENODEV,_|_,ENODEV->false|ENOENT,ENOENT->true|ENOENT,_|_,ENOENT->false|ENOEXEC,ENOEXEC->true|ENOEXEC,_|_,ENOEXEC->false|ENOLCK,ENOLCK->true|ENOLCK,_|_,ENOLCK->false|ENOMEM,ENOMEM->true|ENOMEM,_|_,ENOMEM->false|ENOSPC,ENOSPC->true|ENOSPC,_|_,ENOSPC->false|ENOSYS,ENOSYS->true|ENOSYS,_|_,ENOSYS->false|ENOTDIR,ENOTDIR->true|ENOTDIR,_|_,ENOTDIR->false|ENOTEMPTY,ENOTEMPTY->true|ENOTEMPTY,_|_,ENOTEMPTY->false|ENOTTY,ENOTTY->true|ENOTTY,_|_,ENOTTY->false|ENXIO,ENXIO->true|ENXIO,_|_,ENXIO->false|EPERM,EPERM->true|EPERM,_|_,EPERM->false|EPIPE,EPIPE->true|EPIPE,_|_,EPIPE->false|ERANGE,ERANGE->true|ERANGE,_|_,ERANGE->false|EROFS,EROFS->true|EROFS,_|_,EROFS->false|ESPIPE,ESPIPE->true|ESPIPE,_|_,ESPIPE->false|ESRCH,ESRCH->true|ESRCH,_|_,ESRCH->false|EXDEV,EXDEV->true|EXDEV,_|_,EXDEV->false|EWOULDBLOCK,EWOULDBLOCK->true|EWOULDBLOCK,_|_,EWOULDBLOCK->false|EINPROGRESS,EINPROGRESS->true|EINPROGRESS,_|_,EINPROGRESS->false|EALREADY,EALREADY->true|EALREADY,_|_,EALREADY->false|ENOTSOCK,ENOTSOCK->true|ENOTSOCK,_|_,ENOTSOCK->false|EDESTADDRREQ,EDESTADDRREQ->true|EDESTADDRREQ,_|_,EDESTADDRREQ->false|EMSGSIZE,EMSGSIZE->true|EMSGSIZE,_|_,EMSGSIZE->false|EPROTOTYPE,EPROTOTYPE->true|EPROTOTYPE,_|_,EPROTOTYPE->false|ENOPROTOOPT,ENOPROTOOPT->true|ENOPROTOOPT,_|_,ENOPROTOOPT->false|EPROTONOSUPPORT,EPROTONOSUPPORT->true|EPROTONOSUPPORT,_|_,EPROTONOSUPPORT->false|ESOCKTNOSUPPORT,ESOCKTNOSUPPORT->true|ESOCKTNOSUPPORT,_|_,ESOCKTNOSUPPORT->false|EOPNOTSUPP,EOPNOTSUPP->true|EOPNOTSUPP,_|_,EOPNOTSUPP->false|EPFNOSUPPORT,EPFNOSUPPORT->true|EPFNOSUPPORT,_|_,EPFNOSUPPORT->false|EAFNOSUPPORT,EAFNOSUPPORT->true|EAFNOSUPPORT,_|_,EAFNOSUPPORT->false|EADDRINUSE,EADDRINUSE->true|EADDRINUSE,_|_,EADDRINUSE->false|EADDRNOTAVAIL,EADDRNOTAVAIL->true|EADDRNOTAVAIL,_|_,EADDRNOTAVAIL->false|ENETDOWN,ENETDOWN->true|ENETDOWN,_|_,ENETDOWN->false|ENETUNREACH,ENETUNREACH->true|ENETUNREACH,_|_,ENETUNREACH->false|ENETRESET,ENETRESET->true|ENETRESET,_|_,ENETRESET->false|ECONNABORTED,ECONNABORTED->true|ECONNABORTED,_|_,ECONNABORTED->false|ECONNRESET,ECONNRESET->true|ECONNRESET,_|_,ECONNRESET->false|ENOBUFS,ENOBUFS->true|ENOBUFS,_|_,ENOBUFS->false|EISCONN,EISCONN->true|EISCONN,_|_,EISCONN->false|ENOTCONN,ENOTCONN->true|ENOTCONN,_|_,ENOTCONN->false|ESHUTDOWN,ESHUTDOWN->true|ESHUTDOWN,_|_,ESHUTDOWN->false|ETOOMANYREFS,ETOOMANYREFS->true|ETOOMANYREFS,_|_,ETOOMANYREFS->false|ETIMEDOUT,ETIMEDOUT->true|ETIMEDOUT,_|_,ETIMEDOUT->false|ECONNREFUSED,ECONNREFUSED->true|ECONNREFUSED,_|_,ECONNREFUSED->false|EHOSTDOWN,EHOSTDOWN->true|EHOSTDOWN,_|_,EHOSTDOWN->false|EHOSTUNREACH,EHOSTUNREACH->true|EHOSTUNREACH,_|_,EHOSTUNREACH->false|ELOOP,ELOOP->true|ELOOP,_|_,ELOOP->false|EOVERFLOW,EOVERFLOW->true|EOVERFLOW,_|_,EOVERFLOW->false|EUNKNOWNERRx,EUNKNOWNERRy->Int.equalxy;;moduleDetailed=structtypenonrect=t*string*stringletraise(e,x,y)=raise(Unix.Unix_error(e,x,y))letcreateerror~syscall~arg=error,syscall,argletcatchfx=matchfxwith|res->Okres|exceptionUnix.Unix_error(error,syscall,arg)->Error(createerror~syscall~arg);;letequal(a1,b1,c1)(a2,b2,c2)=equala1a2&&String.equalb1b2&&String.equalc1c2;;letto_string_hum(error,syscall,arg)=Format.sprintf"%s(%s): %s"syscallarg(Unix.error_messageerror);;endendmoduleFile_kind=structtypet=Unix.file_kind=|S_REG|S_DIR|S_CHR|S_BLK|S_LNK|S_FIFO|S_SOCKletto_string=function|S_REG->"S_REG"|S_DIR->"S_DIR"|S_CHR->"S_CHR"|S_BLK->"S_BLK"|S_LNK->"S_LNK"|S_FIFO->"S_FIFO"|S_SOCK->"S_SOCK";;letto_string_hum=function|S_REG->"regular file"|S_DIR->"directory"|S_CHR->"character device"|S_BLK->"block device"|S_LNK->"symbolic link"|S_FIFO->"named pipe"|S_SOCK->"socket";;letequalxy=matchx,ywith|S_REG,S_REG->true|S_REG,_|_,S_REG->false|S_DIR,S_DIR->true|S_DIR,_|_,S_DIR->false|S_CHR,S_CHR->true|S_CHR,_|_,S_CHR->false|S_BLK,S_BLK->true|S_BLK,_|_,S_BLK->false|S_LNK,S_LNK->true|S_LNK,_|_,S_LNK->false|S_FIFO,S_FIFO->true|S_FIFO,_|_,S_FIFO->false|S_SOCK,S_SOCK->true;;moduleOption=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_unix;;letread_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|exceptionUnix.Unix_error_->(* File disappeared between readdir & lstat system calls. Handle
as if readdir never told us about it *)skip()|stat->kstat.st_kind)~some:kinloop[]);;letread_directory_with_kindsdir_path=Unix_error.Detailed.catchread_directory_with_kinds_exndir_path;;letread_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=Unix_error.Detailed.catchread_directory_exndir_path