123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328[%%import"config.h"]open!CoremoduleSyscall_result=Unix.Syscall_resultopenBigarrayincludeCore_kernel.BigstringexceptionIOErrorofint*exn[@@derivingsexp]externalinit_stub:unit->unit="bigstring_init_stub"let()=Callback.register_exception"Bigstring.End_of_file"End_of_file;Callback.register_exception"Bigstring.IOError"(IOError(0,Exit));init_stub()letcheck_min_len~loc~len=function|None->0|Somemin_len->ifmin_len>lenthen(letmsg=sprintf"%s: min_len (%d) > len (%d)"locmin_lenlenininvalid_argmsg);ifmin_len<0then(letmsg=sprintf"%s: min_len (%d) < 0"locmin_lenininvalid_argmsg);min_len(* Input functions *)externalunsafe_read:min_len:int->Unix.File_descr.t->pos:int->len:int->t->int="bigstring_read_stub"letread?min_lenfd?(pos=0)?lenbstr=letlen=get_opt_lenbstr~posleninletloc="read"incheck_args~loc~pos~lenbstr;letmin_len=check_min_len~loc~lenmin_leninunsafe_read~min_lenfd~pos~lenbstrexternalunsafe_pread_assume_fd_is_nonblocking_stub:Unix.File_descr.t->offset:int->pos:int->len:int->t->int="bigstring_pread_assume_fd_is_nonblocking_stub"letpread_assume_fd_is_nonblockingfd~offset?(pos=0)?lenbstr=letlen=get_opt_lenbstr~posleninletloc="pread"incheck_args~loc~pos~lenbstr;unsafe_pread_assume_fd_is_nonblocking_stubfd~offset~pos~lenbstrletreally_readfd?(pos=0)?lenbstr=letlen=get_opt_lenbstr~posleninignore(read~min_len:lenfd~pos~lenbstr:int)externalunsafe_really_recv:Unix.File_descr.t->pos:int->len:int->t->unit="bigstring_really_recv_stub"letreally_recvsock?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"really_recv"~pos~lenbstr;unsafe_really_recvsock~pos~lenbstrexternalunsafe_recvfrom_assume_fd_is_nonblocking:Unix.File_descr.t->pos:int->len:int->t->int*Unix.sockaddr="bigstring_recvfrom_assume_fd_is_nonblocking_stub"letrecvfrom_assume_fd_is_nonblockingsock?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"recvfrom_assume_fd_is_nonblocking"~pos~lenbstr;unsafe_recvfrom_assume_fd_is_nonblockingsock~pos~lenbstrexternalunsafe_read_assume_fd_is_nonblocking:Unix.File_descr.t->pos:int->len:int->t->Syscall_result.Int.t="bigstring_read_assume_fd_is_nonblocking_stub"letread_assume_fd_is_nonblockingfd?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"read_assume_fd_is_nonblocking"~pos~lenbstr;unsafe_read_assume_fd_is_nonblockingfd~pos~lenbstrexternalunsafe_input:min_len:int->In_channel.t->pos:int->len:int->t->int="bigstring_input_stub"letinput?min_lenic?(pos=0)?lenbstr=letlen=get_opt_lenbstr~posleninletloc="input"incheck_args~loc~pos~lenbstr;letmin_len=check_min_len~loc~lenmin_leninunsafe_input~min_lenic~pos~lenbstrletreally_inputic?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"really_input"~pos~lenbstr;ignore(unsafe_input~min_len:lenic~pos~lenbstr:int)(* Output functions *)externalunsafe_really_write:Unix.File_descr.t->pos:int->len:int->t->unit="bigstring_really_write_stub"letreally_writefd?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"really_write"~pos~lenbstr;unsafe_really_writefd~pos~lenbstrexternalunsafe_pwrite_assume_fd_is_nonblocking:Unix.File_descr.t->offset:int->pos:int->len:int->t->int="bigstring_pwrite_assume_fd_is_nonblocking_stub"letpwrite_assume_fd_is_nonblockingfd~offset?(pos=0)?lenbstr=letlen=get_opt_lenbstr~posleninletloc="pwrite"incheck_args~loc~pos~lenbstr;unsafe_pwrite_assume_fd_is_nonblockingfd~offset~pos~lenbstr[%%ifdefJSC_MSG_NOSIGNAL][%%defineJSC_NOSIGPIPE][%%endif][%%ifdefJSC_SO_NOSIGPIPE][%%defineJSC_NOSIGPIPE][%%endif][%%ifdefJSC_NOSIGPIPE]externalunsafe_really_send_no_sigpipe:Unix.File_descr.t->pos:int->len:int->t->unit="bigstring_really_send_no_sigpipe_stub"letreally_send_no_sigpipefd?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"really_send_no_sigpipe"~pos~lenbstr;unsafe_really_send_no_sigpipefd~pos~lenbstrexternalunsafe_send_nonblocking_no_sigpipe:Unix.File_descr.t->pos:int->len:int->t->Syscall_result.Int.t="bigstring_send_nonblocking_no_sigpipe_stub"[@@noalloc]letsend_nonblocking_no_sigpipefd?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"send_nonblocking_no_sigpipe"~pos~lenbstr;unsafe_send_nonblocking_no_sigpipefd~pos~lenbstrexternalunsafe_sendto_nonblocking_no_sigpipe:Unix.File_descr.t->pos:int->len:int->t->Unix.sockaddr->Syscall_result.Int.t="bigstring_sendto_nonblocking_no_sigpipe_stub"letsendto_nonblocking_no_sigpipefd?(pos=0)?lenbstrsockaddr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"sendto_nonblocking_no_sigpipe"~pos~lenbstr;unsafe_sendto_nonblocking_no_sigpipefd~pos~lenbstrsockaddrletreally_send_no_sigpipe=Okreally_send_no_sigpipeletsend_nonblocking_no_sigpipe=Oksend_nonblocking_no_sigpipeletsendto_nonblocking_no_sigpipe=Oksendto_nonblocking_no_sigpipeletunsafe_really_send_no_sigpipe=Okunsafe_really_send_no_sigpipeletunsafe_send_nonblocking_no_sigpipe=Okunsafe_send_nonblocking_no_sigpipe[%%else]letu=Or_error.unimplementedletreally_send_no_sigpipe=u"Bigstring.really_send_no_sigpipe"letsend_nonblocking_no_sigpipe=u"Bigstring.send_nonblocking_no_sigpipe"letsendto_nonblocking_no_sigpipe=u"Bigstring.sendto_nonblocking_no_sigpipe"letunsafe_really_send_no_sigpipe=u"Bigstring.unsafe_really_send_no_sigpipe"letunsafe_send_nonblocking_no_sigpipe=u"Bigstring.unsafe_send_nonblocking_no_sigpipe"[%%endif]externalunsafe_write:Unix.File_descr.t->pos:int->len:int->t->int="bigstring_write_stub"letwritefd?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"write"~pos~lenbstr;unsafe_writefd~pos~lenbstrexternalunsafe_write_assume_fd_is_nonblocking:Unix.File_descr.t->pos:int->len:int->t->int="bigstring_write_assume_fd_is_nonblocking_stub"letwrite_assume_fd_is_nonblockingfd?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"write_assume_fd_is_nonblocking"~pos~lenbstr;unsafe_write_assume_fd_is_nonblockingfd~pos~lenbstrexternalunsafe_writev:Unix.File_descr.t->tUnix.IOVec.tarray->int->int="bigstring_writev_stub"letget_iovec_countlociovecs=function|None->Array.lengthiovecs|Somecount->ifcount<0theninvalid_arg(loc^": count < 0");letn_iovecs=Array.lengthiovecsinifcount>n_iovecstheninvalid_arg(loc^": count > n_iovecs");countletwritevfd?countiovecs=letcount=get_iovec_count"writev"iovecscountinunsafe_writevfdiovecscountexternalunsafe_writev_assume_fd_is_nonblocking:Unix.File_descr.t->tUnix.IOVec.tarray->int->int="bigstring_writev_assume_fd_is_nonblocking_stub"letwritev_assume_fd_is_nonblockingfd?countiovecs=letcount=get_iovec_count"writev_nonblocking"iovecscountinunsafe_writev_assume_fd_is_nonblockingfdiovecscount;;externalunsafe_output:min_len:int->Out_channel.t->pos:int->len:int->t->int="bigstring_output_stub"letoutput?min_lenoc?(pos=0)?lenbstr=letlen=get_opt_lenbstr~posleninletloc="output"incheck_args~loc~pos~lenbstr;letmin_len=check_min_len~loc~lenmin_leninunsafe_outputoc~min_len~pos~lenbstrletreally_outputoc?(pos=0)?lenbstr=letlen=get_opt_lenbstr~poslenincheck_args~loc:"really_output"~pos~lenbstr;ignore(unsafe_outputoc~min_len:len~pos~lenbstr:int)[%%ifdefJSC_RECVMMSG]externalunsafe_recvmmsg_assume_fd_is_nonblocking:Unix.File_descr.t->tUnix.IOVec.tarray->int->Unix.sockaddrarrayoption->intarray->int="bigstring_recvmmsg_assume_fd_is_nonblocking_stub"letrecvmmsg_assume_fd_is_nonblockingfd?count?srcsiovecs~lens=letloc="recvmmsg_assume_fd_is_nonblocking"inletcount=get_iovec_countlociovecscountinbeginmatchsrcswith|None->()|Somea->ifcount>Array.lengthatheninvalid_arg(loc^": count > n_srcs")end;ifcount>Array.lengthlenstheninvalid_arg(loc^": count > n_lens");unsafe_recvmmsg_assume_fd_is_nonblockingfdiovecscountsrcslens;;letunsafe_recvmmsg_assume_fd_is_nonblocking=Okunsafe_recvmmsg_assume_fd_is_nonblockingletrecvmmsg_assume_fd_is_nonblocking=(* At Jane Street, we link with [--wrap recvmmsg] so that we can use our own wrapper
around [recvmmsg]. This allows us to compile an executable on a machine that has
recvmmsg (e.g., CentOS 6) but then run the executable on a machine that does not
(e.g., CentOS 5), but that has our wrapper library. We set up our wrapper so that
when running on a machine that doesn't have it, [recvmmsg] always returns -1 and sets
errno to ENOSYS. *)letok=Okrecvmmsg_assume_fd_is_nonblockingintryassert(recvmmsg_assume_fd_is_nonblocking(Unix.File_descr.of_int(-1))[||]~lens:[||]=0);ok(* maybe it will ignore the bogus sockfd *)with|Unix.Unix_error(ENOSYS,_,_)->Or_error.unimplemented"Bigstring.recvmmsg_assume_fd_is_nonblocking"|_->ok;;[%%else](* NDEF RECVMMSG *)letunsafe_recvmmsg_assume_fd_is_nonblocking=Or_error.unimplemented"Bigstring.unsafe_recvmmsg_assume_fd_is_nonblocking";;letrecvmmsg_assume_fd_is_nonblocking=Or_error.unimplemented"Bigstring.recvmmsg_assume_fd_is_nonblocking";;[%%endif](* RECVMMSG *)(* Memory mapping *)[%%ifdefJSC_MSG_NOSIGNAL](* Input and output, linux only *)externalunsafe_sendmsg_nonblocking_no_sigpipe:Unix.File_descr.t->tUnix.IOVec.tarray->int->int="bigstring_sendmsg_nonblocking_no_sigpipe_stub"letunsafe_sendmsg_nonblocking_no_sigpipefdiovecscount=letres=unsafe_sendmsg_nonblocking_no_sigpipefdiovecscountinifres=-1thenNoneelseSomeresletsendmsg_nonblocking_no_sigpipefd?countiovecs=letcount=get_iovec_count"sendmsg_nonblocking_no_sigpipe"iovecscountinunsafe_sendmsg_nonblocking_no_sigpipefdiovecscountletsendmsg_nonblocking_no_sigpipe=Oksendmsg_nonblocking_no_sigpipeletunsafe_sendmsg_nonblocking_no_sigpipe=Okunsafe_sendmsg_nonblocking_no_sigpipe[%%else]letsendmsg_nonblocking_no_sigpipe=Or_error.unimplemented"Bigstring.sendmsg_nonblocking_no_sigpipe";;letunsafe_sendmsg_nonblocking_no_sigpipe=Or_error.unimplemented"Bigstring.unsafe_sendmsg_nonblocking_no_sigpipe";;[%%endif](* Memory mapping *)letmap_file~sharedfdsize=Bigarray.array1_of_genarray(Unix.map_filefdBigarray.charc_layout~shared[|size|])