123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143openCtypes(* Errno C bindings *)moduleStubs=Posix_errno_stubs.Def(Posix_errno_generated_stubs)includePosix_errno_typeincludePosix_errno_conversionsincludePosix_errno_is_native_impl(** Get current errno value *)letget_errno()=of_int(Stubs.posix_errno_get_errno())(** Get current errno as int *)letget_errno_int()=Stubs.posix_errno_get_errno()(** Reset errno to 0 *)letreset_errno()=Stubs.posix_errno_set_errno0n(** Convert errno variant to Unix.error *)letto_unix_error=function|`E2BIG->Unix.E2BIG|`EACCES->Unix.EACCES|`EAGAIN->Unix.EAGAIN|`EBADF->Unix.EBADF|`EBUSY->Unix.EBUSY|`ECHILD->Unix.ECHILD|`EDEADLK->Unix.EDEADLK|`EDOM->Unix.EDOM|`EEXIST->Unix.EEXIST|`EFAULT->Unix.EFAULT|`EFBIG->Unix.EFBIG|`EINTR->Unix.EINTR|`EINVAL->Unix.EINVAL|`EIO->Unix.EIO|`EISDIR->Unix.EISDIR|`EMFILE->Unix.EMFILE|`EMLINK->Unix.EMLINK|`ENAMETOOLONG->Unix.ENAMETOOLONG|`ENFILE->Unix.ENFILE|`ENODEV->Unix.ENODEV|`ENOENT->Unix.ENOENT|`ENOEXEC->Unix.ENOEXEC|`ENOLCK->Unix.ENOLCK|`ENOMEM->Unix.ENOMEM|`ENOSPC->Unix.ENOSPC|`ENOSYS->Unix.ENOSYS|`ENOTDIR->Unix.ENOTDIR|`ENOTEMPTY->Unix.ENOTEMPTY|`ENOTTY->Unix.ENOTTY|`ENXIO->Unix.ENXIO|`EPERM->Unix.EPERM|`EPIPE->Unix.EPIPE|`ERANGE->Unix.ERANGE|`EROFS->Unix.EROFS|`ESPIPE->Unix.ESPIPE|`ESRCH->Unix.ESRCH|`EXDEV->Unix.EXDEV|`EWOULDBLOCK->Unix.EWOULDBLOCK|`EINPROGRESS->Unix.EINPROGRESS|`EALREADY->Unix.EALREADY|`ENOTSOCK->Unix.ENOTSOCK|`EDESTADDRREQ->Unix.EDESTADDRREQ|`EMSGSIZE->Unix.EMSGSIZE|`EPROTOTYPE->Unix.EPROTOTYPE|`ENOPROTOOPT->Unix.ENOPROTOOPT|`EPROTONOSUPPORT->Unix.EPROTONOSUPPORT|`ESOCKTNOSUPPORT->Unix.ESOCKTNOSUPPORT|`EOPNOTSUPP->Unix.EOPNOTSUPP|`EPFNOSUPPORT->Unix.EPFNOSUPPORT|`EAFNOSUPPORT->Unix.EAFNOSUPPORT|`EADDRINUSE->Unix.EADDRINUSE|`EADDRNOTAVAIL->Unix.EADDRNOTAVAIL|`ENETDOWN->Unix.ENETDOWN|`ENETUNREACH->Unix.ENETUNREACH|`ENETRESET->Unix.ENETRESET|`ECONNABORTED->Unix.ECONNABORTED|`ECONNRESET->Unix.ECONNRESET|`ENOBUFS->Unix.ENOBUFS|`EISCONN->Unix.EISCONN|`ENOTCONN->Unix.ENOTCONN|`ESHUTDOWN->Unix.ESHUTDOWN|`ETOOMANYREFS->Unix.ETOOMANYREFS|`ETIMEDOUT->Unix.ETIMEDOUT|`ECONNREFUSED->Unix.ECONNREFUSED|`EHOSTDOWN->Unix.EHOSTDOWN|`EHOSTUNREACH->Unix.EHOSTUNREACH|`ELOOP->Unix.ELOOP|`EOVERFLOW->Unix.EOVERFLOW|(`EATTR|`EAUTH|`EBADARCH|`EBADE|`EBADEXEC|`EBADFD|`EBADMACHO|`EBADMSG|`EBADR|`EBADRPC|`EBADRQC|`EBADSLT|`ECANCELED|`ECHRNG|`ECOMM|`EDEADLOCK|`EDEVERR|`EDQUOT|`EFTYPE|`EHWPOISON|`EIDRM|`EILSEQ|`EISNAM|`EKEYEXPIRED|`EKEYREJECTED|`EKEYREVOKED|`EL2HLT|`EL2NSYNC|`EL3HLT|`EL3RST|`ELIBACC|`ELIBBAD|`ELIBEXEC|`ELIBMAX|`ELIBSCN|`ELNRNG|`EMEDIUMTYPE|`EMULTIHOP|`ENEEDAUTH|`ENOANO|`ENOATTR|`ENOCSI|`ENODATA|`ENOKEY|`ENOLINK|`ENOMEDIUM|`ENOMSG|`ENONET|`ENOPKG|`ENOPOLICY|`ENOSR|`ENOSTR|`ENOTBLK|`ENOTRECOVERABLE|`ENOTSUP|`ENOTUNIQ|`EOTHER|`EOWNERDEAD|`EPROCLIM|`EPROCUNAVAIL|`EPROGMISMATCH|`EPROGUNAVAIL|`EPROTO|`EPWROFF|`EREMCHG|`EREMOTE|`EREMOTEIO|`ERESTART|`ERFKILL|`ERPCMISMATCH|`ESHLIBVERS|`ESTALE|`ESTRPIPE|`ETIME|`ETOOBIG|`ETXTBSY|`EUCLEAN|`EUNATCH|`EUSERS|`EXFULL)asv->Unix.EUNKNOWNERR(Nativeint.to_int(to_intv))|`EUNKNOWNn->Unix.EUNKNOWNERR(Nativeint.to_intn)(** Convert errno int to Unix.error *)letint_to_unix_errorn=to_unix_error(of_intn)(** Generic error-raising function *)letraise_on_error?(call="")fcheck=reset_errno();letresult=f()inifcheckresultthenraise(Unix.Unix_error(to_unix_error(get_errno()),call,""))elseresult(** Check for negative integer return *)letraise_on_neg?callf=raise_on_error?callf(funx->x<0)(** Check for null pointer return *)letraise_on_null?callf=raise_on_error?callf(funptr->is_nullptr)(** Check for zero return value *)letraise_on_zero?callf=raise_on_error?callf(funx->x=0)letraise_on_none?callf=Option.get(raise_on_error?callf(funx->x=None))letstrerrorerr=Stubs.strerror(to_interr)(** Get error string from errno using strerror_r (thread-safe, POSIX only)
@raise Invalid_argument on Windows where strerror_r is not available *)letstrerror_r?(buflen=1024)err=letopenCtypesinletbuf=CArray.makecharbufleninletbuf_ptr=CArray.startbufinletresult=Stubs.strerror_r(to_interr)buf_ptrbufleninifresult=0nthen((* Success - get actual string length and convert to OCaml string *)letlen=Stubs.strlenbuf_ptrinstring_from_ptrbuf_ptr~length:len)else((* Error - strerror_r returned an error code, raise Unix error *)leterr=int_to_unix_errorresultinraise(Unix.Unix_error(err,"strerror_r","")))