Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file fs.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372openLwt.Infixlet(>>?)=Lwt_result.(>>=)let(>|?)=Lwt_result.(>|=)letsrc=Logs.Src.create"git-unix.fs"~doc:"logs unix file-system's event"moduleLog=(valLogs.src_logsrc:Logs.LOG)typet=unittypeerror=Fpath.t*[`Statofstring|`Unlinkofstring|`Rmdirofstring|`Readdirofstring|`Pathofstring|`Getcwdofstring|`Openofstring|`Writeofstring|`Readofstring|`Closeofstring|`Renameofstring|`Mkdirofstring|`Mmapofstring](* XXX(samoht): better error messages in plain english *)letpp_errorppf(path,e)=letppppf=function|`Staterr->Fmt.pfppf"(`Stat %s)"err|`Unlinkerr->Fmt.pfppf"(`Unlink %s)"err|`Rmdirerr->Fmt.pfppf"(`Rmdir %s)"err|`Readdirerr->Fmt.pfppf"(`Readdir %s)"err|`Patherr->Fmt.pfppf"(`Path %s)"err|`Getcwderr->Fmt.pfppf"(`Getcwd %s)"err|`Mkdirerr->Fmt.pfppf"(`Mkdir %s)"err|`Openerr->Fmt.pfppf"(`Open %s)"err|`Writeerr->Fmt.pfppf"(`Write %s)"err|`Readerr->Fmt.pfppf"(`Read %s)"err|`Closeerr->Fmt.pfppf"(`Close %s)"err|`Renameerr->Fmt.pfppf"(`Rename %s)"err|`Mmaperr->Fmt.pfppf"(`Mmap %s)"errinFmt.pfppf"Error while processing %a: %a"Fpath.pppathppeleterrpathx:(_,error)resultLwt.t=Lwt.return(Error(path,x))leterr_unlinkdire=errdir(`Unlink(Unix.error_messagee))leterr_readdirdire=errdir(`Readdir(Unix.error_messagee))leterr_mkdirdire=errdir(`Mkdir(Unix.error_messagee))leterr_rmdirdire=errdir(`Rmdir(Unix.error_messagee))leterr_getcwddirfmt=Fmt.kstrf(funs->errdir(`Getcwds))fmtleterr_openfilee=errfile(`Open(Unix.error_messagee))leterr_writefilee=errfile(`Write(Unix.error_messagee))leterr_readfilee=errfile(`Read(Unix.error_messagee))leterr_closefilee=errfile(`Close(Unix.error_messagee))leterr_statfilee=errfile(`Stat(Unix.error_messagee))leterr_renamefilee=errfile(`Rename(Unix.error_messagee))leterr_deletefilee=errfile(`Unlink(Unix.error_messagee))leterr_mmapfilee=errfile(`Mmap(Unix.error_messagee))letexpected_unix_errorexn=Fmt.kstrfinvalid_arg"Expected an unix error: %a."Fmt.exnexnletopen_pool=Lwt_pool.create200(fun()->Lwt.return())letrecprotect?(n=0)nameerrf=letsleep_t=0.001inifn>=10_000thenLwt.fail_with"timeout"elseLwt.catch(fun()->f()>|=funx->Okx)(fune->letopenUnixinletlog_err()=Log.debug(funl->l"[%s] error: %a"nameFmt.exne)inmatchewith|Unix_error(EINTR,_,_)->Lwt.return(Error`EAGAIN)|Unix_error(EACCES,_,_)whenSys.win32->lets=sleep_t*.(1.+.(Random.float(floatn)**2.))inLog.debug(funl->l"sleeping for %.2fs"s);Lwt_unix.sleeps>|=fun()->Error`EAGAIN|Unix_error(e,_,_)->(erre>|=function|Ok_asx->x|Errore->log_err();Error(`Ee))|exn->log_err();expected_unix_errorexn)>>=function|Ok_asx->Lwt.returnx|Error`EAGAIN->protect~n:(n+1)nameerrf|Error(`Ee)->Lwt.return(Errore)letis_file_tpath=leterr=function|Unix.ENOENT->Lwt.return(Okfalse)|e->err_statpatheinprotect"is_file"err@@fun()->Lwt_unix.stat(Fpath.to_stringpath)>|=funstat->stat.Lwt_unix.st_kind=Lwt_unix.S_REGletis_dir_tpath=leterr=function|Unix.ENOENT->Lwt.return(Okfalse)|e->err_statpatheinprotect"is_dir"err@@fun()->Lwt_unix.stat(Fpath.to_stringpath)>|=funstat->stat.Lwt_unix.st_kind=Lwt_unix.S_DIRletresult_mapfa=matchawithOkx->fx|Errorerr->ErrorerrmoduleDir=structtypenonrect=ttypenonrecerror=errorletcreatetdir=letmode=0o755inletmkdird=leterr=function|Unix.EEXIST->Lwt.return(Ok())|e->err_mkdirdeinprotect"Dir.create"err@@fun()->Log.debug(funl->l"create a new directory %a."Fpath.ppd);Lwt_unix.mkdir(Fpath.to_stringd)modeinis_dirtdir>>=function|Error_ase->Lwt.returne|Oktrue->Lwt.return(Okfalse)|Okfalse->letrecdirs_to_createpacc=is_dirtp>>=function|Error_ase->Lwt.returne|Oktrue->Lwt.return(Okacc)|Okfalse->dirs_to_create(Fpath.parentp)(p::acc)inletreccreate_themdirs()=matchdirswith|[]->Lwt.return(Ok())|dir::dirs->(mkdirdir>>=function|Error_aserr->Lwt.returnerr|Ok()->create_themdirs())indirs_to_createdir[]>>=(function|Okdirs->create_themdirs()|Error_aserr->Lwt.returnerr)>|=result_map(fun_->Oktrue)letkindpath=letopenUnixinleterr=function|ENOENT->Lwt.return(Ok`None)|e->err_statpatheinprotect"Dir.kind"err(fun()->Lwt_unix.stat(Fpath.to_stringpath)>|=funstat->matchstat.Lwt_unix.st_kindwithLwt_unix.S_DIR->`Dir|_->`File)letexists_tpath=kindpath>|?function`Dir->true|_->falseletreaddirdir=protect"Dir.readdir"(err_readdirdir)(fun()->Lwt_unix.files_of_directory(Fpath.to_stringdir)|>Lwt_stream.filter(function"."|".."->false|_->true)|>Lwt_stream.mapFpath.v|>Lwt_stream.to_list)letrecdelete_filekfile=kindfile>>?function|`None->Lwt.return(Ok())|`Dir->delete_dirkfile|`File->letopenUnixinleterr=function|ENOENT->Lwt.return(Ok())|e->err_unlinkfileeinprotect"Dir.delete_file"err(fun()->Log.debug(funl->l"unlink %a"Fpath.ppfile);Lwt_unix.unlink(Fpath.to_stringfile))>>=kanddelete_filesk=function|[]->k(Ok())|file::t->delete_file(functionOk()->delete_fileskt|Error_ase->Lwt.returne)fileanddelete_dirkdir:(unit,error)resultLwt.t=readdirdir>>?funfiles->letfiles=List.map(funx->Fpath.(dir//x))filesinletrmdir=function|Error_ase->Lwt.returne|Ok()->protect"Dir.delete_dir"(err_rmdirdir)(fun()->Log.debug(funl->l"rmdir %a"Fpath.ppdir);Lwt_unix.rmdir(Fpath.to_stringdir))>>=kindelete_filesrmdirfilesletdelete_tdir=Log.debug(funl->l"Dir.delete %a"Fpath.ppdir);delete_dirLwt.returndirletcontents_t?(rel=false)dir=Log.debug(funl->l"Dir.contents %a"Fpath.ppdir);letrecauxacc=function|[]->acc|h::t->aux((ifrelthenhelseFpath.(dir//h))::acc)tinreaddirdir>|?aux[]letreccurrentt=Lwt.try_bind(fun()->Unix.getcwd()|>Lwt.return)(funp->matchFpath.of_stringpwith|Okdir->ifFpath.is_absdirthenLwt.return(Okdir)elseerr_getcwddir"getcwd(3) returned a relative path: (%s)"(Fpath.to_stringdir)|Error_->err_getcwdFpath.(v"CWD")"get current working directory: cannot parse it to a path (%S)"p)(function|Unix.Unix_error(Unix.EINTR,_,_)->currentt|Unix.Unix_error(e,_,_)->err_getcwdFpath.(v"CWD")"get current working directory: %s"(Unix.error_messagee)|exn->expected_unix_errorexn)endmoduleFile=structtypenonrect=ttypenonrecerror=errortype'afd={path:Fpath.t;fd:Lwt_unix.file_descr}constraint'a=[<`Read|`Write]letopen_w_tpath=letmode=0o644inleterre=err_openpatheinLwt_pool.useopen_pool@@fun()->protect"File.open_w"err@@fun()->Lwt_unix.openfile(Fpath.to_stringpath)[Lwt_unix.O_CREAT;Lwt_unix.O_WRONLY;Lwt_unix.O_TRUNC;Lwt_unix.O_NONBLOCK]mode>|=funfd->({fd;path}:>[`Write]fd)letopen_r_tpath=letmode=0o400inleterre=err_openpatheinLwt_pool.useopen_pool@@fun()->protect"File.open_r"err@@fun()->Lwt_unix.openfile(Fpath.to_stringpath)[Lwt_unix.O_RDONLY]mode>|=funfd->({fd;path}:>[`Read]fd)letwriteraw?(off=0)?(len=Cstruct.lenraw){fd;path}=leterre=err_writepatheinprotect"File.write"err@@fun()->Lwt_bytes.writefd(Cstruct.to_bigarrayraw)offlenletreadraw?(off=0)?(len=Cstruct.lenraw){fd;path}=leterre=err_readpatheinprotect"File.read"err@@fun()->Lwt_bytes.readfd(Cstruct.to_bigarrayraw)offlenletclose{fd;path}=leterre=err_closepatheinprotect"File.close"err@@fun()->Lwt_unix.closefdletexists_tpath=leterr=function|Unix.ENOENT->Lwt.return(Okfalse)|e->err_statpatheinprotect"File.exists"err@@fun()->Lwt_unix.stat(Fpath.to_stringpath)>|=funstat->stat.Lwt_unix.st_kind=Lwt_unix.S_REGletmove_tpath_apath_b=leterre=err_renamepath_aeinprotect"File.move"err@@fun()->Lwt_unix.rename(Fpath.to_stringpath_a)(Fpath.to_stringpath_b)letdelete_tpath=leterr=function|Unix.ENOENT->Lwt.return(Ok())|e->err_deletepatheinprotect"File.delete"err@@fun()->Lwt_unix.unlink(Fpath.to_stringpath)endmoduleMapper=structtypenonrect=ttypenonrecerror=errorletpp_error=pp_errortypefd={fd:Lwt_unix.file_descr;path:Fpath.t}letlength{fd;path}=leterre=err_statpatheinprotect"Mapper.length"err@@fun()->Lwt_unix.LargeFile.fstatfd>|=funfstat->fstat.Unix.LargeFile.st_sizeletopenfile_tpath=leterre=err_openpatheinprotect"Mapper.openfile"err@@fun()->Lwt_unix.openfile(Fpath.to_stringpath)[Lwt_unix.O_RDONLY]0o644>|=funfd->{fd;path}letclose{fd;path}=leterre=err_closepatheinprotect"Mapper.close"err@@fun()->Lwt_unix.closefdletmapt?poslen=lengtht>>=function|Errorerr->Lwt.return(Errorerr)|Okmax->(letmax=matchposwithSomepos->Int64.submaxpos|None->maxinleterre=err_mmapt.patheinletfd=Lwt_unix.unix_file_descrt.fdinletsize=Int64.to_int(min(Int64.of_intlen)max)inprotect"Mapper.map"err@@fun()->tryletrs=Mmap.V1.map_filefd?posBigarray.CharBigarray.C_layoutfalse[|size|]inletrs=Bigarray.array1_of_genarrayrsinLwt.return(Cstruct.of_bigarrayrs)withe->Lwt.faile)endletis_dir=is_dirletis_file=is_filelethas_global_checkout=truelethas_global_watches=true