pax_global_header00006660000000000000000000000064151513152530014513gustar00rootroot0000000000000052 comment=fb91029a9782dec6502ef33cc69409bf2da3ecd6 ocaml-posix-4.0.2/000077500000000000000000000000001515131525300137515ustar00rootroot00000000000000ocaml-posix-4.0.2/.github/000077500000000000000000000000001515131525300153115ustar00rootroot00000000000000ocaml-posix-4.0.2/.github/workflows/000077500000000000000000000000001515131525300173465ustar00rootroot00000000000000ocaml-posix-4.0.2/.github/workflows/ci.yml000066400000000000000000000007001515131525300204610ustar00rootroot00000000000000name: CI on: merge_group: pull_request: push: branches: - main concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] steps: - name: Build and test module uses: savonet/build-and-test-ocaml-module@main with: test-target: citest ocaml-posix-4.0.2/.github/workflows/doc.yml000066400000000000000000000011551515131525300206400ustar00rootroot00000000000000name: Doc build on: push: branches: - main jobs: build_doc: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v1 - name: Setup OCaml uses: ocaml/setup-ocaml@v3 with: ocaml-compiler: 4.14.x - name: Pin locally run: opam pin -y add --no-action . - name: Install locally run: opam install -y --with-doc . - name: Build doc run: opam exec dune build @doc - name: Deploy doc uses: JamesIves/github-pages-deploy-action@4.1.4 with: branch: gh-pages folder: _build/default/_doc/_html ocaml-posix-4.0.2/.github/workflows/windows.yml000066400000000000000000000061671515131525300215750ustar00rootroot00000000000000name: Windows CI on: merge_group: pull_request: push: branches: - main concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: OPAMROOT: D:\opamroot OPAMSOLVERTIMEOUT: 120 MSYS: winsymlinks:native jobs: build_and_test: name: "Build and test package" runs-on: windows-latest strategy: fail-fast: false matrix: build_env: [msys2, cygwin] package: [base, errno, math2, socket] ocaml: [5.4.0] steps: - name: Checkout tree uses: actions/checkout@v6 with: fetch-depth: 2 - name: Download install.ps1 run: | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 (New-Object System.Net.WebClient).DownloadFile("https://raw.githubusercontent.com/ocaml/opam/master/shell/install.ps1", ".\install.ps1") - name: Restore opam cache id: cache-opam uses: actions/cache/restore@v5 with: path: | D:\opam\bin D:\opamroot key: ${{ runner.os }}-${{ matrix.build_env }}-opam-${{ hashFiles('install.ps1') }} - name: Add MSYS2 to PATH and install prerequisites if: matrix.build_env == 'msys2' run: | "C:\msys64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append C:\msys64\usr\bin\pacman.exe --noconfirm -Syuu # Core update (in case any core packages are outdated) C:\msys64\usr\bin\pacman.exe --noconfirm -Syuu m4 make mingw-w64-i686-gcc mingw-w64-x86_64-gcc rsync unzip - name: Install opam if: steps.cache-opam.outputs.cache-hit != 'true' run: | Invoke-Expression "& ./install.ps1 -OpamBinDir 'D:\opam\bin'" - name: Add opam to PATH run: | D:\opam\bin\opam --version "D:\opam\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - name: Init opam if: steps.cache-opam.outputs.cache-hit != 'true' run: opam init --yes --no-setup ${{ matrix.build_env == 'msys2' && '--cygwin-local-install' || '' }} ${{ matrix.ocaml }} git+https://github.com/ocaml/opam-repository - name: Restrict testing to available compilers if: steps.cache-opam.outputs.cache-hit != 'true' # TODO Amend this lowerbound as older compiler packages are updated run: opam switch set-invariant --formula "`"ocaml`" {>= `"4.13`"}" - name: Save opam cache if: steps.cache-opam.outputs.cache-hit != 'true' uses: actions/cache/save@v5 with: path: | D:\opam\bin D:\opamroot key: ${{ steps.cache-opam.outputs.cache-primary-key }} - name: Print version and configuration information run: | opam --version opam exec -- ocaml -version opam exec -- ocamlopt -config opam var - name: Install package run: | opam pin -ny . opam install -y posix-${{ matrix.package }} - name: Run tests if: matrix.package != 'base' run: | opam exe dune build @citest modules/${{ matrix.package }} ocaml-posix-4.0.2/.gitignore000066400000000000000000000000721515131525300157400ustar00rootroot00000000000000*~ _build *.byte *.native _tests .merlin *.install .*.sw* ocaml-posix-4.0.2/.ocamlformat000066400000000000000000000003371515131525300162610ustar00rootroot00000000000000version=0.28.1 profile = conventional break-separators = after space-around-lists = false doc-comments = before match-indent = 2 match-indent-nested = always parens-ite exp-grouping = preserve module-item-spacing = compact ocaml-posix-4.0.2/CHANGES.md000066400000000000000000000023201515131525300153400ustar00rootroot00000000000000# 4.0.2 (2026-03-02) * Fixed segfault on 32bit architecture with enabled. LFS is enabled by default now on 32bit architectures. * Fix crash when passing wrong socketlen in getnameinfo. Thanks to @glondu * Fix `optopt` type in `posix-getopt` (should be `int`, not `char`). Thanks to @glondu * Fix `utimes` in `posix-time2`: it now takes separate `~last_access` and `~last_modification` arguments instead of a single `Timeval.t`. Thanks to @glondu * Fix Hurd support: `errno` is a `nativeint` on Hurd, `clock_nanosleep` and `PROCESS_CPUTIME` are not available on Hurd. Thanks to @glondu * Reorganize internal build: all modules moved under `modules/` with improved cflags handling # 4.0.1 (2026-01-10) * Add wrapper for freebsd's non-posix compliant `setpgrp`. # 4.0.0 (2026-01-01) * Add `posix-errno`, remove all use of `unix_errno`. * Add `posix-stat`. * Add `posix-resource`. * Add `posix-unistd`. * Add support for `posix-socket` `EAI_*` errors. # 3.1.0 (2025-12-22) * all: Bump dune to 3.20 * posix-socket: Remove sa_data. * posix-socket: Fix ai_family field type of struct addrinfo. Thanks to @glondu * posix-math2: Remove dependency on unix-errno, finish porting to proper windows/cross build. * Fix CHANGES, sorry! ocaml-posix-4.0.2/LICENSE000066400000000000000000000020421515131525300147540ustar00rootroot00000000000000Copyright (c) 2020 Romain Beauxis Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ocaml-posix-4.0.2/README.md000066400000000000000000000076751515131525300152470ustar00rootroot00000000000000# ocaml-posix [![GitHub license](https://img.shields.io/github/license/savonet/ocaml-posix)](LICENSE) [![CI](https://github.com/savonet/ocaml-posix/actions/workflows/ci.yml/badge.svg)](https://github.com/savonet/ocaml-posix/actions/workflows/ci.yml) [![GitHub release](https://img.shields.io/github/v/release/savonet/ocaml-posix)](https://github.com/savonet/ocaml-posix/releases) OCaml bindings to POSIX APIs. ## Overview ocaml-posix provides comprehensive bindings to POSIX system interfaces for OCaml. Each module offers: - **Low-level bindings** for use with [ocaml-ctypes](https://github.com/ocamllabs/ocaml-ctypes) - **High-level OCaml APIs** for convenient, idiomatic usage This project consolidates and extends various existing POSIX binding libraries into a single, consistent collection. ## Documentation API documentation is available at: http://www.liquidsoap.info/ocaml-posix/ ## Installation ### Via opam (recommended) ```sh opam install posix-base posix-types posix-errno posix-socket posix-time2 ``` ### From source ```sh git clone https://github.com/savonet/ocaml-posix.git cd ocaml-posix opam install . ``` ## Quick Start ```ocaml (* Using posix-time2 for clock operations *) open Posix_time2 let () = let ts = clock_gettime `Realtime in Printf.printf "Current time: %Ld.%09ld seconds\n" ts.Timespec.tv_sec ts.Timespec.tv_nsec ``` ```ocaml (* Using posix-uname for system information *) open Posix_uname let () = let info = uname () in Printf.printf "System: %s %s (%s)\n" info.sysname info.release info.machine ``` ```ocaml (* Using posix-socket for DNS resolution *) open Ctypes open Posix_socket let () = (* Resolve hostname to socket addresses *) let addresses = getaddrinfo ~port:(`Int 443) "example.com" in List.iter (fun sockaddr -> (* Convert back to human-readable form *) let host, port = getnameinfo sockaddr in Printf.printf "Resolved: %s:%d\n" host port ) addresses (* Convert between Unix and POSIX socket addresses *) let unix_to_posix addr = let posix_addr = from_unix_sockaddr addr in let host, port = getnameinfo posix_addr in Printf.printf "Address: %s:%d\n" host port ``` ## Available Packages | Package | Description | Replaces | |---------|-------------|----------| | `posix-base` | Base tools for generating POSIX bindings | - | | `posix-types` | POSIX type definitions | [ocaml-posix-types](https://github.com/yallop/ocaml-posix-types), [PosixTypes](http://ocamllabs.io/ocaml-ctypes/PosixTypes.html) | | `posix-errno` | Error number handling and Unix error conversion | [unix-errno](https://github.com/xapi-project/ocaml-unix-errno) | | `posix-socket` | Socket operations (`sys/socket.h`) | [sys-socket](https://github.com/toots/ocaml-sys-socket) | | `posix-socket-unix` | Unix domain socket extensions | - | | `posix-time2` | Time and clock functions | [posix-time](https://github.com/mwweissmann/ocaml-posix-time), [unix-time](https://github.com/dsheets/ocaml-unix-time), [posix-clock](https://github.com/mwweissmann/ocaml-posix-clock) | | `posix-getopt` | Command-line option parsing | [posix-getopt](https://github.com/toots/posix-getopt) | | `posix-uname` | System identification | - | | `posix-unistd` | Miscellaneous POSIX functions (`unistd.h`) | - | | `posix-resource` | Resource limits and usage (`sys/resource.h`) | [unix-sys-resource](https://github.com/dsheets/ocaml-unix-sys-resource) | | `posix-signal` | Signal handling | - | | `posix-stat` | File status (`sys/stat.h`) | [unix-sys-stat](https://github.com/dsheets/ocaml-unix-sys-stat) | | `posix-math2` | Mathematical functions | - | ## Cross-compilation ocaml-posix supports cross-compilation (e.g., building for Windows from Linux/macOS using mingw). The build system automatically detects cross-compilation scenarios and uses appropriate tooling. ## Contributing Contributions are welcome! Please feel free to submit issues or pull requests. ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ocaml-posix-4.0.2/base/000077500000000000000000000000001515131525300146635ustar00rootroot00000000000000ocaml-posix-4.0.2/base/dune000066400000000000000000000062161515131525300155460ustar00rootroot00000000000000(library (name posix_base) (public_name posix-base) (modules posix_base system_detect lfs_detect clibs_include_path) (synopsis "posix-base provides the base tools to generate the various posix bindings") (libraries ctypes.stubs integers)) (executable (modules gen_clibs_include_path) (name gen_clibs_include_path)) (executable (modules gen_exec_path) (name gen_exec_path) (libraries unix)) (rule (target exec_path) (deps exec.sh) (action (with-stdout-to %{target} (run %{exe:gen_exec_path.exe} exec.sh)))) (rule (target clibs_include_path.ml) (action (with-stdout-to %{target} (run %{exe:gen_clibs_include_path.exe} %{lib:ctypes:ctypes_cstubs_internals.h})))) (rule (targets target_system_detect.exe) (deps target_system_detect.c) (action (run %{ocaml-config:c_compiler} -DOCAML_POSIX_ERRNO_SYSTEM=ocaml_posix_%{system} -o %{targets} target_system_detect.c))) (rule (targets off_t_size_native.exe) (deps off_t_size.c) (action (run %{ocaml-config:c_compiler} -o %{targets} off_t_size.c))) (rule (targets off_t_size_lfs.exe) (deps off_t_size.c) (action (run %{ocaml-config:c_compiler} -D_FILE_OFFSET_BITS=64 -o %{targets} off_t_size.c))) (rule (targets off_t_size_native) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps off_t_size_native.exe) (action (with-stdout-to %{targets} (run ./off_t_size_native.exe)))) (rule (targets off_t_size_native) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps exec_path off_t_size_native.exe) (action (with-stdout-to %{targets} (system "%{read:exec_path} %{ocaml-config:system} ./off_t_size_native.exe")))) (rule (targets off_t_size_lfs) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps off_t_size_lfs.exe) (action (with-stdout-to %{targets} (run ./off_t_size_lfs.exe)))) (rule (targets off_t_size_lfs) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps exec_path off_t_size_lfs.exe) (action (with-stdout-to %{targets} (system "%{read:exec_path} %{ocaml-config:system} ./off_t_size_lfs.exe")))) (executable (name gen_lfs_detect) (modules gen_lfs_detect)) (rule (targets lfs_detect.ml) (deps off_t_size_native off_t_size_lfs gen_lfs_detect.exe) (action (with-stdout-to %{targets} (run ./gen_lfs_detect.exe off_t_size_native off_t_size_lfs)))) (executable (name gen_config) (modules gen_config) (libraries posix-base)) (rule (targets c_flags.inc) (deps gen_config.exe) (action (with-stdout-to %{targets} (run ./gen_config.exe dune)))) (rule (targets c_flags) (deps gen_config.exe) (action (with-stdout-to %{targets} (run ./gen_config.exe include)))) (rule (targets system_detect.ml) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps exec_path (:gen target_system_detect.exe)) (action (with-stdout-to %{targets} (system "%{read:exec_path} %{ocaml-config:system} %{gen}")))) (rule (targets system_detect.ml) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps (:gen target_system_detect.exe)) (action (with-stdout-to %{targets} (run %{gen})))) ocaml-posix-4.0.2/base/exec.sh000077500000000000000000000003671515131525300161540ustar00rootroot00000000000000#!/bin/sh SYSTEM=$1 CMD=$2 ARG=$3 if test "${SYSTEM}" = "mingw"; then wine $CMD $ARG elif test "${SYSTEM}" = "mingw64"; then if command -v wine64 > /dev/null 2>&1; then wine64 $CMD $ARG else wine $CMD $ARG fi else $CMD $ARG fi ocaml-posix-4.0.2/base/gen_clibs_include_path.ml000066400000000000000000000001251515131525300216570ustar00rootroot00000000000000let () = Printf.printf "let c_flags = %S\n" ("-I" ^ Filename.dirname Sys.argv.(1)) ocaml-posix-4.0.2/base/gen_config.ml000066400000000000000000000006461515131525300173210ustar00rootroot00000000000000let () = match Sys.argv.(1) with | "dune" -> Printf.printf "(env\n"; Printf.printf " (_\n"; Printf.printf " (c_flags (:standard %s))))\n" (String.concat " " Posix_base.c_flags) | "include" -> List.iter (fun flag -> Printf.printf "%s\n" flag) Posix_base.c_flags | mode -> failwith (Printf.sprintf "Unknown mode: %s (use 'dune' or 'include')" mode) ocaml-posix-4.0.2/base/gen_exec_path.ml000066400000000000000000000001121515131525300200000ustar00rootroot00000000000000let () = let path = Sys.argv.(1) in print_string (Unix.realpath path) ocaml-posix-4.0.2/base/gen_lfs_detect.ml000066400000000000000000000007021515131525300201610ustar00rootroot00000000000000let read_size filename = let ic = open_in filename in let size = int_of_string (String.trim (input_line ic)) in close_in ic; size let () = let size_native = read_size Sys.argv.(1) in let size_lfs = read_size Sys.argv.(2) in let needs_lfs = size_lfs > size_native in let c_flags = if needs_lfs then "-D_FILE_OFFSET_BITS=64" else "" in Printf.printf "let needs_lfs = %b\n" needs_lfs; Printf.printf "let c_flags = \"%s\"\n" c_flags ocaml-posix-4.0.2/base/off_t_size.c000066400000000000000000000001541515131525300171560ustar00rootroot00000000000000#include #include int main() { printf("%d\n", (int)sizeof(off_t)); return 0; } ocaml-posix-4.0.2/base/posix_base.ml000066400000000000000000000116521515131525300173560ustar00rootroot00000000000000open Ctypes module System_detect = System_detect let needs_lfs = Lfs_detect.needs_lfs let c_flags = List.filter (fun s -> s <> "") [Clibs_include_path.c_flags; Lfs_detect.c_flags] module Generators = struct module type TypesDef = sig module Types : Cstubs.Types.BINDINGS val c_headers : string end module Types (Def : TypesDef) = struct let gen () = let fname = Sys.argv.(1) in let oc = open_out_bin fname in let format = Format.formatter_of_out_channel oc in Format.fprintf format "%s@\n" Def.c_headers; Cstubs.Types.write_c format (module Def.Types); Format.pp_print_flush format (); close_out oc end module type StubsDef = sig module Stubs : Cstubs.BINDINGS val c_headers : string val concurrency : Cstubs.concurrency_policy val prefix : string end module Stubs (Def : StubsDef) = struct let gen () = let mode = Sys.argv.(1) in let fname = Sys.argv.(2) in let oc = open_out_bin fname in let format = Format.formatter_of_out_channel oc in let fn = match mode with | "ml" -> Cstubs.write_ml | "c" -> Format.fprintf format "%s@\n" Def.c_headers; Cstubs.write_c | _ -> assert false in fn ~concurrency:Def.concurrency format ~prefix:Def.prefix (module Def.Stubs); Format.pp_print_flush format (); close_out oc end end module Types = struct module type Arithmetic = sig type t val t : t typ val is_float : bool val to_int64 : t -> int64 val of_int64 : int64 -> t val to_float : t -> float val of_float : float -> t end let mkArithmetic ~name ~size ~is_float : (module Arithmetic) = match (is_float, size) with | true, _ -> (module struct type t = float let t = typedef float name let is_float = true let to_int64 = Int64.of_float let of_int64 = Int64.to_float let to_float x = x let of_float x = x end) | false, 1 | false, 2 -> (module struct type t = int let t = typedef int name let is_float = false let to_int64 = Int64.of_int let of_int64 = Int64.to_int let to_float = float_of_int let of_float = int_of_float end) | false, 4 -> (module struct type t = int32 let t = typedef int32_t name let is_float = false let to_int64 = Int64.of_int32 let of_int64 = Int64.to_int32 let to_float = Int32.to_float let of_float = Int32.of_float end) | false, 8 -> (module struct type t = int64 let t = typedef int64_t name let is_float = false let to_int64 x = x let of_int64 x = x let to_float = Int64.to_float let of_float = Int64.of_float end) | _ -> assert false module type Signed = sig type t val t : t typ include Signed.S with type t := t end module Int8 = struct let t = int8_t include Signed.Int end module Int16 = struct let t = int16_t include Signed.Int end module Int32 = struct let t = int32_t include Signed.Int32 end module Int64 = struct let t = int64_t include Signed.Int64 end let mkSigned ~name ~size : (module Signed) = match size with | 1 -> (module struct include Int8 let t = typedef t name end) | 2 -> (module struct include Int16 let t = typedef t name end) | 4 -> (module struct include Int32 let t = typedef t name end) | 8 -> (module struct include Int64 let t = typedef t name end) | _ -> assert false module type Unsigned = sig type t val t : t typ include Unsigned.S with type t := t end module UInt8 = struct let t = uint8_t include Unsigned.UInt8 end module UInt16 = struct let t = uint16_t include Unsigned.UInt16 end module UInt32 = struct let t = uint32_t include Unsigned.UInt32 end module UInt64 = struct let t = uint64_t include Unsigned.UInt64 end let mkUnsigned ~name ~size : (module Unsigned) = match size with | 1 -> (module struct include UInt8 let t = typedef t name end) | 2 -> (module struct include UInt16 let t = typedef t name end) | 4 -> (module struct include UInt32 let t = typedef t name end) | 8 -> (module struct include UInt64 let t = typedef t name end) | _ -> assert false end ocaml-posix-4.0.2/base/posix_base.mli000066400000000000000000000040171515131525300175240ustar00rootroot00000000000000open Ctypes module System_detect : sig val system : string end (** {2 Large File Support} *) (** [true] when [-D_FILE_OFFSET_BITS=64] is needed to enable large file support. This is typically true on 32-bit systems and false on 64-bit systems where [off_t] is already 64 bits. *) val needs_lfs : bool (** C compiler flags for POSIX compatibility. Should be passed to C compilation commands. *) val c_flags : string list (** Utilities modules to build ctypes bindings. *) (** Module used to define stubs generators. See: {!Posix_uname_stubs} and {!Posix_uname_constants} For some examples. *) module Generators : sig module type TypesDef = sig module Types : Cstubs.Types.BINDINGS val c_headers : string end module Types (_ : TypesDef) : sig val gen : unit -> unit end module type StubsDef = sig module Stubs : Cstubs.BINDINGS val c_headers : string val concurrency : Cstubs.concurrency_policy val prefix : string end module Stubs (_ : StubsDef) : sig val gen : unit -> unit end end (** Module used to define generic types using their size. See {!Posix_types} for an example. *) module Types : sig (** Module type for signed integers. *) module type Signed = sig type t val t : t typ include Signed.S with type t := t end val mkSigned : name:string -> size:int -> (module Signed) (** Module type for unsigned integers. *) module type Unsigned = sig type t val t : t typ include Unsigned.S with type t := t end val mkUnsigned : name:string -> size:int -> (module Unsigned) (** Module type for arithmetic numbers. In POSIX world, an arithmetic type can be either a floating point number or an integer (of unknown size). *) module type Arithmetic = sig type t val t : t typ val is_float : bool val to_int64 : t -> int64 val of_int64 : int64 -> t val to_float : t -> float val of_float : float -> t end val mkArithmetic : name:string -> size:int -> is_float:bool -> (module Arithmetic) end ocaml-posix-4.0.2/base/target_system_detect.c000066400000000000000000000003561515131525300212550ustar00rootroot00000000000000#include #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) int main() { printf("let system = Str.replace_first (Str.regexp \"ocaml_posix_\") \"\" \"%s\"\n", TOSTRING(OCAML_POSIX_ERRNO_SYSTEM)); return 0; } ocaml-posix-4.0.2/dune000066400000000000000000000002741515131525300146320ustar00rootroot00000000000000(rule (alias upload-doc) (deps (alias doc)) (action (progn (run cp -rf _doc/_html/ ../../docs) (run git commit ../../docs -m "Update docs") (run git push origin master)))) ocaml-posix-4.0.2/dune-project000066400000000000000000000100021515131525300162640ustar00rootroot00000000000000(lang dune 3.20) (name posix-bindings) (source (github savonet/ocaml-posix)) (license MIT) (authors "Romain Beauxis") (maintainers "romain.beauxis@gmail.com") (maintenance_intent "(latest)") (version 4.0.2) (generate_opam_files true) (opam_file_location inside_opam_directory) (package (name posix-base) (synopsis "Base module for the posix bindings") (description "posix-base provides base tools for the posix binding modules.") (depends (ocaml (>= 4.08)) (integers (>= 0.3.0)) (ctypes (>= 0.24.0))) ) (package (name posix-errno) (synopsis "POSIX errno handling and Unix error conversion") (description "posix-errno provides comprehensive errno handling.") (depends (ocaml (>= 4.08)) (posix-base (= :version)) ctypes) ) (package (name posix-signal) (synopsis "Bindings for the types defined in ") (description "posix-signal provides an API to the types and bindings defined in ") (depends (posix-base (= :version)) (posix-errno (= :version)) ctypes) ) (package (name posix-types) (synopsis "Bindings for the types defined in ") (description "posix-types provides an API to the types defined in ") (depends (ocaml (>= 4.03)) (posix-base (= :version)) ctypes) ) (package (name posix-time2) (synopsis "Bindings for posix time functions") (description "posix-time2 provides the types and bindings for posix time APIs.") (depends ctypes (posix-base (= :version)) (posix-types (= :version)) (posix-errno (= :version))) ) (package (name posix-unistd) (synopsis "Bindings for posix unistd.h functions") (description "posix-unistd provides comprehensive OCaml bindings to POSIX unistd.h functions.") (depends ctypes (posix-base (= :version)) (posix-types (= :version)) (posix-errno (= :version)))) (package (name posix-socket) (synopsis "Bindings for posix sockets") (description "posix-socket provides the types and bindings of posix sockets APIs available on both unix and windows.") (depends (ocaml (>= 4.12)) dune-configurator (posix-base (= :version)) ctypes) ) (package (name posix-socket-unix) (synopsis "Bindings for posix sockets") (description "posix-socket-unix provides unix-specific types and bindings for posix sockets.") (depends ctypes (posix-base (= :version)) (posix-socket (= :version)) (posix-errno (= :version))) ) (package (name posix-uname) (synopsis "Bindings for posix uname") (description "posix-uname provides a simple interface for POSIX uname.") (depends ctypes (posix-base (= :version)) (posix-errno (= :version))) ) (package (name posix-getopt) (synopsis "Bindings for posix getopt/getopt_long") (description "posix-getopt provides a simple interface for the POSIX getopt and its extensions, getopt_long and getopt_long_only.") (depends dune-configurator (ounit2 :with-test) (lwt :with-test) (posix-uname (and :with-test (= :version))) ctypes (posix-base (= :version)) (posix-errno (= :version))) ) (package (name posix-math2) (synopsis "Bindings for posix math") (description "posix-math2 provides a simple interface for POSIX math functions.") (depends ctypes (posix-base (= :version))) ) (package (name posix-stat) (synopsis "Bindings for posix stat") (description "posix-stat provides types and bindings for POSIX sys/stat.h APIs.") (depends ctypes (posix-base (= :version)) (posix-types (= :version)) (posix-time2 (= :version)) (posix-errno (= :version))) ) (package (name posix-resource) (synopsis "Bindings for posix resource limits and usage") (description "posix-resource provides types and bindings for POSIX sys/resource.h APIs.") (depends ctypes (posix-base (= :version)) (posix-types (= :version)) (posix-time2 (= :version)) (posix-errno (= :version))) ) (package (name posix-bindings) (synopsis "POSIX bindings") (description "install all available posix bindings") (allow_empty) (depends posix-types posix-socket posix-socket-unix posix-time2 posix-unistd posix-uname posix-math2 posix-getopt posix-stat posix-resource) ) ocaml-posix-4.0.2/modules/000077500000000000000000000000001515131525300154215ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/dune000066400000000000000000000000461515131525300162770ustar00rootroot00000000000000(dynamic_include ../base/c_flags.inc) ocaml-posix-4.0.2/modules/errno/000077500000000000000000000000001515131525300165465ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/errno/src/000077500000000000000000000000001515131525300173355ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/errno/src/constants/000077500000000000000000000000001515131525300213515ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/errno/src/constants/dune000066400000000000000000000005321515131525300222270ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_errno_constants) (public_name posix-errno.constants) (libraries posix-base ctypes.stubs)) (rule (targets posix_errno_constants.ml) (deps ../generator/gen_errno_constants.exe) (action (with-stdout-to %{targets} (run ../generator/gen_errno_constants.exe)))) ocaml-posix-4.0.2/modules/errno/src/dune000066400000000000000000000041501515131525300202130ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_errno) (public_name posix-errno) (synopsis "posix-errno provides POSIX errno handling and Unix error conversion") (foreign_stubs (language c) (names posix_errno_generated_stubs)) (modules posix_errno posix_errno_type posix_errno_conversions posix_errno_is_native_impl posix_errno_generated_constants posix_errno_generated_stubs) (libraries unix ctypes posix-errno.constants posix-errno.stubs)) (rule (targets posix_errno_generated_constants.ml) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps ../../../base/exec_path (:gen ./generator/gen_constants_c_target.exe)) (action (with-stdout-to %{targets} (system "%{read:../../../base/exec_path} %{ocaml-config:system} %{gen}")))) (rule (targets posix_errno_generated_constants.ml) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps (:gen ./generator/gen_constants_c_target.exe)) (action (with-stdout-to %{targets} (run %{gen})))) (rule (targets posix_errno_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_errno_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) (rule (targets posix_errno_type.ml) (deps ./generator/gen_errno_type.exe) (action (with-stdout-to %{targets} (run ./generator/gen_errno_type.exe)))) (rule (targets posix_errno_conversions.ml) (deps ./generator/gen_errno_conversions.exe) (action (with-stdout-to %{targets} (run ./generator/gen_errno_conversions.exe)))) (rule (targets posix_errno_is_native_impl.ml) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps ../../../base/exec_path (:gen ./generator/target_is_native_detector.exe)) (action (with-stdout-to %{targets} (system "%{read:../../../base/exec_path} %{ocaml-config:system} %{gen}")))) (rule (targets posix_errno_is_native_impl.ml) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps (:gen ./generator/target_is_native_detector.exe)) (action (with-stdout-to %{targets} (run %{gen})))) ocaml-posix-4.0.2/modules/errno/src/generator/000077500000000000000000000000001515131525300213235ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/errno/src/generator/dune000066400000000000000000000026501515131525300222040ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-errno.stubs posix-base)) (library (name errno_defaults) (libraries str posix-base) (modules errno_defaults)) (executable (name gen_constants_c) (modules gen_constants_c) (libraries errno_defaults posix-errno.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c_target.exe) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_errno_constants) (modules gen_errno_constants) (libraries errno_defaults)) (executable (name gen_errno_type) (modules gen_errno_type) (libraries errno_defaults)) (executable (name gen_errno_conversions) (modules gen_errno_conversions) (libraries errno_defaults)) (executable (name gen_is_native_detector) (modules gen_is_native_detector) (libraries errno_defaults)) (rule (targets target_is_native_detector.c) (action (with-stdout-to %{targets} (run ./gen_is_native_detector.exe)))) (executable (name gen_get_value) (modules gen_get_value) (libraries errno_defaults posix-errno)) (rule (targets target_is_native_detector.exe) (deps target_is_native_detector.c) (action (run %{ocaml-config:c_compiler} -o %{targets} target_is_native_detector.c))) ocaml-posix-4.0.2/modules/errno/src/generator/errno_defaults.ml000066400000000000000000001157331515131525300247030ustar00rootroot00000000000000(* Type for errno definition with platform-specific overrides *) type errno_def = { name : string; default : int; overrides : (string list * int) list; } (* Unified errno definitions with default values and platform-specific overrides Default values are typically for Linux, with overrides for BSD/macOS and Windows *) let errno_defs = [ (* Standard POSIX errno values - consistent across platforms *) { name = "E2BIG"; default = 7; overrides = [] }; { name = "EACCES"; default = 13; overrides = [] }; { name = "EBADF"; default = 9; overrides = [] }; { name = "EBUSY"; default = 16; overrides = [] }; { name = "ECHILD"; default = 10; overrides = [] }; { name = "EDOM"; default = 33; overrides = [] }; { name = "EEXIST"; default = 17; overrides = [] }; { name = "EFAULT"; default = 14; overrides = [] }; { name = "EFBIG"; default = 27; overrides = [] }; { name = "EINTR"; default = 4; overrides = [] }; { name = "EINVAL"; default = 22; overrides = [] }; { name = "EIO"; default = 5; overrides = [] }; { name = "EISDIR"; default = 21; overrides = [] }; { name = "EMFILE"; default = 24; overrides = [] }; { name = "EMLINK"; default = 31; overrides = [] }; { name = "ENFILE"; default = 23; overrides = [] }; { name = "ENODEV"; default = 19; overrides = [] }; { name = "ENOENT"; default = 2; overrides = [] }; { name = "ENOEXEC"; default = 8; overrides = [] }; { name = "ENOMEM"; default = 12; overrides = [] }; { name = "ENOSPC"; default = 28; overrides = [] }; { name = "ENOTDIR"; default = 20; overrides = [] }; { name = "ENOTTY"; default = 25; overrides = [] }; { name = "ENXIO"; default = 6; overrides = [] }; { name = "EPERM"; default = 1; overrides = [] }; { name = "EPIPE"; default = 32; overrides = [] }; { name = "ERANGE"; default = 34; overrides = [] }; { name = "EROFS"; default = 30; overrides = [] }; { name = "ESPIPE"; default = 29; overrides = [] }; { name = "ESRCH"; default = 3; overrides = [] }; { name = "EXDEV"; default = 18; overrides = [] }; { name = "ENOTBLK"; default = 15; overrides = [] }; { name = "ETXTBSY"; default = 26; overrides = [(["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 139)]; }; (* Network and extended POSIX errors - vary by platform *) { name = "EADDRINUSE"; default = 98; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 48); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 100); ]; }; { name = "EADDRNOTAVAIL"; default = 99; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 49); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 101); ]; }; { name = "EAFNOSUPPORT"; default = 97; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 47); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 102); ]; }; { name = "EAGAIN"; default = 11; overrides = [(["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 35)]; }; { name = "EALREADY"; default = 114; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 37); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 103); ]; }; { name = "EBADMSG"; default = 74; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 94); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 104); ]; }; { name = "ECANCELED"; default = 125; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 89); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 105); ]; }; { name = "ECONNABORTED"; default = 103; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 53); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 106); ]; }; { name = "ECONNREFUSED"; default = 111; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 61); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 107); ]; }; { name = "ECONNRESET"; default = 104; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 54); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 108); ]; }; { name = "EDEADLK"; default = 35; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 11); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 36); ]; }; { name = "EDESTADDRREQ"; default = 89; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 39); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 109); ]; }; { name = "EDQUOT"; default = 122; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 69 ); ]; }; { name = "EHOSTDOWN"; default = 112; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 64 ); ]; }; { name = "EHOSTUNREACH"; default = 113; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 65); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 110); ]; }; { name = "EIDRM"; default = 43; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 90); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 111); ]; }; { name = "EILSEQ"; default = 84; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 92); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 42); ]; }; { name = "EINPROGRESS"; default = 115; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 36); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 112); ]; }; { name = "EISCONN"; default = 106; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 56); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 113); ]; }; { name = "ELOOP"; default = 40; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 62); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 114); ]; }; { name = "EMSGSIZE"; default = 90; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 40); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 115); ]; }; { name = "EMULTIHOP"; default = 72; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 95 ); ]; }; { name = "ENAMETOOLONG"; default = 36; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 63); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 38); ]; }; { name = "ENETDOWN"; default = 100; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 50); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 116); ]; }; { name = "ENETRESET"; default = 102; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 52); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 117); ]; }; { name = "ENETUNREACH"; default = 101; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 51); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 118); ]; }; { name = "ENOBUFS"; default = 105; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 55); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 119); ]; }; { name = "ENODATA"; default = 61; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 96); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 120); ]; }; { name = "ENOLCK"; default = 37; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 77); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 39); ]; }; { name = "ENOLINK"; default = 67; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 97); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 121); ]; }; { name = "ENOMSG"; default = 42; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 91); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 122); ]; }; { name = "ENOPROTOOPT"; default = 92; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 42); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 123); ]; }; { name = "ENOSR"; default = 63; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 98); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 124); ]; }; { name = "ENOSTR"; default = 60; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 99); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 125); ]; }; { name = "ENOSYS"; default = 38; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 78); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 40); ]; }; { name = "ENOTCONN"; default = 107; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 57); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 126); ]; }; { name = "ENOTEMPTY"; default = 39; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 66); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 41); ]; }; { name = "ENOTRECOVERABLE"; default = 131; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 104); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 127); ]; }; { name = "ENOTSOCK"; default = 88; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 38); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 128); ]; }; { name = "ENOTSUP"; default = 95; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 45); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 129); ]; }; { name = "EOPNOTSUPP"; default = 95; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 102); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 130); ]; }; { name = "EOVERFLOW"; default = 75; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 84); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 132); ]; }; { name = "EOWNERDEAD"; default = 130; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 105); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 133); ]; }; { name = "EPFNOSUPPORT"; default = 96; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 46 ); ]; }; { name = "EPROTO"; default = 71; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 100); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 134); ]; }; { name = "EPROTONOSUPPORT"; default = 93; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 43); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 135); ]; }; { name = "EPROTOTYPE"; default = 91; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 41); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 136); ]; }; { name = "EREMOTE"; default = 66; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 71 ); ]; }; { name = "ESHUTDOWN"; default = 108; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 58 ); ]; }; { name = "ESOCKTNOSUPPORT"; default = 94; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 44 ); ]; }; { name = "ESTALE"; default = 116; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 70 ); ]; }; { name = "ETIME"; default = 62; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 101); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 137); ]; }; { name = "ETIMEDOUT"; default = 110; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 60); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 138); ]; }; { name = "ETOOMANYREFS"; default = 109; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 59 ); ]; }; { name = "EUSERS"; default = 87; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 68 ); ]; }; (* Linux-specific errors - use high placeholder values on other platforms *) { name = "EBADE"; default = 52; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10052 ); ]; }; { name = "EBADFD"; default = 77; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10077 ); ]; }; { name = "EBADR"; default = 53; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10053 ); ]; }; { name = "EBADRQC"; default = 56; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10056 ); ]; }; { name = "EBADSLT"; default = 57; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10057 ); ]; }; { name = "ECHRNG"; default = 44; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10044 ); ]; }; { name = "ECOMM"; default = 70; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10070 ); ]; }; { name = "EHWPOISON"; default = 133; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10133 ); ]; }; { name = "EISNAM"; default = 120; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10120 ); ]; }; { name = "EKEYEXPIRED"; default = 127; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10127 ); ]; }; { name = "EKEYREJECTED"; default = 129; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10129 ); ]; }; { name = "EKEYREVOKED"; default = 128; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10128 ); ]; }; { name = "EL2HLT"; default = 51; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10051 ); ]; }; { name = "EL2NSYNC"; default = 45; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10045 ); ]; }; { name = "EL3HLT"; default = 46; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10046 ); ]; }; { name = "EL3RST"; default = 47; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10047 ); ]; }; { name = "ELIBACC"; default = 79; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10079 ); ]; }; { name = "ELIBBAD"; default = 80; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10080 ); ]; }; { name = "ELIBEXEC"; default = 83; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10083 ); ]; }; { name = "ELIBMAX"; default = 82; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10082 ); ]; }; { name = "ELIBSCN"; default = 81; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10081 ); ]; }; { name = "ELNRNG"; default = 48; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10048 ); ]; }; { name = "EMEDIUMTYPE"; default = 124; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10124 ); ]; }; { name = "ENOANO"; default = 55; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10055 ); ]; }; { name = "ENOKEY"; default = 126; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10126 ); ]; }; { name = "ENOMEDIUM"; default = 123; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10123 ); ]; }; { name = "ENONET"; default = 64; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10064 ); ]; }; { name = "ENOPKG"; default = 65; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10065 ); ]; }; { name = "ENOTUNIQ"; default = 76; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10076 ); ]; }; { name = "EREMCHG"; default = 78; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10078 ); ]; }; { name = "EREMOTEIO"; default = 121; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10121 ); ]; }; { name = "ERESTART"; default = 85; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10085 ); ]; }; { name = "ERFKILL"; default = 132; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10132 ); ]; }; { name = "ESTRPIPE"; default = 86; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10086 ); ]; }; { name = "ETOOBIG"; default = 200; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10200 ); ]; }; { name = "EUCLEAN"; default = 117; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10117 ); ]; }; { name = "EUNATCH"; default = 49; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10049 ); ]; }; { name = "EXFULL"; default = 54; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 10054 ); ]; }; (* BSD/macOS-specific errors - use high placeholder values on Linux/Windows *) { name = "EAUTH"; default = 10080; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 80 ); ]; }; { name = "EBADRPC"; default = 10072; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 72 ); ]; }; { name = "EFTYPE"; default = 10079; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 79 ); ]; }; { name = "ENEEDAUTH"; default = 10081; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 81 ); ]; }; { name = "ENOCSI"; default = 50; overrides = [] }; { name = "EPROCLIM"; default = 10067; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 67 ); ]; }; { name = "EPROCUNAVAIL"; default = 10076; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 76 ); ]; }; { name = "EPROGMISMATCH"; default = 10075; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 75 ); ]; }; { name = "EPROGUNAVAIL"; default = 10074; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 74 ); ]; }; { name = "ERPCMISMATCH"; default = 10073; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 73 ); ]; }; (* macOS-specific errors - use high placeholder values on Linux/Windows *) { name = "EATTR"; default = 10093; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 93 ); ]; }; { name = "EBADARCH"; default = 10086; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 86 ); ]; }; { name = "EBADEXEC"; default = 10085; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 85 ); ]; }; { name = "EBADMACHO"; default = 10088; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 88 ); ]; }; { name = "EDEVERR"; default = 10083; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 83 ); ]; }; { name = "ENOATTR"; default = 10093; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 93 ); ]; }; { name = "ENOPOLICY"; default = 10103; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 103 ); ]; }; { name = "EPWROFF"; default = 10082; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 82 ); ]; }; { name = "ESHLIBVERS"; default = 10087; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 87 ); ]; }; (* Cross-platform "other" error *) { name = "EOTHER"; default = 10000; overrides = [] }; ] (* Errno aliases - these reference other errno values *) let errno_aliases = [("EWOULDBLOCK", "EAGAIN"); ("EDEADLOCK", "EDEADLK")] (* Get the errno value for a given system *) let get_value_for_system system errno_def = (* Check if any override matches the current system *) let rec find_override = function | [] -> errno_def.default | (systems, value) :: rest -> if List.mem system systems then value else find_override rest in Nativeint.of_int (find_override errno_def.overrides) (* Get platform-specific errno defaults based on system *) let get_errno_defaults system = List.map (fun def -> (def.name, get_value_for_system system def)) errno_defs (* Main errno defaults to use for this build *) let errno_defaults = get_errno_defaults Posix_base.System_detect.system ocaml-posix-4.0.2/modules/errno/src/generator/errno_defaults.mli000066400000000000000000000003321515131525300250400ustar00rootroot00000000000000type errno_def = { name : string; default : int; overrides : (string list * int) list; } val errno_defs : errno_def list val errno_aliases : (string * string) list val errno_defaults : (string * nativeint) list ocaml-posix-4.0.2/modules/errno/src/generator/gen_constants_c.ml000066400000000000000000000015171515131525300250300ustar00rootroot00000000000000(* Generate C code with #ifndef/#define/#endif for errno defaults *) let generate_errno_defaults_c () = let regular_defs = List.map (fun (name, value) -> Printf.sprintf "#ifndef %s\n#define %s %nd\n#endif\n" name name value) Errno_defaults.errno_defaults in let alias_defs = List.map (fun (name, alias) -> Printf.sprintf "#ifndef %s\n#define %s %s\n#endif\n" name name alias) Errno_defaults.errno_aliases in String.concat "\n" (regular_defs @ alias_defs) module Constants = Posix_base.Generators.Types (struct module Types = Posix_errno_constants.Def let c_headers = Printf.sprintf {| #include /* Provide default values for errno constants that might not be defined on all platforms */ %s |} (generate_errno_defaults_c ()) end) let () = Constants.gen () ocaml-posix-4.0.2/modules/errno/src/generator/gen_errno_constants.ml000066400000000000000000000015411515131525300257300ustar00rootroot00000000000000(* Generator for the errno polymorphic variant type *) let generate_constant_definition () = let names = List.map (fun (def : Errno_defaults.errno_def) -> def.name) Errno_defaults.errno_defs @ List.map fst Errno_defaults.errno_aliases in let lines = ["module Def (S : Cstubs.Types.TYPE) = struct"] in (* Generate polymorphic variant constructors from errno_defs *) let let_lines = List.map (fun name -> let error_name = String.sub name 0 1 ^ "_" ^ String.sub name 1 (String.length name - 1) in Printf.sprintf "let %s = S.constant \"%s\" S.nativeint\n" (String.lowercase_ascii error_name) name) names in (* Add unknown directly *) lines @ let_lines @ ["end"] let () = let type_def = generate_constant_definition () in List.iter print_endline type_def ocaml-posix-4.0.2/modules/errno/src/generator/gen_errno_conversions.ml000066400000000000000000000050761515131525300262730ustar00rootroot00000000000000(* Generator for errno conversion functions *) let generate_header () = [ "(* Generated errno conversion functions *)"; "module Constants = Posix_errno_constants.Def \ (Posix_errno_generated_constants)"; ""; ] let generate_of_int_function () = let variants = List.map (fun (def : Errno_defaults.errno_def) -> def.name) Errno_defaults.errno_defs in let aliases = Errno_defaults.errno_aliases in let lines = ["(** Convert errno code to variant *)"; "let of_int n ="] in (* First errno without 'else' *) let first_name = List.hd variants in let const_name = String.lowercase_ascii (String.sub first_name 1 (String.length first_name - 1)) in let first_line = Printf.sprintf " if n = Constants.e_%s then `%s" const_name first_name in (* Rest of the errnos *) let rest_variants = List.tl variants in let condition_lines = List.map (fun name -> let const_name = String.lowercase_ascii (String.sub name 1 (String.length name - 1)) in Printf.sprintf " else if n = Constants.e_%s then `%s" const_name name) rest_variants in (* Add aliases *) let alias_lines = List.map (fun (name, _) -> let const_name = String.lowercase_ascii (String.sub name 1 (String.length name - 1)) in Printf.sprintf " else if n = Constants.e_%s then `%s" const_name name) aliases in lines @ [first_line] @ condition_lines @ alias_lines @ [" else `EUNKNOWN n"] let generate_to_int_function () = let variants = List.map (fun (def : Errno_defaults.errno_def) -> def.name) Errno_defaults.errno_defs in let aliases = List.map fst Errno_defaults.errno_aliases in let lines = [""; "(** Convert variant to errno code *)"; "let to_int = function"] in let case_lines = List.map (fun name -> let const_name = String.lowercase_ascii (String.sub name 1 (String.length name - 1)) in Printf.sprintf " | `%s -> Constants.e_%s" name const_name) variants in let alias_lines = List.map (fun name -> let const_name = String.lowercase_ascii (String.sub name 1 (String.length name - 1)) in Printf.sprintf " | `%s -> Constants.e_%s" name const_name) aliases in lines @ case_lines @ alias_lines @ [" | `EUNKNOWN n -> n"] let () = let header = generate_header () in let of_int = generate_of_int_function () in let to_int = generate_to_int_function () in let output = header @ of_int @ to_int in List.iter print_endline output ocaml-posix-4.0.2/modules/errno/src/generator/gen_errno_type.ml000066400000000000000000000017011515131525300246730ustar00rootroot00000000000000(* Generator for the errno polymorphic variant type *) let generate_type_definition () = let variants = List.map (fun (def : Errno_defaults.errno_def) -> def.name) Errno_defaults.errno_defs in let aliases = List.map fst Errno_defaults.errno_aliases in let lines = [ "(** Comprehensive errno type covering Linux, BSD, macOS, and Windows \ values *)"; "type t = ["; ] in (* Generate polymorphic variant constructors from errno_defs *) let variant_lines = List.mapi (fun i name -> let sep = if i = 0 then " " else "| " in " " ^ sep ^ "`" ^ name) variants in (* Add aliases *) let alias_lines = List.map (fun name -> " | `" ^ name) aliases in (* Add unknown directly *) lines @ variant_lines @ alias_lines @ [" (* Unknown *)"; " | `EUNKNOWN of nativeint"; "]"] let () = let type_def = generate_type_definition () in List.iter print_endline type_def ocaml-posix-4.0.2/modules/errno/src/generator/gen_get_value.ml000066400000000000000000000016271515131525300244670ustar00rootroot00000000000000(* Generate get_value function for tests using errno_defs *) let generate_get_value () = (* Generate cases from errno_defs (not errno_defaults) to get all errno names *) let regular_cases = List.map (fun (def : Errno_defaults.errno_def) -> Printf.sprintf " | \"%s\" -> `%s" def.name def.name) Errno_defaults.errno_defs in let alias_cases = List.map (fun (alias_name, _target) -> Printf.sprintf " | \"%s\" -> `%s" alias_name alias_name) Errno_defaults.errno_aliases in let all_cases = regular_cases @ alias_cases in Printf.sprintf {|(* Auto-generated function - do not edit manually *) (* Generated from errno_defaults.mli using gen_get_value *) (* Function to get system errno value from errno name *) let get_value = function %s | _ -> failwith "Unknown errno" |} (String.concat "\n" all_cases) let () = print_endline (generate_get_value ()) ocaml-posix-4.0.2/modules/errno/src/generator/gen_is_native_detector.ml000066400000000000000000000014371515131525300263650ustar00rootroot00000000000000(* Generate C program that outputs OCaml is_native pattern matching *) let generate_is_native_detector_c () = let all_names = List.map fst Errno_defaults.errno_defaults @ List.map fst Errno_defaults.errno_aliases in let cases = List.map (fun name -> Printf.sprintf {|#ifdef %s printf(" | `%s -> true\n"); #else printf(" | `%s -> false\n"); #endif|} name name name) all_names in Printf.sprintf {|#include #include int main() { printf("(* Auto-generated file - do not edit manually *)\n\n"); printf("let is_native = function\n"); %s printf(" | `EUNKNOWN _ -> false\n"); return 0; }|} (String.concat "\n" cases) let () = let c_code = generate_is_native_detector_c () in print_endline c_code ocaml-posix-4.0.2/modules/errno/src/generator/gen_stubs.ml000066400000000000000000000015131515131525300236460ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_errno_stubs.Def let c_headers = {| #define _POSIX_C_SOURCE 200112L #include #include #include #include /* Get current errno value */ static inline int posix_errno_get_errno(void) { return errno; } /* Set errno value */ static inline void posix_errno_set_errno(int value) { errno = value; } /* strerror_r wrapper - raises Invalid_argument on Windows */ static inline int posix_errno_strerror_r(int errnum, char *buf, size_t buflen) { #ifdef _WIN32 caml_invalid_argument("strerror_r not available on Windows"); return EINVAL; /* Never reached */ #else return strerror_r(errnum, buf, buflen); #endif } |} let concurrency = Cstubs.unlocked let prefix = "posix_errno" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/errno/src/posix_errno.ml000066400000000000000000000120751515131525300222430ustar00rootroot00000000000000open Ctypes (* Errno C bindings *) module Stubs = Posix_errno_stubs.Def (Posix_errno_generated_stubs) include Posix_errno_type include Posix_errno_conversions include Posix_errno_is_native_impl (** Get current errno value *) let get_errno () = of_int (Stubs.posix_errno_get_errno ()) (** Get current errno as int *) let get_errno_int () = Stubs.posix_errno_get_errno () (** Reset errno to 0 *) let reset_errno () = Stubs.posix_errno_set_errno 0n (** Convert errno variant to Unix.error *) let to_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 ) as v -> Unix.EUNKNOWNERR (Nativeint.to_int (to_int v)) | `EUNKNOWN n -> Unix.EUNKNOWNERR (Nativeint.to_int n) (** Convert errno int to Unix.error *) let int_to_unix_error n = to_unix_error (of_int n) (** Generic error-raising function *) let raise_on_error ?(call = "") f check = reset_errno (); let result = f () in if check result then raise (Unix.Unix_error (to_unix_error (get_errno ()), call, "")) else result (** Check for negative integer return *) let raise_on_neg ?call f = raise_on_error ?call f (fun x -> x < 0) (** Check for null pointer return *) let raise_on_null ?call f = raise_on_error ?call f (fun ptr -> is_null ptr) (** Check for zero return value *) let raise_on_zero ?call f = raise_on_error ?call f (fun x -> x = 0) let raise_on_none ?call f = Option.get (raise_on_error ?call f (fun x -> x = None)) let strerror err = Stubs.strerror (to_int err) (** Get error string from errno using strerror_r (thread-safe, POSIX only) @raise Invalid_argument on Windows where strerror_r is not available *) let strerror_r ?(buflen = 1024) err = let open Ctypes in let buf = CArray.make char buflen in let buf_ptr = CArray.start buf in let result = Stubs.strerror_r (to_int err) buf_ptr buflen in if result = 0n then ( (* Success - get actual string length and convert to OCaml string *) let len = Stubs.strlen buf_ptr in string_from_ptr buf_ptr ~length:len) else ( (* Error - strerror_r returned an error code, raise Unix error *) let err = int_to_unix_error result in raise (Unix.Unix_error (err, "strerror_r", ""))) ocaml-posix-4.0.2/modules/errno/src/posix_errno.mli000066400000000000000000000147411515131525300224160ustar00rootroot00000000000000(** POSIX errno handling. This module provides OCaml bindings for POSIX error codes defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html} errno.h}. It includes a comprehensive errno type covering POSIX, Linux, BSD, macOS, and Windows error codes, along with functions for error checking and conversion. {2 Example} {[ (* Check for errors when calling a C function *) let fd = Posix_errno.raise_on_neg ~call:"open" (fun () -> (* some C binding that returns -1 on error *) c_open path flags mode ) in Printf.printf "Opened file descriptor: %d\n" fd (* Get the current errno value *) let err = Posix_errno.get_errno () in Printf.printf "Error: %s\n" (Posix_errno.strerror err) ]} *) (** {1 Errno Type} *) (** Comprehensive errno type covering Linux, BSD, macOS, and Windows values *) type t = [ (* Standard POSIX *) `E2BIG | `EACCES | `EADDRINUSE | `EADDRNOTAVAIL | `EAFNOSUPPORT | `EAGAIN | `EALREADY | `EBADF | `EBADMSG | `EBUSY | `ECANCELED | `ECHILD | `ECONNABORTED | `ECONNREFUSED | `ECONNRESET | `EDEADLK | `EDESTADDRREQ | `EDOM | `EDQUOT | `EEXIST | `EFAULT | `EFBIG | `EHOSTDOWN | `EHOSTUNREACH | `EIDRM | `EILSEQ | `EINPROGRESS | `EINTR | `EINVAL | `EIO | `EISCONN | `EISDIR | `ELOOP | `EMFILE | `EMLINK | `EMSGSIZE | `EMULTIHOP | `ENAMETOOLONG | `ENETDOWN | `ENETRESET | `ENETUNREACH | `ENFILE | `ENOBUFS | `ENODATA | `ENODEV | `ENOENT | `ENOEXEC | `ENOLCK | `ENOLINK | `ENOMEM | `ENOMSG | `ENOPROTOOPT | `ENOSPC | `ENOSR | `ENOSTR | `ENOSYS | `ENOTCONN | `ENOTDIR | `ENOTEMPTY | `ENOTRECOVERABLE | `ENOTSOCK | `ENOTSUP | `ENOTTY | `ENXIO | `EOPNOTSUPP | `EOVERFLOW | `EOWNERDEAD | `EPERM | `EPFNOSUPPORT | `EPIPE | `EPROTO | `EPROTONOSUPPORT | `EPROTOTYPE | `ERANGE | `EREMOTE | `EROFS | `ESHUTDOWN | `ESOCKTNOSUPPORT | `ESPIPE | `ESRCH | `ESTALE | `ETIME | `ETIMEDOUT | `ETOOMANYREFS | `ETXTBSY | `EUSERS | `EWOULDBLOCK | `EXDEV | (* Linux-specific *) `EBADE | `EBADFD | `EBADR | `EBADRQC | `EBADSLT | `ECHRNG | `ECOMM | `EDEADLOCK | `EHWPOISON | `EISNAM | `EKEYEXPIRED | `EKEYREJECTED | `EKEYREVOKED | `EL2HLT | `EL2NSYNC | `EL3HLT | `EL3RST | `ELIBACC | `ELIBBAD | `ELIBEXEC | `ELIBMAX | `ELIBSCN | `ELNRNG | `EMEDIUMTYPE | `ENOANO | `ENOKEY | `ENOMEDIUM | `ENONET | `ENOPKG | `ENOTBLK | `ENOTUNIQ | `EREMCHG | `EREMOTEIO | `ERESTART | `ERFKILL | `ESTRPIPE | `ETOOBIG | `EUCLEAN | `EUNATCH | `EXFULL | (* BSD/macOS *) `EAUTH | `EBADRPC | `EFTYPE | `ENEEDAUTH | `ENOCSI | `EPROCLIM | `EPROCUNAVAIL | `EPROGMISMATCH | `EPROGUNAVAIL | `ERPCMISMATCH | (* macOS-specific *) `EATTR | `EBADARCH | `EBADEXEC | `EBADMACHO | `EDEVERR | `ENOATTR | `ENOPOLICY | `EPWROFF | `ESHLIBVERS | (* Windows *) `EOTHER | (* Unknown *) `EUNKNOWN of nativeint ] (** {1 Errno Conversion} *) (** Convert errno integer code to variant. *) val of_int : nativeint -> t (** Convert variant to errno integer code. *) val to_int : t -> nativeint (** {1 Errno Access} *) (** Get current errno value. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html} errno(3)}. *) val get_errno : unit -> t (** Get current errno as integer. *) val get_errno_int : unit -> nativeint (** Reset errno to 0. Should be called before operations that set errno. *) val reset_errno : unit -> unit (** {1 Error Raising} *) (** Generic error-raising function. [raise_on_error ?call f check] calls [f()] and checks the result with [check]. If [check] returns [true], raises a Unix_error based on the current errno. @param call Optional name of the calling function (for error messages) @param f Function to execute @param check Function to check if result indicates an error @return The result of [f()] if no error occurred @raise Unix_error if [check] returns [true] *) val raise_on_error : ?call:string -> (unit -> 'a) -> ('a -> bool) -> 'a (** {1 Specialized Error Checkers} *) (** Check for negative integer return (common for syscalls). Raises Unix_error if result < 0. *) val raise_on_neg : ?call:string -> (unit -> int) -> int (** Check for null pointer return (for C functions). Raises Unix_error if result is null. *) val raise_on_null : ?call:string -> (unit -> 'a Ctypes.ptr) -> 'a Ctypes.ptr (** Check for zero return value (some functions return 0 on error). Raises Unix_error if result = 0. *) val raise_on_zero : ?call:string -> (unit -> int) -> int (** Check for None return value. Raise Unix_error if result = None. *) val raise_on_none : ?call:string -> (unit -> 'a option) -> 'a (** {1 Unix Error Conversion} *) (** Convert errno variant to Unix.error *) val to_unix_error : t -> Unix.error (** Convert errno int to Unix.error *) val int_to_unix_error : nativeint -> Unix.error (** {1 Error String Functions} *) (** Get error message string for an errno value using strerror. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html} strerror(3)}. This function is cross-platform (works on both POSIX and Windows) but not thread-safe. @return Error message string. *) val strerror : t -> string (** Get error message string for an errno value using strerror_r. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html} strerror_r(3)}. This function is thread-safe but only available on POSIX systems. @param buflen Optional buffer length for error message (default: 1024). @return Error message string. @raise Invalid_argument on Windows where strerror_r is not available. @raise Unix_error if strerror_r fails. *) val strerror_r : ?buflen:int -> t -> string (** {1 Native Definition Detection} *) (** Check if an errno value is natively defined on this platform. Returns [true] if the errno is natively defined by the system, [false] if it's using a placeholder fallback value. This is useful to determine if an errno constant represents a real system error on the current platform, or if it's just a placeholder value (typically in the 10000+ range) that was assigned because the error doesn't exist on this system. @param errnum The errno value to check @return [true] if natively defined, [false] if using placeholder *) val is_native : t -> bool ocaml-posix-4.0.2/modules/errno/src/stubs/000077500000000000000000000000001515131525300204755ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/errno/src/stubs/dune000066400000000000000000000002251515131525300213520ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_errno_stubs) (public_name posix-errno.stubs) (libraries ctypes.stubs)) ocaml-posix-4.0.2/modules/errno/src/stubs/posix_errno_stubs.ml000066400000000000000000000014161515131525300246200ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F (* Errno access functions *) let posix_errno_get_errno = foreign "posix_errno_get_errno" (void @-> returning nativeint) let posix_errno_set_errno = foreign "posix_errno_set_errno" (nativeint @-> returning void) (* strerror function - returns OCaml string (cross-platform, not thread-safe) *) let strerror = foreign "strerror" (nativeint @-> returning string) (* strerror_r function - POSIX version returns int (0 on success) *) (* Raises Invalid_argument on Windows *) let strerror_r = foreign "posix_errno_strerror_r" (nativeint @-> ptr char @-> int @-> returning nativeint) (* strlen function to get string length *) let strlen = foreign "strlen" (ptr char @-> returning int) end ocaml-posix-4.0.2/modules/errno/test/000077500000000000000000000000001515131525300175255ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/errno/test/dune000066400000000000000000000007751515131525300204140ustar00rootroot00000000000000(rule (targets test_get_value.ml) (deps (:gen ../src/generator/gen_get_value.exe)) (action (with-stdout-to %{targets} (run %{gen})))) (executable (name test) (libraries posix-errno)) (rule (alias citest) (package posix-errno) (action (run %{exe:test.exe}))) (executable (name test_errno_defaults) (modules test_errno_defaults test_get_value) (libraries posix-errno errno_defaults unix)) (rule (alias citest) (package posix-errno) (action (run %{exe:test_errno_defaults.exe}))) ocaml-posix-4.0.2/modules/errno/test/test.ml000066400000000000000000000054151515131525300210430ustar00rootroot00000000000000open Posix_errno let () = Printf.printf "=== POSIX Errno strerror Tests ===\n\n"; Printf.printf "Testing strerror with common errno values:\n"; (* Test with errno integers *) let test_errno errnum err_variant = Printf.printf " %s (errno %nd): %s\n" (match err_variant with | `EPERM -> "EPERM" | `ENOENT -> "ENOENT" | `ESRCH -> "ESRCH" | `EINTR -> "EINTR" | `EIO -> "EIO" | `ENXIO -> "ENXIO" | `EBADF -> "EBADF" | `EAGAIN -> "EAGAIN" | `ENOMEM -> "ENOMEM" | `EACCES -> "EACCES" | `EFAULT -> "EFAULT" | `EBUSY -> "EBUSY" | `EEXIST -> "EEXIST" | `ENOTDIR -> "ENOTDIR" | `EISDIR -> "EISDIR" | `EINVAL -> "EINVAL" | `EMFILE -> "EMFILE" | `ENOSPC -> "ENOSPC" | `EPIPE -> "EPIPE" | `ERANGE -> "ERANGE" | _ -> "OTHER") errnum (strerror (of_int errnum)) in (* Test common POSIX errors *) test_errno (to_int `EPERM) `EPERM; test_errno (to_int `ENOENT) `ENOENT; test_errno (to_int `ESRCH) `ESRCH; test_errno (to_int `EINTR) `EINTR; test_errno (to_int `EIO) `EIO; test_errno (to_int `ENXIO) `ENXIO; test_errno (to_int `EBADF) `EBADF; test_errno (to_int `EAGAIN) `EAGAIN; test_errno (to_int `ENOMEM) `ENOMEM; test_errno (to_int `EACCES) `EACCES; test_errno (to_int `EFAULT) `EFAULT; test_errno (to_int `EBUSY) `EBUSY; test_errno (to_int `EEXIST) `EEXIST; test_errno (to_int `ENOTDIR) `ENOTDIR; test_errno (to_int `EISDIR) `EISDIR; test_errno (to_int `EINVAL) `EINVAL; test_errno (to_int `EMFILE) `EMFILE; test_errno (to_int `ENOSPC) `ENOSPC; test_errno (to_int `EPIPE) `EPIPE; test_errno (to_int `ERANGE) `ERANGE; Printf.printf "\nTesting strerror_of_t with errno variants:\n"; (* Test with errno variants *) let test_errno_t err name = Printf.printf " %s: %s\n" name (strerror err) in test_errno_t `ECONNREFUSED "ECONNREFUSED"; test_errno_t `EADDRINUSE "EADDRINUSE"; test_errno_t `ETIMEDOUT "ETIMEDOUT"; test_errno_t `ENOTCONN "ENOTCONN"; test_errno_t `EHOSTUNREACH "EHOSTUNREACH"; Printf.printf "\nTesting strerror (cross-platform, not thread-safe):\n"; Printf.printf " EPERM: %s\n" (strerror `EPERM); Printf.printf " ENOENT: %s\n" (strerror `ENOENT); Printf.printf "\nTesting strerror_r with custom buffer length:\n"; (* Skip strerror_r tests on Windows where it's not available *) if Sys.os_type = "Win32" then Printf.printf " (Skipped on Windows - strerror_r not available)\n" else ( (* Test with small buffer *) Printf.printf " EPERM (buflen=50): %s\n" (strerror_r ~buflen:50 `EPERM); Printf.printf " EACCES (buflen=50): %s\n" (strerror_r ~buflen:50 `EACCES)); Printf.printf "\n✓ All strerror tests completed successfully!\n" ocaml-posix-4.0.2/modules/errno/test/test_errno_defaults.ml000066400000000000000000000071641515131525300241420ustar00rootroot00000000000000open Posix_errno (* get_value is now generated from errno_defaults.mli in Test_get_value module *) let get_alias_value _name target_name = try Test_get_value.get_value target_name with _ -> Printf.printf " (alias target %s not found)\n" target_name; assert false let () = Printf.printf "=== POSIX Errno Default Values Test ===\n\n"; (* Print system information *) Printf.printf "Platform: system=%s\n\n" Posix_base.System_detect.system; Printf.printf "Comparing default errno values with system values...\n\n"; (* Compare regular errno values *) Printf.printf "Regular errno constants:\n"; Printf.printf "%-20s | %-10s | %-10s | %-10s | %s\n" "Name" "Default" "System" "Native" "Status"; Printf.printf "%s\n" (String.make 77 '-'); let matching = ref 0 in let different = ref 0 in let different_list = ref [] in List.iter (fun (name, default_value) -> let value = Test_get_value.get_value name in let int_value = Posix_errno.to_int value in let is_native_val = is_native value in let native_str = if is_native_val then "YES" else "NO" in let status, mark = if int_value = default_value then ( incr matching; ("MATCH", " ")) else ( incr different; different_list := (name, default_value, int_value) :: !different_list; ("DIFFERENT", "**")) in Printf.printf "%s%-20s | %-10nd | %-10nd | %-10s | %s\n" mark name default_value int_value native_str status) Errno_defaults.errno_defaults; (* Handle aliases *) Printf.printf "\nErrno aliases:\n"; Printf.printf "%-20s | %-10s | %-10s | %-15s | %-10s | %-10s\n" "Alias" "Value" "Native" "Target" "Value" "Native"; Printf.printf "%s\n" (String.make 82 '-'); List.iter (fun (alias_name, target_name) -> let target_value = get_alias_value alias_name target_name in let alias_value = Test_get_value.get_value alias_name in let alias_native = if is_native alias_value then "YES" else "NO" in let target_native = if is_native target_value then "YES" else "NO" in Printf.printf " %-20s | %-10nd | %-10s | %-15s | %-10nd | %-10s\n" alias_name (Posix_errno.to_int alias_value) alias_native target_name (Posix_errno.to_int target_value) target_native) Errno_defaults.errno_aliases; (* Summary *) Printf.printf "\n=== Summary ===\n"; Printf.printf "Total errno constants tested: %d\n" (List.length Errno_defaults.errno_defaults); Printf.printf "Values matching defaults: %d\n" !matching; Printf.printf "Values different from defaults: %d\n" !different; if !different > 0 then ( Printf.printf "\nValues that differ from defaults:\n"; List.iter (fun (name, default_val, system_val) -> Printf.printf " %-20s: default=%nd, system=%nd (diff=%nd)\n" name default_val system_val Nativeint.(sub system_val default_val)) (List.rev !different_list)); Printf.printf "\nNote: The 'Native' column shows whether the errno is natively\n"; Printf.printf "defined by the system (YES) or using a placeholder fallback (NO).\n"; Printf.printf "\nValues that match the defaults may either:\n"; Printf.printf " 1. Be natively defined by the system with that value, OR\n"; Printf.printf " 2. Not be defined by the system and use the fallback default value\n"; Printf.printf "\nValues that differ from defaults are definitely defined by the system.\n"; Printf.printf "Use the is_native() function to distinguish between cases 1 and 2.\n"; Printf.printf "\nTest completed successfully (informational only, no failures)\n" ocaml-posix-4.0.2/modules/getopt/000077500000000000000000000000001515131525300167235ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/getopt/CHANGES000066400000000000000000000005071515131525300177200ustar00rootroot000000000000002.2.0 (2025-01-30) ===== * Fix copy code in `getaddrinfo`. 2.1.0 (2025-01-16) ===== * Added `posix-math2` * Invoke `wine64` only when available. * Added `sockaddr_len` in `ocaml-posix`. * Add support for string and optional `port. * Add support for `hints`. 2.0.2 (2023-02-08) ===== **posix-time2** * Added `clock_nanosleep` ocaml-posix-4.0.2/modules/getopt/README.md000066400000000000000000000002111515131525300201740ustar00rootroot00000000000000# posix-getopt This module provides a simple interface for the POSIX `getopt` and its extensions,` getopt_long` and `getopt_long_only`. ocaml-posix-4.0.2/modules/getopt/src/000077500000000000000000000000001515131525300175125ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/getopt/src/config/000077500000000000000000000000001515131525300207575ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/getopt/src/config/discover.ml000066400000000000000000000022041515131525300231250ustar00rootroot00000000000000module C = Configurator.V1 let has_getopt_h_code = {| #include int main() { return 0; } |} let has_optreset_code = {| #include int main() { int foo = optreset; return 0; } |} let has_get_getopt_long_code = {| #include #include int main() { int ret = getopt_long(0, NULL, NULL, NULL, NULL); return 0; } |} let has_get_getopt_long_only_code = {| #include #include int main() { int ret = getopt_long_only(0, NULL, NULL, NULL, NULL); return 0; } |} let () = C.main ~name:"posix_getopt" (fun c -> let has_getopt_h = C.c_test c has_getopt_h_code in let has_optreset = C.c_test c has_optreset_code in let has_get_getopt_long = C.c_test c has_get_getopt_long_code in let has_get_getopt_long_only = C.c_test c has_get_getopt_long_only_code in C.C_define.gen_header_file c ~fname:"config.h" [ ("HAS_GETOPT_H", Switch has_getopt_h); ("HAS_OPTRESET", Switch has_optreset); ("HAS_GETOPT_LONG", Switch has_get_getopt_long); ("HAS_GETOPT_LONG_ONLY", Switch has_get_getopt_long_only); ]) ocaml-posix-4.0.2/modules/getopt/src/config/dune000066400000000000000000000000751515131525300216370ustar00rootroot00000000000000(executable (name discover) (libraries dune.configurator)) ocaml-posix-4.0.2/modules/getopt/src/dune000066400000000000000000000011511515131525300203660ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_getopt) (public_name posix-getopt) (synopsis "posix-getopt provides access to the features exposed in unistd.h") (foreign_stubs (language c) (names posix_getopt_generated_stubs)) (libraries ctypes posix-errno posix-getopt.stubs)) (rule (targets posix_getopt_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_getopt_generated_stubs.c) (deps config.h) (action (run ./generator/gen_stubs.exe c %{targets}))) (rule (targets config.h) (action (run ./config/discover.exe))) ocaml-posix-4.0.2/modules/getopt/src/generator/000077500000000000000000000000001515131525300215005ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/getopt/src/generator/dune000066400000000000000000000011151515131525300223540ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-getopt.stubs posix-base)) (executable (name gen_types_c) (modules gen_types_c) (libraries posix-getopt.types posix-base)) (rule (targets gen_types.c) (deps config.h) (action (run ./gen_types_c.exe %{targets}))) (rule (targets config.h) (action (run ../config/discover.exe))) (rule (targets gen_types_c) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/getopt/src/generator/gen_stubs.ml000066400000000000000000000023051515131525300240230ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_getopt_stubs.Def let c_headers = {| #include #include #include #include "config.h" #ifdef HAS_GETOPT_H #include #else struct option { char *name; int has_arg; int *flag; int val; }; #endif static int *getoptind() { return &optind; } static int *getopterr() { return &opterr; } static int *getoptopt() { return (int *)&optopt; } static int *getoptreset() { #ifdef HAS_OPTRESET return &optreset; #else return NULL; #endif } static char *getoptarg() { return optarg; } #ifndef HAS_GETOPT_LONG static int has_getopt_long() { return 0; } int getopt_long(int x, char **y, const char *z, const struct option *t, int *u) { errno = ENOSYS; return 0; } #else static int has_getopt_long() { return 1; } #endif #ifndef HAS_GETOPT_LONG_ONLY static int has_getopt_long_only() { return 0; } int getopt_long_only(int x, char **y, const char *z, const struct option *t, int *u) { errno = ENOSYS; return 0; } #else static int has_getopt_long_only() { return 1; } #endif |} let concurrency = Cstubs.unlocked let prefix = "posix_getopt" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/getopt/src/generator/gen_types_c.ml000066400000000000000000000004461515131525300243350ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_getopt_types.Def let c_headers = {| #include "config.h" #ifdef HAS_GETOPT_H #include #else struct option { char *name; int has_arg; int *flag; int val; }; #endif |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/getopt/src/posix_getopt.ml000066400000000000000000000105731515131525300225760ustar00rootroot00000000000000open Ctypes include Posix_getopt_stubs.Def (Posix_getopt_generated_stubs) type short = char type long = string * char type arg = [ `None of unit -> unit | `Optional of string option -> unit | `Required of string -> unit ] type 'a opt = { name : 'a; arg : arg } exception Unknown_option of string exception Missing_argument of char let () = Printexc.register_printer (function | Unknown_option s -> Some (Printf.sprintf "Unknown getopt option: %s" s) | Missing_argument c -> Some (Printf.sprintf "Missing argument for getopt option: %c" c) | _ -> None) let opterr = getopterr () let optopt = getoptopt () let optind = getoptind () let optreset = getoptreset () let optarg () = let p = getoptarg () in string_from_ptr p ~length:(strlen p) let print_error flag = opterr <-@ if flag then 1 else 0 let () = print_error false let reset () = (* GNU *) if is_null optreset then optind <-@ 0 else begin (* Others *) optreset <-@ 1; optind <-@ 1 end let remaining_argv _argv = let argc = CArray.length _argv in let optind = min !@optind argc in let argv = Array.of_list (CArray.to_list _argv) in Array.sub argv optind (argc - optind) let apply_opt c = function | `None callback -> callback () | `Optional callback -> if c = ':' then callback None else callback (Some (optarg ())) | `Required callback -> callback (optarg ()) let unknown_option _argv = let _optopt = Char.chr !@optopt in let unknown = if _optopt <> Char.chr 0 then Printf.sprintf "-%c" _optopt else List.nth (CArray.to_list _argv) (!@optind - 1) in raise (Unknown_option unknown) let check_result _argv c opts select = if c = '?' then unknown_option _argv; let _optopt = if c = ':' then Char.chr !@optopt else c in let opt = List.find (select _optopt) opts in if c = ':' then begin match opt.arg with | `None _ -> assert false | `Optional _ -> () | `Required _ -> raise (Missing_argument (Char.chr !@optopt)) end; opt let string_of_short_opt { name; arg } = let arg = match arg with `None _ -> "" | _ -> ":" in Printf.sprintf "%c%s" name arg let getopt argv opts = let _argc = Array.length argv in let _argv = CArray.of_list string (Array.to_list argv) in let _short_opts = String.concat "" (List.map string_of_short_opt opts) in let _short_opts = ":" ^ _short_opts in let rec f () = let ret = getopt _argc (CArray.start _argv) _short_opts in if ret = -1 then remaining_argv _argv else begin let c = Char.chr ret in let { arg; _ } = check_result _argv c opts (fun c { name; _ } -> name = c) in apply_opt c arg; f () end in f () let string_of_long_opt { name; arg } = let arg = match arg with `None _ -> "" | _ -> ":" in Printf.sprintf "%c%s" (snd name) arg let long_opt_of_opt { name; arg } = let long_name, short_name = name in let _opt = make Option.t in setf _opt Option.name long_name; let has_arg = match arg with `None _ -> 0 | _ -> 1 in setf _opt Option.has_arg has_arg; setf _opt Option.flag (from_voidp int null); setf _opt Option._val (Char.code short_name); _opt let getopt_long_generic ~call fn argv opts = let _argc = Array.length argv in let _argv = CArray.of_list string (Array.to_list argv) in let _short_opts = String.concat "" (List.map string_of_long_opt opts) in let _short_opts = ":" ^ _short_opts in let _long_opts = List.map long_opt_of_opt opts in let _long_opts = CArray.of_list Option.t _long_opts in let index = allocate int 0 in let rec f () = let ret = Posix_errno.raise_on_none ~call (fun () -> fn _argc (CArray.start _argv) _short_opts (CArray.start _long_opts) index) in if ret = -1 then remaining_argv _argv else begin let c = Char.chr ret in let { arg; _ } = check_result _argv c opts (fun c { name; _ } -> snd name = c) in apply_opt c arg; f () end in f () let has_getopt_long = has_getopt_long () let has_getopt_long_only = has_getopt_long_only () let getopt_long x y z t u = let ret = getopt_long x y z t u in if has_getopt_long then Some ret else None let getopt_long_only x y z t u = let ret = getopt_long_only x y z t u in if has_getopt_long_only then Some ret else None let getopt_long = getopt_long_generic ~call:"getopt_long" getopt_long let getopt_long_only = getopt_long_generic ~call:"getopt_long_only" getopt_long_only ocaml-posix-4.0.2/modules/getopt/src/posix_getopt.mli000066400000000000000000000072641515131525300227520ustar00rootroot00000000000000(** POSIX command-line option parsing bindings. This module provides OCaml bindings to the POSIX getopt functions defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html} unistd.h}. It supports short options (single character), long options (GNU extension), and various argument handling modes. *) (** {1 Option Types} *) (** Short option: a single character (e.g., ['v'] for [-v]). *) type short = char (** Long option: a pair of (long name, short equivalent). For example, [("verbose", 'v')] matches both [--verbose] and [-v]. *) type long = string * char (** Argument specification for an option. - [`None f] - Option takes no argument. [f ()] is called when matched. - [`Optional f] - Option has an optional argument. [f (Some arg)] or [f None]. - [`Required f] - Option requires an argument. [f arg] is called with the value. *) type arg = [ `None of unit -> unit | `Optional of string option -> unit | `Required of string -> unit ] (** Option specification combining name and argument handler. *) type 'a opt = { name : 'a; arg : arg } (** {1 Exceptions} *) (** Raised when an unknown option is encountered. *) exception Unknown_option of string (** Raised when a required argument is missing for the given option. *) exception Missing_argument of char (** {1 Feature Detection} *) (** [true] if the system supports GNU-style long options via [getopt_long]. *) val has_getopt_long : bool (** [true] if the system supports [getopt_long_only] (long options with single dash). *) val has_getopt_long_only : bool (** {1 Configuration} *) (** Enable or disable error messages printed to stderr by getopt. Default is [true] (errors are printed). *) val print_error : bool -> unit (** Reset the getopt state for parsing a new set of arguments. Call this before parsing a new argv if you've already parsed arguments. *) val reset : unit -> unit (** {1 Parsing Functions} *) (** Parse command-line arguments using short options only. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html} getopt(3)}. @param argv The argument array to parse (typically [Sys.argv]). @param opts List of short option specifications. @return Array of non-option arguments (positional arguments). @raise Unknown_option if an unrecognized option is found. @raise Missing_argument if a required argument is missing. Example: {[ let verbose = ref false in let output = ref "out.txt" in let opts = [ { name = 'v'; arg = `None (fun () -> verbose := true) }; { name = 'o'; arg = `Required (fun s -> output := s) }; ] in let args = getopt Sys.argv opts in (* args contains non-option arguments *) ]} *) val getopt : string array -> short opt list -> string array (** Parse command-line arguments using long options (GNU extension). See getopt_long(3). Long options are specified as [--name] or [--name=value]. Each long option also has a short equivalent. @param argv The argument array to parse. @param opts List of long option specifications. @return Array of non-option arguments. @raise Unknown_option if an unrecognized option is found. @raise Missing_argument if a required argument is missing. *) val getopt_long : string array -> long opt list -> string array (** Like {!getopt_long} but also accepts long options with a single dash. For example, [-verbose] is treated the same as [--verbose]. @param argv The argument array to parse. @param opts List of long option specifications. @return Array of non-option arguments. *) val getopt_long_only : string array -> long opt list -> string array ocaml-posix-4.0.2/modules/getopt/src/stubs/000077500000000000000000000000001515131525300206525ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/getopt/src/stubs/dune000066400000000000000000000004521515131525300215310ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_getopt_stubs) (public_name posix-getopt.stubs) (libraries posix-getopt.types ctypes.stubs)) (rule (targets posix_getopt_generated_types.ml) (action (with-stdout-to %{targets} (run ../generator/gen_types_c)))) ocaml-posix-4.0.2/modules/getopt/src/stubs/posix_getopt_stubs.ml000066400000000000000000000022431515131525300251510ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F module Types = Posix_getopt_types.Def (Posix_getopt_generated_types) include Types let const_string_ptr = typedef (ptr string) "char * const *" let getopt = foreign "getopt" (int @-> const_string_ptr @-> string @-> returning int) let has_getopt_long = foreign "has_getopt_long" (void @-> returning bool) let getopt_long = foreign "getopt_long" (int @-> const_string_ptr @-> string @-> ptr Option.t @-> ptr int @-> returning int) let has_getopt_long_only = foreign "has_getopt_long_only" (void @-> returning bool) let getopt_long_only = foreign "getopt_long_only" (int @-> const_string_ptr @-> string @-> ptr Option.t @-> ptr int @-> returning int) let getoptarg = foreign "getoptarg" (void @-> returning (ptr char)) let getoptind = foreign "getoptind" (void @-> returning (ptr int)) let getopterr = foreign "getopterr" (void @-> returning (ptr int)) let getoptopt = foreign "getoptopt" (void @-> returning (ptr int)) let getoptreset = foreign "getoptreset" (void @-> returning (ptr int)) let strlen = foreign "strlen" (ptr char @-> returning int) end ocaml-posix-4.0.2/modules/getopt/src/types/000077500000000000000000000000001515131525300206565ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/getopt/src/types/dune000066400000000000000000000002421515131525300215320ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_getopt_types) (public_name posix-getopt.types) (libraries posix-base ctypes.stubs)) ocaml-posix-4.0.2/modules/getopt/src/types/posix_getopt_types.ml000066400000000000000000000005011515131525300251540ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct module Option = struct type t = unit let t = S.structure "option" let name = S.field t "name" S.string let has_arg = S.field t "has_arg" S.int let flag = S.field t "flag" (S.ptr S.int) let _val = S.field t "val" S.int let () = S.seal t end end ocaml-posix-4.0.2/modules/getopt/src/types/posix_getopt_types.mli000066400000000000000000000004621515131525300253330ustar00rootroot00000000000000open Ctypes module Def (S : Cstubs.Types.TYPE) : sig module Option : sig type t val t : t structure S.typ val name : (string, t structure) S.field val has_arg : (int, t structure) S.field val flag : (int ptr, t structure) S.field val _val : (int, t structure) S.field end end ocaml-posix-4.0.2/modules/getopt/test/000077500000000000000000000000001515131525300177025ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/getopt/test/autogenerated_tests.ml000066400000000000000000000134041515131525300243070ustar00rootroot00000000000000(* Error handling tests for posix-getopt with posix-errno *) open Posix_getopt (* Test that getopt handles empty argv correctly *) let test_getopt_empty_argv () = Printf.printf "Testing getopt with empty argv...\n%!"; reset (); let argv = [| "progname" |] in let opt = { name = 'a'; arg = `None (fun () -> ()) } in let ret = getopt argv [opt] in assert (Array.length ret = 0); Printf.printf " ✓ getopt handled empty argv correctly\n%!" (* Test that Missing_argument exception is raised properly *) let test_missing_argument_error () = Printf.printf "Testing Missing_argument exception...\n%!"; reset (); let argv = [| "progname"; "-a" |] in let opt = { name = 'a'; arg = `Required (fun _ -> ()) } in let got_error = ref false in (try ignore (getopt argv [opt]); Printf.printf " ✗ Should have raised Missing_argument\n%!"; assert false with Missing_argument 'a' -> got_error := true; Printf.printf " ✓ Missing_argument exception raised correctly\n%!"); assert !got_error (* Test that Unknown_option exception is raised properly *) let test_unknown_option_error () = Printf.printf "Testing Unknown_option exception...\n%!"; reset (); let argv = [| "progname"; "-z" |] in let opt = { name = 'a'; arg = `None (fun () -> ()) } in let got_error = ref false in (try ignore (getopt argv [opt]); Printf.printf " ✗ Should have raised Unknown_option\n%!"; assert false with Unknown_option "-z" -> got_error := true; Printf.printf " ✓ Unknown_option exception raised correctly\n%!"); assert !got_error (* Test getopt_long error handling (if available) *) let test_getopt_long_errors () = if not has_getopt_long then ( Printf.printf "Skipping getopt_long tests (not available)\n%!"; ()) else ( Printf.printf "Testing getopt_long error handling...\n%!"; (* Test unknown long option *) reset (); let argv = [| "progname"; "--unknown" |] in let opt = { name = ("known", 'k'); arg = `None (fun () -> ()) } in let got_error = ref false in (try ignore (getopt_long argv [opt]); Printf.printf " ✗ Should have raised Unknown_option\n%!"; assert false with Unknown_option "--unknown" -> got_error := true; Printf.printf " ✓ getopt_long raised Unknown_option for long option\n%!"); assert !got_error; (* Test missing required argument for long option *) (* Note: This test can cause issues on some platforms *) let sysname = Posix_uname.((uname ()).sysname) in if sysname = "Darwin" then Printf.printf " ⚠ Skipping missing argument test on Darwin (known issues)\n%!" else ( reset (); let argv = [| "progname"; "--require" |] in let opt = { name = ("require", 'r'); arg = `Required (fun _ -> ()) } in let got_error = ref false in (try ignore (getopt_long argv [opt]); Printf.printf " ✗ Should have raised Missing_argument\n%!" (* Note: behavior may vary by platform *) with | Missing_argument 'r' -> got_error := true; Printf.printf " ✓ getopt_long raised Missing_argument\n%!" | Unknown_option _ -> (* Some implementations might return unknown option *) got_error := true; Printf.printf " ✓ getopt_long raised error (platform-specific behavior)\n%!" | e -> Printf.printf " ⚠ Unexpected exception: %s\n%!" (Printexc.to_string e); got_error := true); if !got_error then Printf.printf " ✓ getopt_long error handling tested\n%!" else Printf.printf " ⚠ getopt_long did not raise expected error\n%!")) (* Test that optional arguments work correctly *) let test_optional_argument_handling () = Printf.printf "Testing optional argument handling...\n%!"; reset (); let argv = [| "progname"; "-o"; "value" |] in let received = ref None in let opt = { name = 'o'; arg = `Optional (fun arg -> received := Some arg) } in let ret = getopt argv [opt] in match !received with | Some (Some "value") -> assert (Array.length ret = 0); Printf.printf " ✓ Optional argument handled correctly\n%!" | _ -> Printf.printf " ✗ Optional argument not received correctly\n%!"; assert false (* Test that reset() properly resets state *) let test_reset_state () = Printf.printf "Testing reset() state management...\n%!"; (* First parse *) reset (); let argv1 = [| "progname"; "-a" |] in let called1 = ref false in let opt1 = { name = 'a'; arg = `None (fun () -> called1 := true) } in let _ = getopt argv1 [opt1] in assert !called1; (* Second parse with reset *) reset (); let argv2 = [| "progname"; "-b" |] in let called2 = ref false in let opt2 = { name = 'b'; arg = `None (fun () -> called2 := true) } in let _ = getopt argv2 [opt2] in assert !called2; Printf.printf " ✓ reset() properly resets parsing state\n%!" (* Test error message formatting *) let test_error_message_format () = Printf.printf "Testing error message formatting...\n%!"; let missing_arg_exception = Missing_argument 'x' in let msg1 = Printexc.to_string missing_arg_exception in assert (String.length msg1 > 0); let unknown_opt_exception = Unknown_option "--test" in let msg2 = Printexc.to_string unknown_opt_exception in assert (String.length msg2 > 0); Printf.printf " ✓ Error messages are properly formatted\n%!" let () = Printf.printf "\n=== POSIX Getopt Error Handling Tests ===\n\n%!"; test_getopt_empty_argv (); test_missing_argument_error (); test_unknown_option_error (); test_getopt_long_errors (); test_optional_argument_handling (); test_reset_state (); test_error_message_format (); Printf.printf "\n✓ All getopt error tests passed!\n%!" ocaml-posix-4.0.2/modules/getopt/test/dune000066400000000000000000000005301515131525300205560ustar00rootroot00000000000000(executable (name test) (libraries lwt.unix posix-uname posix-getopt ounit2)) (rule (alias citest) (package posix-getopt) (action (run %{exe:test.exe}))) (executable (name autogenerated_tests) (libraries posix-getopt posix-uname unix)) (rule (alias citest) (package posix-getopt) (action (run %{exe:autogenerated_tests.exe}))) ocaml-posix-4.0.2/modules/getopt/test/test.ml000066400000000000000000000166321515131525300212230ustar00rootroot00000000000000open OUnit2 open Posix_getopt let sysname = Posix_uname.((uname ()).sysname) module Process = struct let read_stdout cmd args = let cmd = (cmd, Array.append [| cmd |] args) in Lwt_process.pread_lines cmd |> Lwt_stream.to_list |> Lwt_main.run end let is_alpine = try Process.read_stdout "/bin/sh" [| "-c"; "cat /etc/os-release | grep alpine" |] <> [] with _ -> false let is_s390x_debian = try List.hd (Process.read_stdout "dpkg" [| "--print-architecture" |]) = "s390x" with _ -> false let test_short_flag _ = reset (); let argv = [| "progname"; "-b" |] in let test = ref false in let opt = { name = 'b'; arg = `None (fun () -> test := true) } in let ret = getopt argv [opt] in assert !test; assert (Array.length ret = 0) let test_short_required _ = reset (); let argv = [| "progname"; "-b"; "arg" |] in let test = ref "" in let opt = { name = 'b'; arg = `Required (fun arg -> test := arg) } in let ret = getopt argv [opt] in assert_equal "arg" !test; assert (Array.length ret = 0) let test_long_required_long _ = skip_if (not has_getopt_long) "Doesn't support getopt_long"; reset (); let argv = [| "progname"; "--bla"; "arg" |] in let test = ref "" in let opt = { name = ("bla", 'b'); arg = `Required (fun arg -> test := arg) } in let ret = getopt_long argv [opt] in assert_equal "arg" !test; assert (Array.length ret = 0) let test_long_required_short _ = skip_if (not has_getopt_long) "Doesn't support getopt_long"; reset (); let argv = [| "progname"; "-b"; "arg" |] in let test = ref "" in let opt = { name = ("bla", 'b'); arg = `Required (fun arg -> test := arg) } in let ret = getopt_long argv [opt] in assert_equal "arg" !test; assert (Array.length ret = 0) let test_short_required_no_arg _ = skip_if is_s390x_debian "Not supported"; reset (); let argv = [| "progname"; "-b" |] in let opt = { name = 'b'; arg = `Required (fun _ -> ()) } in let test = ref false in begin try ignore (getopt argv [opt]) with Missing_argument 'b' -> test := true end; assert !test let test_long_required_no_long_arg _ = skip_if (not has_getopt_long) "Doesn't support getopt_long"; skip_if (sysname = "Darwin") "Doesn't work on OSX"; skip_if is_alpine "Doesn't work in Alpine"; skip_if is_s390x_debian "Not supported"; reset (); let argv = [| "progname"; "--bla" |] in let opt = { name = ("bla", 'b'); arg = `Required (fun _ -> ()) } in let test = ref false in begin try ignore (getopt_long argv [opt]) with Missing_argument 'b' -> test := true end; assert !test let test_long_required_no_short_arg _ = skip_if (not has_getopt_long) "Doesn't support getopt_long"; skip_if is_s390x_debian "Not supported"; reset (); let argv = [| "progname"; "-b" |] in let opt = { name = ("bla", 'b'); arg = `Required (fun _ -> ()) } in let test = ref false in begin try ignore (getopt_long argv [opt]) with Missing_argument 'b' -> test := true end; assert !test let test_short_optional_no_arg _ = skip_if is_s390x_debian "Not supported"; reset (); let argv = [| "progname"; "-b" |] in let test = ref false in let opt = { name = 'b'; arg = `Optional (fun arg -> test := arg = None) } in let ret = getopt argv [opt] in assert !test; assert (Array.length ret = 0) let test_short_optional_arg _ = reset (); let argv = [| "progname"; "-b"; "yup" |] in let test = ref false in let opt = { name = 'b'; arg = `Optional (fun arg -> test := arg = Some "yup") } in let ret = getopt argv [opt] in assert !test; assert (Array.length ret = 0) let test_remaining_arg _ = reset (); let argv = [| "progname"; "--"; "-b" |] in let opt = { name = 'b'; arg = `None (fun () -> ()) } in let ret = getopt argv [opt] in assert_equal [| "-b" |] ret let test_permuted_remaining_arg _ = skip_if (sysname = "Darwin") "Doesn't work on OSX"; skip_if is_alpine "Doesn't work in Alpine"; reset (); let argv = [| "progname"; "bla"; "-b" |] in let opt = { name = 'b'; arg = `None (fun () -> ()) } in let ret = getopt argv [opt] in assert_equal [| "bla" |] ret let test_complex_scenario _ = skip_if (not has_getopt_long) "Doesn't support getopt_long"; reset (); let argv = [| "progname"; "-a"; "-cret"; "-bopt"; "--gno"; "gna"; "--foo"; "--foo"; "--"; "bla"; |] in let a = ref false in let b = ref "" in let c = ref (Some "value") in let gno = ref "" in let foo = ref false in let opts = [ { name = ("aa", 'a'); arg = `None (fun () -> a := true) }; { name = ("bb", 'b'); arg = `Required (fun v -> b := v) }; { name = ("cc", 'c'); arg = `Optional (fun v -> c := v) }; { name = ("gno", 'g'); arg = `Required (fun v -> gno := v) }; { name = ("foo", 'f'); arg = `None (fun () -> foo := true) }; ] in let ret = getopt_long argv opts in assert !a; assert_equal "opt" !b; assert_equal (Some "ret") !c; assert_equal "gna" !gno; assert_equal true !foo; assert_equal [| "bla" |] ret let test_short_unknown_before _ = reset (); let argv = [| "progname"; "-u"; "-b" |] in let test = ref true in let opt = { name = 'b'; arg = `None (fun () -> test := false) } in try ignore (getopt argv [opt]); assert false with Unknown_option "-u" -> assert !test let test_short_unknown_after _ = skip_if is_s390x_debian "Not supported"; reset (); let argv = [| "progname"; "-b"; "--unknown" |] in let test = ref false in let opt = { name = 'b'; arg = `None (fun () -> test := true) } in try ignore (getopt argv [opt]); assert false with Unknown_option "--" -> assert !test let test_long_unknown_before _ = skip_if (not has_getopt_long) "Doesn't support getopt_long"; reset (); let argv = [| "progname"; "--unknown"; "--bla" |] in let test = ref true in let opt = { name = ("bla", 'b'); arg = `None (fun () -> test := false) } in try ignore (getopt_long argv [opt]); assert false with Unknown_option "--unknown" -> assert !test let test_long_unknown_after _ = skip_if (not has_getopt_long) "Doesn't support getopt_long"; reset (); let argv = [| "progname"; "--bla"; "--unknown" |] in let test = ref false in let opt = { name = ("bla", 'b'); arg = `None (fun () -> test := true) } in try ignore (getopt_long argv [opt]); assert false with Unknown_option "--unknown" -> assert !test let suite = "getopt tests" >::: [ "test_short_flag" >:: test_short_flag; "test_short_required" >:: test_short_required; "test_long_required_long" >:: test_long_required_long; "test_long_required_short" >:: test_long_required_short; "test_short_required_no_arg" >:: test_short_required_no_arg; "test_long_required_no_short_arg" >:: test_long_required_no_short_arg; "test_long_required_no_long_arg" >:: test_long_required_no_long_arg; "test_short_optional_no_arg" >:: test_short_optional_no_arg; "test_short_optional_arg" >:: test_short_optional_arg; "test_remaining_arg" >:: test_remaining_arg; "test_permuted_remaining_arg" >:: test_permuted_remaining_arg; "test_complex_scenario" >:: test_complex_scenario; "test_short_unknown_before" >:: test_short_unknown_before; "test_short_unknown_after" >:: test_short_unknown_after; "test_long_unknown_before" >:: test_long_unknown_before; "test_long_unknown_after" >:: test_long_unknown_after; ] let () = run_test_tt_main suite ocaml-posix-4.0.2/modules/math2/000077500000000000000000000000001515131525300164345ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/math2/CHANGES000066400000000000000000000005071515131525300174310ustar00rootroot000000000000002.2.0 (2025-01-30) ===== * Fix copy code in `getaddrinfo`. 2.1.0 (2025-01-16) ===== * Added `posix-math2` * Invoke `wine64` only when available. * Added `sockaddr_len` in `ocaml-posix`. * Add support for string and optional `port. * Add support for `hints`. 2.0.2 (2023-02-08) ===== **posix-time2** * Added `clock_nanosleep` ocaml-posix-4.0.2/modules/math2/src/000077500000000000000000000000001515131525300172235ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/math2/src/constants/000077500000000000000000000000001515131525300212375ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/math2/src/constants/dune000066400000000000000000000001461515131525300221160ustar00rootroot00000000000000(library (name posix_math_constants) (public_name posix-math2.constants) (libraries ctypes.stubs)) ocaml-posix-4.0.2/modules/math2/src/constants/posix_math_constants.ml000066400000000000000000000010071515131525300260360ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct let sizeof_float_t = S.constant "SIZEOF_FLOAT_T" S.int let alignof_float_t = S.constant "ALIGNOF_FLOAT_T" S.int let sizeof_double_t = S.constant "SIZEOF_DOUBLE_T" S.int let alignof_double_t = S.constant "ALIGNOF_DOUBLE_T" S.int let fp_infinite = S.constant "FP_INFINITE" S.int let fp_nan = S.constant "FP_NAN" S.int let fp_normal = S.constant "FP_NORMAL" S.int let fp_subnormal = S.constant "FP_SUBNORMAL" S.int let fp_zero = S.constant "FP_ZERO" S.int end ocaml-posix-4.0.2/modules/math2/src/dune000066400000000000000000000010201515131525300200720ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_math) (public_name posix-math2) (synopsis "posix-math2 provides access to the features exposed in math.h") (foreign_stubs (language c) (names posix_math_generated_stubs)) (libraries unix ctypes posix-math2.types posix-math2.stubs)) (rule (targets posix_math_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_math_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) ocaml-posix-4.0.2/modules/math2/src/generator/000077500000000000000000000000001515131525300212115ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/math2/src/generator/dune000066400000000000000000000016761515131525300221010ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-math2.stubs posix-base)) (executable (name gen_types_c) (modules gen_types_c) (libraries posix-math2.types posix-base)) (rule (targets gen_types.c) (action (run ./gen_types_c.exe %{targets}))) (rule (targets gen_types_c_target.exe) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-math2.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c_target.exe) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/math2/src/generator/gen_constants_c.ml000066400000000000000000000005431515131525300247140ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_math_constants.Def let c_headers = {| #include #include #define SIZEOF_FLOAT_T sizeof(float_t) #define ALIGNOF_FLOAT_T alignof(float_t) #define SIZEOF_DOUBLE_T sizeof(double_t) #define ALIGNOF_DOUBLE_T alignof(double_t) |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/math2/src/generator/gen_stubs.ml000066400000000000000000000024421515131525300235360ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_math_stubs.Def let c_headers = {| #include double ocaml_posix_math_huge_val() { return HUGE_VAL; } float ocaml_posix_math_huge_valf() { return HUGE_VALF; } long double ocaml_posix_math_huge_vall() { return HUGE_VALL; } float ocaml_posix_math_infinity() { return INFINITY; } float ocaml_posix_math_nan() { return NAN; } int *ocaml_posix_math_signgam() { return &signgam; } double ocaml_posix_math_m_e() { return M_E; }; double ocaml_posix_math_m_log2e() { return M_LOG2E; }; double ocaml_posix_math_m_log10e() { return M_LOG10E; }; double ocaml_posix_math_m_ln2() { return M_LN2; }; double ocaml_posix_math_m_ln10() { return M_LN10; }; double ocaml_posix_math_m_pi() { return M_PI; }; double ocaml_posix_math_m_pi_2() { return M_PI_2; }; double ocaml_posix_math_m_pi_4() { return M_PI_4; }; double ocaml_posix_math_m_1_pi() { return M_1_PI; }; double ocaml_posix_math_m_2_pi() { return M_2_PI; }; double ocaml_posix_math_m_2_sqrtpi() { return M_2_SQRTPI; }; double ocaml_posix_math_m_sqrt2() { return M_SQRT2; }; double ocaml_posix_math_m_sqrt1_2() { return M_SQRT1_2; }; |} let concurrency = Cstubs.unlocked let prefix = "posix_math" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/math2/src/generator/gen_types_c.ml000066400000000000000000000002401515131525300240360ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_math_types.Def let c_headers = {| #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/math2/src/posix_math.ml000066400000000000000000000015651515131525300217370ustar00rootroot00000000000000include Posix_math_stubs.Def (Posix_math_generated_stubs) type fp_type = [ `Infinite | `NaN | `Normal | `Subnormal | `Zero ] let fpclassify f = match fpclassify f with | x when x = fp_infinite -> Some `Infinite | x when x = fp_nan -> Some `NaN | x when x = fp_normal -> Some `Normal | x when x = fp_subnormal -> Some `Subnormal | x when x = fp_zero -> Some `Zero | _ -> None let huge_val = huge_val () let huge_valf = huge_valf () let huge_vall = huge_vall () let infinity = infinity () let nan_constant = nan_constant () let signgam = signgam () let m_e = m_e () let m_log2e = m_log2e () let m_log10e = m_log10e () let m_ln2 = m_ln2 () let m_ln10 = m_ln10 () let m_pi = m_pi () let m_pi_2 = m_pi_2 () let m_pi_4 = m_pi_4 () let m_1_pi = m_1_pi () let m_2_pi = m_2_pi () let m_2_sqrtpi = m_2_sqrtpi () let m_sqrt2 = m_sqrt2 () let m_sqrt1_2 = m_sqrt1_2 () ocaml-posix-4.0.2/modules/math2/src/posix_math.mli000066400000000000000000000226121515131525300221040ustar00rootroot00000000000000(** POSIX mathematical functions bindings. This module provides OCaml bindings to the POSIX math functions defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/math.h.html} math.h}. Functions are provided in three variants: - Double precision: [sin], [cos], etc. - Single precision (float): [sinf], [cosf], etc. - Extended precision (long double): [sinl], [cosl], etc. Most functions map directly to their C equivalents. *) open Ctypes (** {1 Floating-Point Classification} *) (** Result of floating-point classification. *) type fp_type = [ `Infinite (** Positive or negative infinity *) | `NaN (** Not a number *) | `Normal (** Normal floating-point number *) | `Subnormal (** Subnormal (denormalized) number *) | `Zero ] (** Positive or negative zero *) (** Classify a floating-point value. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fpclassify.html} fpclassify(3)}. *) val fpclassify : float -> fp_type option (** Test if a value is finite (not infinite and not NaN). *) val isfinite : float -> bool (** Test if a value is infinite. *) val isinf : float -> bool (** Test if a value is NaN (not a number). *) val isnan : float -> bool (** Test if a value is a normal number (not zero, subnormal, infinite, or NaN). *) val isnormal : float -> bool (** Test if a value is negative (including negative zero). *) val signbit : float -> bool (** {1 Comparison Macros} *) (** [isgreater x y] is [true] if [x > y], without raising exceptions for NaN. *) val isgreater : float -> float -> bool (** [isgreaterequal x y] is [true] if [x >= y], without raising exceptions for NaN. *) val isgreaterequal : float -> float -> bool (** [isless x y] is [true] if [x < y], without raising exceptions for NaN. *) val isless : float -> float -> bool (** [islessequal x y] is [true] if [x <= y], without raising exceptions for NaN. *) val islessequal : float -> float -> bool (** [islessgreater x y] is [true] if [x < y] or [x > y], without raising exceptions for NaN. *) val islessgreater : float -> float -> bool (** [isunordered x y] is [true] if either [x] or [y] is NaN. *) val isunordered : float -> float -> bool (** {1 Mathematical Constants} *) (** e (Euler's number) *) val m_e : float (** log2(e) *) val m_log2e : float (** log10(e) *) val m_log10e : float (** ln(2) *) val m_ln2 : float (** ln(10) *) val m_ln10 : float (** pi *) val m_pi : float (** pi/2 *) val m_pi_2 : float (** pi/4 *) val m_pi_4 : float (** 1/pi *) val m_1_pi : float (** 2/pi *) val m_2_pi : float (** 2/sqrt(pi) *) val m_2_sqrtpi : float (** sqrt(2) *) val m_sqrt2 : float (** 1/sqrt(2) *) val m_sqrt1_2 : float (** {1 Special Values} *) (** Large positive double value (may be infinity) *) val huge_val : float (** Large positive float value *) val huge_valf : float (** Large positive long double value *) val huge_vall : LDouble.t (** Positive infinity *) val infinity : float (** A quiet NaN value *) val nan_constant : float (** {1 Ctypes} *) val float_t : float typ val double_t : float typ (** Sign of gamma function result *) val signgam : int ptr (** {1 Trigonometric Functions} *) val acos : float -> float val acosf : float -> float val acosl : LDouble.t -> LDouble.t val asin : float -> float val asinf : float -> float val asinl : LDouble.t -> LDouble.t val atan : float -> float val atanf : float -> float val atanl : LDouble.t -> LDouble.t val atan2 : float -> float -> float val atan2f : float -> float -> float val atan2l : LDouble.t -> LDouble.t -> LDouble.t val cos : float -> float val cosf : float -> float val cosl : LDouble.t -> LDouble.t val sin : float -> float val sinf : float -> float val sinl : LDouble.t -> LDouble.t val tan : float -> float val tanf : float -> float val tanl : LDouble.t -> LDouble.t (** {1 Hyperbolic Functions} *) val acosh : float -> float val acoshf : float -> float val acoshl : LDouble.t -> LDouble.t val asinh : float -> float val asinhf : float -> float val asinhl : LDouble.t -> LDouble.t val atanh : float -> float val atanhf : float -> float val atanhl : LDouble.t -> LDouble.t val cosh : float -> float val coshf : float -> float val coshl : LDouble.t -> LDouble.t val sinh : float -> float val sinhf : float -> float val sinhl : LDouble.t -> LDouble.t val tanh : float -> float val tanhf : float -> float val tanhl : LDouble.t -> LDouble.t (** {1 Exponential and Logarithmic Functions} *) val exp : float -> float val expf : float -> float val expl : LDouble.t -> LDouble.t val exp2 : float -> float val exp2f : float -> float val exp2l : LDouble.t -> LDouble.t val expm1 : float -> float val expm1f : float -> float val expm1l : LDouble.t -> LDouble.t val frexp : float -> int ptr -> float val frexpf : float -> int ptr -> float val frexpl : LDouble.t -> int ptr -> LDouble.t val ilogb : float -> int val ilogbf : float -> int val ilogbl : LDouble.t -> int val ldexp : float -> int -> float val ldexpf : float -> int -> float val ldexpl : LDouble.t -> int -> LDouble.t val log : float -> float val logf : float -> float val logl : LDouble.t -> LDouble.t val log10 : float -> float val log10f : float -> float val log10l : LDouble.t -> LDouble.t val log1p : float -> float val log1pf : float -> float val log1pl : LDouble.t -> LDouble.t val log2 : float -> float val log2f : float -> float val log2l : LDouble.t -> LDouble.t val logb : float -> float val logbf : float -> float val logbl : LDouble.t -> LDouble.t val modf : float -> float ptr -> float val modff : float -> float ptr -> float val modfl : LDouble.t -> LDouble.t ptr -> LDouble.t val scalbln : float -> Signed.Long.t -> float val scalblnf : float -> Signed.Long.t -> float val scalblnl : LDouble.t -> Signed.Long.t -> LDouble.t val scalbn : float -> int -> float val scalbnf : float -> int -> float val scalbnl : LDouble.t -> int -> LDouble.t (** {1 Power and Absolute Value Functions} *) val cbrt : float -> float val cbrtf : float -> float val cbrtl : LDouble.t -> LDouble.t val fabs : float -> float val fabsf : float -> float val fabsl : LDouble.t -> LDouble.t val hypot : float -> float -> float val hypotf : float -> float -> float val hypotl : LDouble.t -> LDouble.t -> LDouble.t val pow : float -> float -> float val powf : float -> float -> float val powl : LDouble.t -> LDouble.t -> LDouble.t val sqrt : float -> float val sqrtf : float -> float val sqrtl : LDouble.t -> LDouble.t (** {1 Error and Gamma Functions} *) val erf : float -> float val erff : float -> float val erfl : LDouble.t -> LDouble.t val erfc : float -> float val erfcf : float -> float val erfcl : LDouble.t -> LDouble.t val lgamma : float -> float val lgammaf : float -> float val lgammal : LDouble.t -> LDouble.t val tgamma : float -> float val tgammaf : float -> float val tgammal : LDouble.t -> LDouble.t (** {1 Nearest Integer Functions} *) val ceil : float -> float val ceilf : float -> float val ceill : LDouble.t -> LDouble.t val floor : float -> float val floorf : float -> float val floorl : LDouble.t -> LDouble.t val nearbyint : float -> float val nearbyintf : float -> float val nearbyintl : LDouble.t -> LDouble.t val rint : float -> float val rintf : float -> float val rintl : LDouble.t -> LDouble.t val lrint : float -> Signed.Long.t val lrintf : float -> Signed.Long.t val lrintl : LDouble.t -> Signed.Long.t val llrint : float -> Signed.LLong.t val llrintf : float -> Signed.LLong.t val llrintl : LDouble.t -> Signed.LLong.t val round : float -> float val roundf : float -> float val roundl : LDouble.t -> LDouble.t val lround : float -> Signed.Long.t val lroundf : float -> Signed.Long.t val lroundl : LDouble.t -> Signed.Long.t val llround : float -> Signed.LLong.t val llroundf : float -> Signed.LLong.t val llroundl : LDouble.t -> Signed.LLong.t val trunc : float -> float val truncf : float -> float val truncl : LDouble.t -> LDouble.t (** {1 Remainder Functions} *) val fmod : float -> float -> float val fmodf : float -> float -> float val fmodl : LDouble.t -> LDouble.t -> LDouble.t val remainder : float -> float -> float val remainderf : float -> float -> float val remainderl : LDouble.t -> LDouble.t -> LDouble.t val remquo : float -> float -> int ptr -> float val remquof : float -> float -> int ptr -> float val remquol : LDouble.t -> LDouble.t -> int ptr -> LDouble.t (** {1 Manipulation Functions} *) val copysign : float -> float -> float val copysignf : float -> float -> float val copysignl : LDouble.t -> LDouble.t -> LDouble.t val nan : string -> float val nanf : string -> float val nanl : string -> LDouble.t val nextafter : float -> float -> float val nextafterf : float -> float -> float val nextafterl : LDouble.t -> LDouble.t -> LDouble.t val nexttoward : float -> LDouble.t -> float val nexttowardf : float -> LDouble.t -> float val nexttowardl : LDouble.t -> LDouble.t -> LDouble.t (** {1 Positive Difference and Multiply-Add} *) val fdim : float -> float -> float val fdimf : float -> float -> float val fdiml : LDouble.t -> LDouble.t -> LDouble.t val fma : float -> float -> float -> float val fmaf : float -> float -> float -> float val fmal : LDouble.t -> LDouble.t -> LDouble.t -> LDouble.t val fmax : float -> float -> float val fmaxf : float -> float -> float val fmaxl : LDouble.t -> LDouble.t -> LDouble.t val fmin : float -> float -> float val fminf : float -> float -> float val fminl : LDouble.t -> LDouble.t -> LDouble.t (** {1 Bessel Functions} *) val j0 : float -> float val j1 : float -> float val jn : int -> float -> float val y0 : float -> float val y1 : float -> float val yn : int -> float -> float ocaml-posix-4.0.2/modules/math2/src/stubs/000077500000000000000000000000001515131525300203635ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/math2/src/stubs/dune000066400000000000000000000013111515131525300212350ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_math_stubs) (public_name posix-math2.stubs) (libraries posix-math2.types ctypes.stubs)) (rule (targets posix_math_generated_types.ml) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps ../../../../base/exec_path (:gen ../generator/gen_types_c_target.exe)) (action (with-stdout-to %{targets} (system "%{read:../../../../base/exec_path} %{ocaml-config:system} %{gen}")))) (rule (targets posix_math_generated_types.ml) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps (:gen ../generator/gen_types_c_target.exe)) (action (with-stdout-to %{targets} (run %{gen})))) ocaml-posix-4.0.2/modules/math2/src/stubs/posix_math_stubs.ml000066400000000000000000000332141515131525300243130ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F module Types = Posix_math_types.Def (Posix_math_generated_types) include Types let fpclassify = foreign "fpclassify" (float @-> returning int) let isfinite = foreign "isfinite" (double @-> returning bool) let isgreater = foreign "isgreater" (double @-> double @-> returning bool) let isgreaterequal = foreign "isgreaterequal" (double @-> double @-> returning bool) let isinf = foreign "isinf" (double @-> returning bool) let isless = foreign "isless" (double @-> double @-> returning bool) let islessequal = foreign "islessequal" (double @-> double @-> returning bool) let islessgreater = foreign "islessgreater" (double @-> double @-> returning bool) let isnan = foreign "isnan" (double @-> returning bool) let isnormal = foreign "isnormal" (double @-> returning bool) let isunordered = foreign "isunordered" (double @-> double @-> returning bool) let signbit = foreign "signbit" (double @-> returning bool) let m_e = foreign "ocaml_posix_math_m_e" (void @-> returning float) let m_log2e = foreign "ocaml_posix_math_m_log2e" (void @-> returning float) let m_log10e = foreign "ocaml_posix_math_m_log10e" (void @-> returning float) let m_ln2 = foreign "ocaml_posix_math_m_ln2" (void @-> returning float) let m_ln10 = foreign "ocaml_posix_math_m_ln10" (void @-> returning float) let m_pi = foreign "ocaml_posix_math_m_pi" (void @-> returning float) let m_pi_2 = foreign "ocaml_posix_math_m_pi_2" (void @-> returning float) let m_pi_4 = foreign "ocaml_posix_math_m_pi_4" (void @-> returning float) let m_1_pi = foreign "ocaml_posix_math_m_1_pi" (void @-> returning float) let m_2_pi = foreign "ocaml_posix_math_m_2_pi" (void @-> returning float) let m_2_sqrtpi = foreign "ocaml_posix_math_m_2_sqrtpi" (void @-> returning float) let m_sqrt2 = foreign "ocaml_posix_math_m_sqrt2" (void @-> returning float) let m_sqrt1_2 = foreign "ocaml_posix_math_m_sqrt1_2" (void @-> returning float) let signgam = foreign "ocaml_posix_math_signgam" (void @-> returning (ptr int)) let huge_val = foreign "ocaml_posix_math_huge_val" (void @-> returning double) let huge_valf = foreign "ocaml_posix_math_huge_valf" (void @-> returning float) let huge_vall = foreign "ocaml_posix_math_huge_vall" (void @-> returning ldouble) let infinity = foreign "ocaml_posix_math_infinity" (void @-> returning float) let nan_constant = foreign "ocaml_posix_math_nan" (void @-> returning float) let acos = foreign "acos" (double @-> returning double) let acosf = foreign "acosf" (float @-> returning float) let acosh = foreign "acosh" (double @-> returning double) let acoshf = foreign "acoshf" (float @-> returning float) let acoshl = foreign "acoshl" (ldouble @-> returning ldouble) let acosl = foreign "acosl" (ldouble @-> returning ldouble) let asin = foreign "asin" (double @-> returning double) let asinf = foreign "asinf" (float @-> returning float) let asinh = foreign "asinh" (double @-> returning double) let asinhf = foreign "asinhf" (float @-> returning float) let asinhl = foreign "asinhl" (ldouble @-> returning ldouble) let asinl = foreign "asinl" (ldouble @-> returning ldouble) let atan = foreign "atan" (double @-> returning double) let atan2 = foreign "atan2" (double @-> double @-> returning double) let atan2f = foreign "atan2f" (float @-> float @-> returning float) let atan2l = foreign "atan2l" (ldouble @-> ldouble @-> returning ldouble) let atanf = foreign "atanf" (float @-> returning float) let atanh = foreign "atanh" (double @-> returning double) let atanhf = foreign "atanhf" (float @-> returning float) let atanhl = foreign "atanhl" (ldouble @-> returning ldouble) let atanl = foreign "atanl" (ldouble @-> returning ldouble) let cbrt = foreign "cbrt" (double @-> returning double) let cbrtf = foreign "cbrtf" (float @-> returning float) let cbrtl = foreign "cbrtl" (ldouble @-> returning ldouble) let ceil = foreign "ceil" (double @-> returning double) let ceilf = foreign "ceilf" (float @-> returning float) let ceill = foreign "ceill" (ldouble @-> returning ldouble) let copysign = foreign "copysign" (double @-> double @-> returning double) let copysignf = foreign "copysignf" (float @-> float @-> returning float) let copysignl = foreign "copysignl" (ldouble @-> ldouble @-> returning ldouble) let cos = foreign "cos" (double @-> returning double) let cosf = foreign "cosf" (float @-> returning float) let cosh = foreign "cosh" (double @-> returning double) let coshf = foreign "coshf" (float @-> returning float) let coshl = foreign "coshl" (ldouble @-> returning ldouble) let cosl = foreign "cosl" (ldouble @-> returning ldouble) let erf = foreign "erf" (double @-> returning double) let erfc = foreign "erfc" (double @-> returning double) let erfcf = foreign "erfcf" (float @-> returning float) let erfcl = foreign "erfcl" (ldouble @-> returning ldouble) let erff = foreign "erff" (float @-> returning float) let erfl = foreign "erfl" (ldouble @-> returning ldouble) let exp = foreign "exp" (double @-> returning double) let exp2 = foreign "exp2" (double @-> returning double) let exp2f = foreign "exp2f" (float @-> returning float) let exp2l = foreign "exp2l" (ldouble @-> returning ldouble) let expf = foreign "expf" (float @-> returning float) let expl = foreign "expl" (ldouble @-> returning ldouble) let expm1 = foreign "expm1" (double @-> returning double) let expm1f = foreign "expm1f" (float @-> returning float) let expm1l = foreign "expm1l" (ldouble @-> returning ldouble) let fabs = foreign "fabs" (double @-> returning double) let fabsf = foreign "fabsf" (float @-> returning float) let fabsl = foreign "fabsl" (ldouble @-> returning ldouble) let fdim = foreign "fdim" (double @-> double @-> returning double) let fdimf = foreign "fdimf" (float @-> float @-> returning float) let fdiml = foreign "fdiml" (ldouble @-> ldouble @-> returning ldouble) let floor = foreign "floor" (double @-> returning double) let floorf = foreign "floorf" (float @-> returning float) let floorl = foreign "floorl" (ldouble @-> returning ldouble) let fma = foreign "fma" (double @-> double @-> double @-> returning double) let fmaf = foreign "fmaf" (float @-> float @-> float @-> returning float) let fmal = foreign "fmal" (ldouble @-> ldouble @-> ldouble @-> returning ldouble) let fmax = foreign "fmax" (double @-> double @-> returning double) let fmaxf = foreign "fmaxf" (float @-> float @-> returning float) let fmaxl = foreign "fmaxl" (ldouble @-> ldouble @-> returning ldouble) let fmin = foreign "fmin" (double @-> double @-> returning double) let fminf = foreign "fminf" (float @-> float @-> returning float) let fminl = foreign "fminl" (ldouble @-> ldouble @-> returning ldouble) let fmod = foreign "fmod" (double @-> double @-> returning double) let fmodf = foreign "fmodf" (float @-> float @-> returning float) let fmodl = foreign "fmodl" (ldouble @-> ldouble @-> returning ldouble) let frexp = foreign "frexp" (double @-> ptr int @-> returning double) let frexpf = foreign "frexpf" (float @-> ptr int @-> returning float) let frexpl = foreign "frexpl" (ldouble @-> ptr int @-> returning ldouble) let hypot = foreign "hypot" (double @-> double @-> returning double) let hypotf = foreign "hypotf" (float @-> float @-> returning float) let hypotl = foreign "hypotl" (ldouble @-> ldouble @-> returning ldouble) let ilogb = foreign "ilogb" (double @-> returning int) let ilogbf = foreign "ilogbf" (float @-> returning int) let ilogbl = foreign "ilogbl" (ldouble @-> returning int) let j0 = foreign "j0" (double @-> returning double) let j1 = foreign "j1" (double @-> returning double) let jn = foreign "jn" (int @-> double @-> returning double) let ldexp = foreign "ldexp" (double @-> int @-> returning double) let ldexpf = foreign "ldexpf" (float @-> int @-> returning float) let ldexpl = foreign "ldexpl" (ldouble @-> int @-> returning ldouble) let lgamma = foreign "lgamma" (double @-> returning double) let lgammaf = foreign "lgammaf" (float @-> returning float) let lgammal = foreign "lgammal" (ldouble @-> returning ldouble) let llrint = foreign "llrint" (double @-> returning llong) let llrintf = foreign "llrintf" (float @-> returning llong) let llrintl = foreign "llrintl" (ldouble @-> returning llong) let llround = foreign "llround" (double @-> returning llong) let llroundf = foreign "llroundf" (float @-> returning llong) let llroundl = foreign "llroundl" (ldouble @-> returning llong) let log = foreign "log" (double @-> returning double) let log10 = foreign "log10" (double @-> returning double) let log10f = foreign "log10f" (float @-> returning float) let log10l = foreign "log10l" (ldouble @-> returning ldouble) let log1p = foreign "log1p" (double @-> returning double) let log1pf = foreign "log1pf" (float @-> returning float) let log1pl = foreign "log1pl" (ldouble @-> returning ldouble) let log2 = foreign "log2" (double @-> returning double) let log2f = foreign "log2f" (float @-> returning float) let log2l = foreign "log2l" (ldouble @-> returning ldouble) let logb = foreign "logb" (double @-> returning double) let logbf = foreign "logbf" (float @-> returning float) let logbl = foreign "logbl" (ldouble @-> returning ldouble) let logf = foreign "logf" (float @-> returning float) let logl = foreign "logl" (ldouble @-> returning ldouble) let lrint = foreign "lrint" (double @-> returning long) let lrintf = foreign "lrintf" (float @-> returning long) let lrintl = foreign "lrintl" (ldouble @-> returning long) let lround = foreign "lround" (double @-> returning long) let lroundf = foreign "lroundf" (float @-> returning long) let lroundl = foreign "lroundl" (ldouble @-> returning long) let modf = foreign "modf" (double @-> ptr double @-> returning double) let modff = foreign "modff" (float @-> ptr float @-> returning float) let modfl = foreign "modfl" (ldouble @-> ptr ldouble @-> returning ldouble) let nan = foreign "nan" (string @-> returning double) let nanf = foreign "nanf" (string @-> returning float) let nanl = foreign "nanl" (string @-> returning ldouble) let nearbyint = foreign "nearbyint" (double @-> returning double) let nearbyintf = foreign "nearbyintf" (float @-> returning float) let nearbyintl = foreign "nearbyintl" (ldouble @-> returning ldouble) let nextafter = foreign "nextafter" (double @-> double @-> returning double) let nextafterf = foreign "nextafterf" (float @-> float @-> returning float) let nextafterl = foreign "nextafterl" (ldouble @-> ldouble @-> returning ldouble) let nexttoward = foreign "nexttoward" (double @-> ldouble @-> returning double) let nexttowardf = foreign "nexttowardf" (float @-> ldouble @-> returning float) let nexttowardl = foreign "nexttowardl" (ldouble @-> ldouble @-> returning ldouble) let pow = foreign "pow" (double @-> double @-> returning double) let powf = foreign "powf" (float @-> float @-> returning float) let powl = foreign "powl" (ldouble @-> ldouble @-> returning ldouble) let remainder = foreign "remainder" (double @-> double @-> returning double) let remainderf = foreign "remainderf" (float @-> float @-> returning float) let remainderl = foreign "remainderl" (ldouble @-> ldouble @-> returning ldouble) let remquo = foreign "remquo" (double @-> double @-> ptr int @-> returning double) let remquof = foreign "remquof" (float @-> float @-> ptr int @-> returning float) let remquol = foreign "remquol" (ldouble @-> ldouble @-> ptr int @-> returning ldouble) let rint = foreign "rint" (double @-> returning double) let rintf = foreign "rintf" (float @-> returning float) let rintl = foreign "rintl" (ldouble @-> returning ldouble) let round = foreign "round" (double @-> returning double) let roundf = foreign "roundf" (float @-> returning float) let roundl = foreign "roundl" (ldouble @-> returning ldouble) let scalbln = foreign "scalbln" (double @-> long @-> returning double) let scalblnf = foreign "scalblnf" (float @-> long @-> returning float) let scalblnl = foreign "scalblnl" (ldouble @-> long @-> returning ldouble) let scalbn = foreign "scalbn" (double @-> int @-> returning double) let scalbnf = foreign "scalbnf" (float @-> int @-> returning float) let scalbnl = foreign "scalbnl" (ldouble @-> int @-> returning ldouble) let sin = foreign "sin" (double @-> returning double) let sinf = foreign "sinf" (float @-> returning float) let sinh = foreign "sinh" (double @-> returning double) let sinhf = foreign "sinhf" (float @-> returning float) let sinhl = foreign "sinhl" (ldouble @-> returning ldouble) let sinl = foreign "sinl" (ldouble @-> returning ldouble) let sqrt = foreign "sqrt" (double @-> returning double) let sqrtf = foreign "sqrtf" (float @-> returning float) let sqrtl = foreign "sqrtl" (ldouble @-> returning ldouble) let tan = foreign "tan" (double @-> returning double) let tanf = foreign "tanf" (float @-> returning float) let tanh = foreign "tanh" (double @-> returning double) let tanhf = foreign "tanhf" (float @-> returning float) let tanhl = foreign "tanhl" (ldouble @-> returning ldouble) let tanl = foreign "tanl" (ldouble @-> returning ldouble) let tgamma = foreign "tgamma" (double @-> returning double) let tgammaf = foreign "tgammaf" (float @-> returning float) let tgammal = foreign "tgammal" (ldouble @-> returning ldouble) let trunc = foreign "trunc" (double @-> returning double) let truncf = foreign "truncf" (float @-> returning float) let truncl = foreign "truncl" (ldouble @-> returning ldouble) let y0 = foreign "y0" (double @-> returning double) let y1 = foreign "y1" (double @-> returning double) let yn = foreign "yn" (int @-> double @-> returning double) end ocaml-posix-4.0.2/modules/math2/src/types/000077500000000000000000000000001515131525300203675ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/math2/src/types/dune000066400000000000000000000013501515131525300212440ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_math_types) (public_name posix-math2.types) (libraries posix-math2.constants posix-base ctypes.stubs)) (rule (targets posix_math_generated_constants.ml) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps ../../../../base/exec_path (:gen ../generator/gen_constants_c_target.exe)) (action (with-stdout-to %{targets} (system "%{read:../../../../base/exec_path} %{ocaml-config:system} %{gen}")))) (rule (targets posix_math_generated_constants.ml) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps (:gen ../generator/gen_constants_c_target.exe)) (action (with-stdout-to %{targets} (run %{gen})))) ocaml-posix-4.0.2/modules/math2/src/types/posix_math_types.ml000066400000000000000000000003561515131525300243240ustar00rootroot00000000000000module Constants = Posix_math_constants.Def (Posix_math_generated_constants) module Def (S : Cstubs.Types.TYPE) = struct include Constants let float_t = S.typedef S.float "float_t" let double_t = S.typedef S.double "double_t" end ocaml-posix-4.0.2/modules/resource/000077500000000000000000000000001515131525300172505ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/resource/CHANGES000066400000000000000000000007531515131525300202500ustar00rootroot000000000000003.2.0 (unreleased) * Initial release of posix-resource module * Provides bindings to sys/resource.h * Includes getrlimit/setrlimit for resource limit management * Includes getrusage for detailed resource usage statistics * Includes getpriority/setpriority for process priority control * Support for struct rlimit with cur/max limits * Support for struct rusage with comprehensive statistics * Integration with posix-time2 for timeval timestamps * Unix-only module (not available on Windows) ocaml-posix-4.0.2/modules/resource/src/000077500000000000000000000000001515131525300200375ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/resource/src/constants/000077500000000000000000000000001515131525300220535ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/resource/src/constants/dune000066400000000000000000000002561515131525300227340ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_resource_constants) (public_name posix-resource.constants) (libraries posix-base ctypes.stubs)) ocaml-posix-4.0.2/modules/resource/src/constants/posix_resource_constants.ml000066400000000000000000000015461515131525300275600ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct (* Resource limit types *) let rlimit_cpu = S.constant "RLIMIT_CPU" S.int let rlimit_fsize = S.constant "RLIMIT_FSIZE" S.int let rlimit_data = S.constant "RLIMIT_DATA" S.int let rlimit_stack = S.constant "RLIMIT_STACK" S.int let rlimit_core = S.constant "RLIMIT_CORE" S.int let rlimit_nofile = S.constant "RLIMIT_NOFILE" S.int let rlimit_as = S.constant "RLIMIT_AS" S.int (* rusage who constants *) let rusage_self = S.constant "RUSAGE_SELF" S.int let rusage_children = S.constant "RUSAGE_CHILDREN" S.int (* Priority who constants *) let prio_process = S.constant "PRIO_PROCESS" S.int let prio_pgrp = S.constant "PRIO_PGRP" S.int let prio_user = S.constant "PRIO_USER" S.int (* Special rlimit value - needs special handling *) let rlim_infinity = S.constant "RLIM_INFINITY" S.uint64_t end ocaml-posix-4.0.2/modules/resource/src/dune000066400000000000000000000011411515131525300207120ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_resource) (public_name posix-resource) (synopsis "posix-resource provides access to the features exposed in sys/resource.h") (foreign_stubs (language c) (names posix_resource_generated_stubs)) (libraries ctypes posix-errno posix-types posix-time2 posix-resource.types posix-resource.stubs)) (rule (targets posix_resource_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_resource_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) ocaml-posix-4.0.2/modules/resource/src/generator/000077500000000000000000000000001515131525300220255ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/resource/src/generator/dune000066400000000000000000000016611515131525300227070ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-resource.stubs posix-base)) (executable (name gen_types_c) (modules gen_types_c) (libraries posix-resource.types posix-base)) (rule (targets gen_types.c) (action (run ./gen_types_c.exe %{targets}))) (rule (targets gen_types_c) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-resource.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/resource/src/generator/gen_constants_c.ml000066400000000000000000000003061515131525300255250ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_resource_constants.Def let c_headers = {| #include #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/resource/src/generator/gen_stubs.ml000066400000000000000000000004071515131525300243510ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_resource_stubs.Def let c_headers = {| #include #include |} let concurrency = Cstubs.unlocked let prefix = "posix_resource" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/resource/src/generator/gen_types_c.ml000066400000000000000000000003301515131525300246520ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_resource_types.Def let c_headers = {| #include #include #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/resource/src/posix_resource.ml000066400000000000000000000062261515131525300234500ustar00rootroot00000000000000open Ctypes include Posix_resource_stubs.Def (Posix_resource_generated_stubs) include Posix_resource_types (* High-level types *) type rlimit = { rlim_cur : Unsigned.uint64; rlim_max : Unsigned.uint64 } type rusage = { ru_utime : Posix_time2.Timeval.t; ru_stime : Posix_time2.Timeval.t; ru_maxrss : int64; ru_ixrss : int64; ru_idrss : int64; ru_isrss : int64; ru_minflt : int64; ru_majflt : int64; ru_nswap : int64; ru_inblock : int64; ru_oublock : int64; ru_msgsnd : int64; ru_msgrcv : int64; ru_nsignals : int64; ru_nvcsw : int64; ru_nivcsw : int64; } (* Conversion helpers *) let from_rlimit rlim = let get f = getf rlim f in { rlim_cur = get Types.Rlimit.rlim_cur; rlim_max = get Types.Rlimit.rlim_max } let to_rlimit { rlim_cur; rlim_max } = let rlim = make Types.Rlimit.t in setf rlim Types.Rlimit.rlim_cur rlim_cur; setf rlim Types.Rlimit.rlim_max rlim_max; rlim let from_rusage ru = let get f = getf ru f in let get_timeval f = let tv = get f in let tv_sec = Posix_types.Time.to_int64 (getf tv Types.Time2_types.Timeval.tv_sec) in let tv_usec = Posix_types.Suseconds.to_int64 (getf tv Types.Time2_types.Timeval.tv_usec) in Posix_time2.Timeval.create tv_sec tv_usec in { ru_utime = get_timeval Types.Rusage.ru_utime; ru_stime = get_timeval Types.Rusage.ru_stime; ru_maxrss = Signed.Long.to_int64 (get Types.Rusage.ru_maxrss); ru_ixrss = Signed.Long.to_int64 (get Types.Rusage.ru_ixrss); ru_idrss = Signed.Long.to_int64 (get Types.Rusage.ru_idrss); ru_isrss = Signed.Long.to_int64 (get Types.Rusage.ru_isrss); ru_minflt = Signed.Long.to_int64 (get Types.Rusage.ru_minflt); ru_majflt = Signed.Long.to_int64 (get Types.Rusage.ru_majflt); ru_nswap = Signed.Long.to_int64 (get Types.Rusage.ru_nswap); ru_inblock = Signed.Long.to_int64 (get Types.Rusage.ru_inblock); ru_oublock = Signed.Long.to_int64 (get Types.Rusage.ru_oublock); ru_msgsnd = Signed.Long.to_int64 (get Types.Rusage.ru_msgsnd); ru_msgrcv = Signed.Long.to_int64 (get Types.Rusage.ru_msgrcv); ru_nsignals = Signed.Long.to_int64 (get Types.Rusage.ru_nsignals); ru_nvcsw = Signed.Long.to_int64 (get Types.Rusage.ru_nvcsw); ru_nivcsw = Signed.Long.to_int64 (get Types.Rusage.ru_nivcsw); } (* Resource limit functions *) let getrlimit resource = let rlim = make Types.Rlimit.t in ignore (Posix_errno.raise_on_neg ~call:"getrlimit" (fun () -> getrlimit resource (addr rlim))); from_rlimit rlim let setrlimit resource limits = let rlim = to_rlimit limits in ignore (Posix_errno.raise_on_neg ~call:"setrlimit" (fun () -> setrlimit resource (addr rlim))) (* Resource usage functions *) let getrusage who = let ru = make Types.Rusage.t in ignore (Posix_errno.raise_on_neg ~call:"getrusage" (fun () -> getrusage who (addr ru))); from_rusage ru (* Priority functions *) let getpriority which who = Posix_errno.raise_on_error ~call:"getpriority" (fun () -> getpriority which who) (fun n -> n = -1) let setpriority which who prio = ignore (Posix_errno.raise_on_neg ~call:"setpriority" (fun () -> setpriority which who prio)) ocaml-posix-4.0.2/modules/resource/src/posix_resource.mli000066400000000000000000000105321515131525300236140ustar00rootroot00000000000000(** POSIX resource usage and limits. This module provides OCaml bindings to POSIX resource functions defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_resource.h.html} sys/resource.h}. It includes functions for querying and setting resource limits, getting resource usage statistics, and managing process priorities. {2 Example} {[ (* Get resource usage for current process *) let usage = Posix_resource.getrusage rusage_self in Printf.printf "User CPU time: %s\n" (Posix_time2.Timeval.to_string usage.ru_utime); Printf.printf "Max RSS: %Ld KB\n" usage.ru_maxrss; (* Get file descriptor limit *) let limits = Posix_resource.getrlimit rlimit_nofile in Printf.printf "Max open files: %s\n" (Unsigned.UInt64.to_string limits.rlim_cur) ]} *) (** {1 Resource Limit Constants} *) (** CPU time limit in seconds (RLIMIT_CPU). *) val rlimit_cpu : int (** Maximum file size in bytes (RLIMIT_FSIZE). *) val rlimit_fsize : int (** Maximum data segment size (RLIMIT_DATA). *) val rlimit_data : int (** Maximum stack size (RLIMIT_STACK). *) val rlimit_stack : int (** Maximum core file size (RLIMIT_CORE). *) val rlimit_core : int (** Maximum number of open files (RLIMIT_NOFILE). *) val rlimit_nofile : int (** Maximum address space size (RLIMIT_AS). *) val rlimit_as : int (** Special value meaning no limit (RLIM_INFINITY). *) val rlim_infinity : Unsigned.uint64 (** {1 Resource Usage Constants} *) (** Current process (RUSAGE_SELF). *) val rusage_self : int (** All terminated and waited-for children (RUSAGE_CHILDREN). *) val rusage_children : int (** {1 Priority Constants} *) (** Process priority (PRIO_PROCESS). *) val prio_process : int (** Process group priority (PRIO_PGRP). *) val prio_pgrp : int (** User priority (PRIO_USER). *) val prio_user : int (** {1 Resource Limit Types} *) type rlimit = { rlim_cur : Unsigned.uint64; (** Current (soft) limit *) rlim_max : Unsigned.uint64; (** Maximum (hard) limit *) } (** {1 Resource Usage Types} *) (** Resource usage information returned by {!getrusage}. Corresponds to POSIX [struct rusage]. *) type rusage = { ru_utime : Posix_time2.Timeval.t; ru_stime : Posix_time2.Timeval.t; ru_maxrss : int64; ru_ixrss : int64; ru_idrss : int64; ru_isrss : int64; ru_minflt : int64; ru_majflt : int64; ru_nswap : int64; ru_inblock : int64; ru_oublock : int64; ru_msgsnd : int64; ru_msgrcv : int64; ru_nsignals : int64; ru_nvcsw : int64; ru_nivcsw : int64; } (** {1 Resource Limit Functions} *) (** Get resource limits. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html} getrlimit(2)}. @param resource One of the [rlimit_*] constants. @return The current soft and hard limits. @raise Unix.Unix_error on failure. *) val getrlimit : int -> rlimit (** Set resource limits. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setrlimit.html} setrlimit(2)}. @param resource One of the [rlimit_*] constants. @param limits The new soft and hard limits. @raise Unix.Unix_error on failure. *) val setrlimit : int -> rlimit -> unit (** {1 Resource Usage Functions} *) (** Get resource usage statistics. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrusage.html} getrusage(2)}. @param who {!rusage_self} or {!rusage_children}. @return Resource usage information. @raise Unix.Unix_error on failure. *) val getrusage : int -> rusage (** {1 Priority Functions} *) (** Get process scheduling priority. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpriority.html} getpriority(2)}. @param which {!prio_process}, {!prio_pgrp}, or {!prio_user}. @param who Process ID, process group ID, or user ID (0 for current). @return The priority value. @raise Unix.Unix_error on failure. *) val getpriority : int -> int -> int (** Set process scheduling priority. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpriority.html} setpriority(2)}. @param which {!prio_process}, {!prio_pgrp}, or {!prio_user}. @param who Process ID, process group ID, or user ID (0 for current). @param prio The new priority value. @raise Unix.Unix_error on failure. *) val setpriority : int -> int -> int -> unit ocaml-posix-4.0.2/modules/resource/src/stubs/000077500000000000000000000000001515131525300211775ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/resource/src/stubs/dune000066400000000000000000000004621515131525300220570ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_resource_stubs) (public_name posix-resource.stubs) (libraries posix-resource.types ctypes.stubs)) (rule (targets posix_resource_generated_types.ml) (action (with-stdout-to %{targets} (run ../generator/gen_types_c)))) ocaml-posix-4.0.2/modules/resource/src/stubs/posix_resource_stubs.ml000066400000000000000000000012041515131525300260170ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F module Types = Posix_resource_types.Def (Posix_resource_generated_types) open Types (* Resource limit functions *) let getrlimit = foreign "getrlimit" (int @-> ptr Rlimit.t @-> returning int) let setrlimit = foreign "setrlimit" (int @-> ptr Rlimit.t @-> returning int) (* Resource usage functions *) let getrusage = foreign "getrusage" (int @-> ptr Rusage.t @-> returning int) (* Priority functions *) let getpriority = foreign "getpriority" (int @-> int @-> returning int) let setpriority = foreign "setpriority" (int @-> int @-> int @-> returning int) end ocaml-posix-4.0.2/modules/resource/src/types/000077500000000000000000000000001515131525300212035ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/resource/src/types/dune000066400000000000000000000005431515131525300220630ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_resource_types) (public_name posix-resource.types) (libraries posix-resource.constants posix-base posix-time2.types ctypes.stubs)) (rule (targets posix_resource_generated_constants.ml) (action (with-stdout-to %{targets} (run ../generator/gen_constants_c)))) ocaml-posix-4.0.2/modules/resource/src/types/posix_resource_types.ml000066400000000000000000000041701515131525300260340ustar00rootroot00000000000000open Ctypes module Constants = Posix_resource_constants.Def (Posix_resource_generated_constants) (* Re-export constants *) let rlimit_cpu = Constants.rlimit_cpu let rlimit_fsize = Constants.rlimit_fsize let rlimit_data = Constants.rlimit_data let rlimit_stack = Constants.rlimit_stack let rlimit_core = Constants.rlimit_core let rlimit_nofile = Constants.rlimit_nofile let rlimit_as = Constants.rlimit_as let rusage_self = Constants.rusage_self let rusage_children = Constants.rusage_children let prio_process = Constants.prio_process let prio_pgrp = Constants.prio_pgrp let prio_user = Constants.prio_user let rlim_infinity = Constants.rlim_infinity module Def (S : Cstubs.Types.TYPE) = struct (* Import timeval type from posix-time2 *) module Time2_types = Posix_time2_types.Def (S) (* rlim_t type - typically unsigned long or uint64 *) let rlim_t = S.typedef S.uint64_t "rlim_t" module Rlimit = struct type t = unit let t = S.structure "rlimit" let rlim_cur = S.field t "rlim_cur" rlim_t let rlim_max = S.field t "rlim_max" rlim_t let () = S.seal t end module Rusage = struct type t = unit let t = S.structure "rusage" let ru_utime = S.field t "ru_utime" Time2_types.Timeval.t let ru_stime = S.field t "ru_stime" Time2_types.Timeval.t let ru_maxrss = S.field t "ru_maxrss" S.long let ru_ixrss = S.field t "ru_ixrss" S.long let ru_idrss = S.field t "ru_idrss" S.long let ru_isrss = S.field t "ru_isrss" S.long let ru_minflt = S.field t "ru_minflt" S.long let ru_majflt = S.field t "ru_majflt" S.long let ru_nswap = S.field t "ru_nswap" S.long let ru_inblock = S.field t "ru_inblock" S.long let ru_oublock = S.field t "ru_oublock" S.long let ru_msgsnd = S.field t "ru_msgsnd" S.long let ru_msgrcv = S.field t "ru_msgrcv" S.long let ru_nsignals = S.field t "ru_nsignals" S.long let ru_nvcsw = S.field t "ru_nvcsw" S.long let ru_nivcsw = S.field t "ru_nivcsw" S.long let () = S.seal t end type rlimit = Rlimit.t structure type rusage = Rusage.t structure let rlimit_t : rlimit S.typ = Rlimit.t let rusage_t : rusage S.typ = Rusage.t end ocaml-posix-4.0.2/modules/resource/src/types/posix_resource_types.mli000066400000000000000000000036031515131525300262050ustar00rootroot00000000000000open Ctypes (** Resource limit constants *) val rlimit_cpu : int val rlimit_fsize : int val rlimit_data : int val rlimit_stack : int val rlimit_core : int val rlimit_nofile : int val rlimit_as : int (** rusage who constants *) val rusage_self : int val rusage_children : int (** Priority who constants *) val prio_process : int val prio_pgrp : int val prio_user : int (** Special rlimit value *) val rlim_infinity : Unsigned.uint64 (** Structure definitions *) module Def (S : Cstubs.Types.TYPE) : sig module Time2_types : module type of Posix_time2_types.Def (S) val rlim_t : Unsigned.uint64 S.typ module Rlimit : sig type t val t : t structure S.typ val rlim_cur : (Unsigned.uint64, t structure) S.field val rlim_max : (Unsigned.uint64, t structure) S.field end module Rusage : sig type t val t : t structure S.typ val ru_utime : (Time2_types.Timeval.t structure, t structure) S.field val ru_stime : (Time2_types.Timeval.t structure, t structure) S.field val ru_maxrss : (Signed.long, t structure) S.field val ru_ixrss : (Signed.long, t structure) S.field val ru_idrss : (Signed.long, t structure) S.field val ru_isrss : (Signed.long, t structure) S.field val ru_minflt : (Signed.long, t structure) S.field val ru_majflt : (Signed.long, t structure) S.field val ru_nswap : (Signed.long, t structure) S.field val ru_inblock : (Signed.long, t structure) S.field val ru_oublock : (Signed.long, t structure) S.field val ru_msgsnd : (Signed.long, t structure) S.field val ru_msgrcv : (Signed.long, t structure) S.field val ru_nsignals : (Signed.long, t structure) S.field val ru_nvcsw : (Signed.long, t structure) S.field val ru_nivcsw : (Signed.long, t structure) S.field end type rlimit = Rlimit.t structure type rusage = Rusage.t structure val rlimit_t : rlimit S.typ val rusage_t : rusage S.typ end ocaml-posix-4.0.2/modules/resource/test/000077500000000000000000000000001515131525300202275ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/resource/test/dune000066400000000000000000000002171515131525300211050ustar00rootroot00000000000000(executable (name test) (libraries posix-resource unix)) (rule (alias citest) (package posix-resource) (action (run %{exe:test.exe}))) ocaml-posix-4.0.2/modules/resource/test/test.ml000066400000000000000000000046271515131525300215510ustar00rootroot00000000000000open Posix_resource let test_getrlimit () = Printf.printf "Testing getrlimit...\n%!"; let rlim = getrlimit rlimit_nofile in Printf.printf " ✓ RLIMIT_NOFILE: cur=%s, max=%s\n%!" (Unsigned.UInt64.to_string rlim.rlim_cur) (Unsigned.UInt64.to_string rlim.rlim_max); assert (Unsigned.UInt64.(compare rlim.rlim_cur zero) > 0); Printf.printf " ✓ getrlimit test passed\n%!" let test_setrlimit () = Printf.printf "\nTesting setrlimit...\n%!"; let orig = getrlimit rlimit_nofile in (* Try to set to same value (should always succeed) *) setrlimit rlimit_nofile orig; let new_rlim = getrlimit rlimit_nofile in assert (Unsigned.UInt64.equal orig.rlim_cur new_rlim.rlim_cur); Printf.printf " ✓ setrlimit test passed\n%!" let test_getrusage () = Printf.printf "\nTesting getrusage...\n%!"; let ru = getrusage rusage_self in Printf.printf " ✓ User time: %s\n%!" (Posix_time2.Timeval.to_string ru.ru_utime); Printf.printf " ✓ System time: %s\n%!" (Posix_time2.Timeval.to_string ru.ru_stime); Printf.printf " ✓ Max RSS: %Ld KB\n%!" ru.ru_maxrss; Printf.printf " ✓ getrusage test passed\n%!" let test_priority () = Printf.printf "\nTesting priority functions...\n%!"; let prio = getpriority prio_process 0 in Printf.printf " ✓ Current process priority: %d\n%!" prio; (* Try to set to same priority (should succeed for normal users) *) setpriority prio_process 0 prio; let new_prio = getpriority prio_process 0 in assert (prio = new_prio); Printf.printf " ✓ priority test passed\n%!" let test_rlim_infinity () = Printf.printf "\nTesting RLIM_INFINITY constant...\n%!"; Printf.printf " ✓ RLIM_INFINITY = %s\n%!" (Unsigned.UInt64.to_string rlim_infinity); assert (Unsigned.UInt64.(compare rlim_infinity zero) > 0); Printf.printf " ✓ RLIM_INFINITY test passed\n%!" let test_constants () = Printf.printf "\nTesting resource constants...\n%!"; assert (rlimit_cpu >= 0); assert (rlimit_fsize >= 0); assert (rlimit_data >= 0); assert (rlimit_stack >= 0); assert (rlimit_core >= 0); assert (rlimit_nofile >= 0); assert (rlimit_as >= 0); Printf.printf " ✓ Resource constants test passed\n%!" let () = Printf.printf "=== Running posix-resource tests ===\n\n%!"; test_constants (); test_getrlimit (); test_setrlimit (); test_getrusage (); test_priority (); test_rlim_infinity (); Printf.printf "\n=== All tests passed! ===\n%!" ocaml-posix-4.0.2/modules/signal/000077500000000000000000000000001515131525300166765ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/signal/CHANGES000066400000000000000000000005071515131525300176730ustar00rootroot000000000000002.2.0 (2025-01-30) ===== * Fix copy code in `getaddrinfo`. 2.1.0 (2025-01-16) ===== * Added `posix-math2` * Invoke `wine64` only when available. * Added `sockaddr_len` in `ocaml-posix`. * Add support for string and optional `port. * Add support for `hints`. 2.0.2 (2023-02-08) ===== **posix-time2** * Added `clock_nanosleep` ocaml-posix-4.0.2/modules/signal/src/000077500000000000000000000000001515131525300174655ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/signal/src/constants/000077500000000000000000000000001515131525300215015ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/signal/src/constants/dune000066400000000000000000000001511515131525300223540ustar00rootroot00000000000000(library (name posix_signal_constants) (public_name posix-signal.constants) (libraries ctypes.stubs)) ocaml-posix-4.0.2/modules/signal/src/constants/posix_signal_constants.ml000066400000000000000000000024611515131525300266310ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct let sigset_size = S.constant "SIGSET_SIZE" S.int let sigset_alignment = S.constant "SIGSET_ALIGNMENT" S.int let sig_block = S.constant "SIG_BLOCK" S.int let sig_setmask = S.constant "SIG_SETMASK" S.int let sig_unblock = S.constant "SIG_UNBLOCK" S.int let sigabrt = S.constant "SIGABRT" S.int let sigalrm = S.constant "SIGALRM" S.int let sigbus = S.constant "SIGBUS" S.int let sigchld = S.constant "SIGCHLD" S.int let sigcont = S.constant "SIGCONT" S.int let sigfpe = S.constant "SIGFPE" S.int let sighup = S.constant "SIGHUP" S.int let sigill = S.constant "SIGILL" S.int let sigint = S.constant "SIGINT" S.int let sigkill = S.constant "SIGKILL" S.int let sigpipe = S.constant "SIGPIPE" S.int let sigquit = S.constant "SIGQUIT" S.int let sigsegv = S.constant "SIGSEGV" S.int let sigstop = S.constant "SIGSTOP" S.int let sigterm = S.constant "SIGTERM" S.int let sigtstp = S.constant "SIGTSTP" S.int let sigttin = S.constant "SIGTTIN" S.int let sigttou = S.constant "SIGTTOU" S.int let sigusr1 = S.constant "SIGUSR1" S.int let sigusr2 = S.constant "SIGUSR2" S.int let sigtrap = S.constant "SIGTRAP" S.int let sigurg = S.constant "SIGURG" S.int let sigxcpu = S.constant "SIGXCPU" S.int let sigxfsz = S.constant "SIGXFSZ" S.int end ocaml-posix-4.0.2/modules/signal/src/dune000066400000000000000000000011441515131525300203430ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_signal) (public_name posix-signal) (synopsis "posix-signal provides access to the features exposed in signal.h") (foreign_stubs (language c) (names posix_signal_generated_stubs)) (c_library_flags %{ocaml-config:bytecomp_c_libraries}) (libraries unix ctypes posix-errno posix-signal.types posix-signal.stubs)) (rule (targets posix_signal_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_signal_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) ocaml-posix-4.0.2/modules/signal/src/generator/000077500000000000000000000000001515131525300214535ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/signal/src/generator/dune000066400000000000000000000016531515131525300223360ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-signal.stubs posix-base)) (executable (name gen_types_c) (modules gen_types_c) (libraries posix-signal.types posix-base)) (rule (targets gen_types.c) (action (run ./gen_types_c.exe %{targets}))) (rule (targets gen_types_c) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-signal.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/signal/src/generator/gen_constants_c.ml000066400000000000000000000004271515131525300251570ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_signal_constants.Def let c_headers = {| #include #define SIGSET_SIZE sizeof(sigset_t) #define SIGSET_ALIGNMENT offsetof(struct { char c; sigset_t x; }, x) |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/signal/src/generator/gen_stubs.ml000066400000000000000000000003471515131525300240020ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_signal_stubs.Def let c_headers = {| #include |} let concurrency = Cstubs.unlocked let prefix = "posix_signal" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/signal/src/generator/gen_types_c.ml000066400000000000000000000002441515131525300243040ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_signal_types.Def let c_headers = {| #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/signal/src/posix_signal.ml000066400000000000000000000053011515131525300225150ustar00rootroot00000000000000open Ctypes open Posix_signal_types include Posix_signal_stubs.Def (Posix_signal_generated_stubs) type sigset = Types.sigset_t ptr type signal = [ `Sigabrt | `Sigalrm | `Sigbus | `Sigchld | `Sigcont | `Sigfpe | `Sighup | `Sigill | `Sigint | `Sigkill | `Sigpipe | `Sigquit | `Sigsegv | `Sigstop | `Sigterm | `Sigtstp | `Sigttin | `Sigttou | `Sigusr1 | `Sigusr2 | `Sigtrap | `Sigurg | `Sigxcpu | `Sigxfsz ] let int_of_signal = function | `Sigabrt -> sigabrt | `Sigalrm -> sigalrm | `Sigbus -> sigbus | `Sigchld -> sigchld | `Sigcont -> sigcont | `Sigfpe -> sigfpe | `Sighup -> sighup | `Sigill -> sigill | `Sigint -> sigint | `Sigkill -> sigkill | `Sigpipe -> sigpipe | `Sigquit -> sigquit | `Sigsegv -> sigsegv | `Sigstop -> sigstop | `Sigterm -> sigterm | `Sigtstp -> sigtstp | `Sigttin -> sigttin | `Sigttou -> sigttou | `Sigusr1 -> sigusr1 | `Sigusr2 -> sigusr2 | `Sigtrap -> sigtrap | `Sigurg -> sigurg | `Sigxcpu -> sigxcpu | `Sigxfsz -> sigxfsz type action = [ `Sig_block | `Sig_setmask | `Sig_unblock ] let int_of_action = function | `Sig_block -> sig_block | `Sig_setmask -> sig_setmask | `Sig_unblock -> sig_unblock let sigemptyset () = Posix_errno.raise_on_none ~call:"sigemptyset" (fun () -> let p = allocate_n Types.sigset_t ~count:1 in match sigemptyset p with x when x < 0 -> None | _ -> Some p) let sigaddset sigset signal = Posix_errno.raise_on_none ~call:"sigaddset" (fun () -> let signal = int_of_signal signal in match sigaddset sigset signal with x when x < 0 -> None | _ -> Some ()) let sigismember sigset signal = Posix_errno.raise_on_none ~call:"sigismember" (fun () -> let signal = int_of_signal signal in match sigismember sigset signal with | x when x < 0 -> None | 1 -> Some true | _ -> Some false) let pthread_sigmask action sigset = Posix_errno.raise_on_none ~call:"pthread_sigmask" (fun () -> let action = int_of_action action in let sigset = match sigset with Some p -> p | None -> from_voidp Types.sigset_t null in let old_sigset = allocate_n Types.sigset_t ~count:1 in match pthread_sigmask action sigset old_sigset with | x when x < 0 -> None | _ -> Some old_sigset) let sigprocmask action sigset = Posix_errno.raise_on_none ~call:"sigprocmask" (fun () -> let action = int_of_action action in let sigset = match sigset with Some p -> p | None -> from_voidp Types.sigset_t null in let old_sigset = allocate_n Types.sigset_t ~count:1 in match sigprocmask action sigset old_sigset with | x when x < 0 -> None | _ -> Some old_sigset) ocaml-posix-4.0.2/modules/signal/src/posix_signal.mli000066400000000000000000000062721515131525300226760ustar00rootroot00000000000000(** POSIX signal handling bindings. This module provides OCaml bindings to POSIX signal functions defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html} signal.h}. It includes functions for manipulating signal sets and controlling signal delivery to threads and processes. *) (** {1 Signal Sets} *) (** Abstract type representing a set of signals. *) type sigset (** POSIX signals. *) type signal = [ `Sigabrt (** Abnormal termination *) | `Sigalrm (** Alarm clock *) | `Sigbus (** Bus error *) | `Sigchld (** Child process terminated *) | `Sigcont (** Continue if stopped *) | `Sigfpe (** Floating-point exception *) | `Sighup (** Hangup *) | `Sigill (** Illegal instruction *) | `Sigint (** Interactive attention signal *) | `Sigkill (** Kill (cannot be caught or ignored) *) | `Sigpipe (** Broken pipe *) | `Sigquit (** Quit *) | `Sigsegv (** Segmentation fault *) | `Sigstop (** Stop (cannot be caught or ignored) *) | `Sigterm (** Termination request *) | `Sigtstp (** Terminal stop *) | `Sigttin (** Background read from terminal *) | `Sigttou (** Background write to terminal *) | `Sigusr1 (** User-defined signal 1 *) | `Sigusr2 (** User-defined signal 2 *) | `Sigtrap (** Trace/breakpoint trap *) | `Sigurg (** Urgent data on socket *) | `Sigxcpu (** CPU time limit exceeded *) | `Sigxfsz ] (** File size limit exceeded *) (** {1 Signal Mask Actions} *) (** Actions for modifying the signal mask. *) type action = [ `Sig_block (** Add signals to the mask *) | `Sig_setmask (** Set the mask to the specified signals *) | `Sig_unblock (** Remove signals from the mask *) ] (** {1 Signal Set Functions} *) (** Create an empty signal set. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigemptyset.html} sigemptyset(3)}. *) val sigemptyset : unit -> sigset (** Add a signal to a signal set. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html} sigaddset(3)}. *) val sigaddset : sigset -> signal -> unit (** Test whether a signal is in a signal set. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigismember.html} sigismember(3)}. *) val sigismember : sigset -> signal -> bool (** {1 Signal Mask Functions} *) (** Examine and change the signal mask of the calling thread. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html} pthread_sigmask(3)}. @param action How to modify the signal mask. @param set The signal set to use, or [None] to only retrieve the current mask. @return The previous signal mask. *) val pthread_sigmask : action -> sigset option -> sigset (** Examine and change the signal mask of the calling process. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html} sigprocmask(2)}. Note: In multi-threaded programs, use {!pthread_sigmask} instead. @param action How to modify the signal mask. @param set The signal set to use, or [None] to only retrieve the current mask. @return The previous signal mask. *) val sigprocmask : action -> sigset option -> sigset ocaml-posix-4.0.2/modules/signal/src/stubs/000077500000000000000000000000001515131525300206255ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/signal/src/stubs/dune000066400000000000000000000004521515131525300215040ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_signal_stubs) (public_name posix-signal.stubs) (libraries posix-signal.types ctypes.stubs)) (rule (targets posix_signal_generated_types.ml) (action (with-stdout-to %{targets} (run ../generator/gen_types_c)))) ocaml-posix-4.0.2/modules/signal/src/stubs/posix_signal_stubs.ml000066400000000000000000000011601515131525300250740ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F module Types = Posix_signal_types.Def (Posix_signal_generated_types) open Types let sigemptyset = foreign "sigemptyset" (ptr sigset_t @-> returning int) let sigaddset = foreign "sigaddset" (ptr sigset_t @-> int @-> returning int) let sigismember = foreign "sigismember" (ptr sigset_t @-> int @-> returning int) let pthread_sigmask = foreign "pthread_sigmask" (int @-> ptr sigset_t @-> ptr sigset_t @-> returning int) let sigprocmask = foreign "sigprocmask" (int @-> ptr sigset_t @-> ptr sigset_t @-> returning int) end ocaml-posix-4.0.2/modules/signal/src/types/000077500000000000000000000000001515131525300206315ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/signal/src/types/dune000066400000000000000000000005011515131525300215030ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_signal_types) (public_name posix-signal.types) (libraries posix-signal.constants posix-base ctypes.stubs)) (rule (targets posix_signal_generated_constants.ml) (action (with-stdout-to %{targets} (run ../generator/gen_constants_c)))) ocaml-posix-4.0.2/modules/signal/src/types/posix_signal_types.ml000066400000000000000000000004501515131525300251050ustar00rootroot00000000000000module Constants = Posix_signal_constants.Def (Posix_signal_generated_constants) include Constants module Def (S : Cstubs.Types.TYPE) = struct open Ctypes type sigset_t = unit Ctypes.abstract let sigset_t = abstract ~name:"sigset_t" ~size:sigset_size ~alignment:sigset_alignment end ocaml-posix-4.0.2/modules/signal/src/types/posix_signal_types.mli000066400000000000000000000011621515131525300252570ustar00rootroot00000000000000(** Ctypes types for *) val sigabrt : int val sigalrm : int val sigbus : int val sigchld : int val sigcont : int val sigfpe : int val sighup : int val sigill : int val sigint : int val sigkill : int val sigpipe : int val sigquit : int val sigsegv : int val sigstop : int val sigterm : int val sigtstp : int val sigttin : int val sigttou : int val sigusr1 : int val sigusr2 : int val sigtrap : int val sigurg : int val sigxcpu : int val sigxfsz : int val sig_block : int val sig_setmask : int val sig_unblock : int module Def (_ : Cstubs.Types.TYPE) : sig type sigset_t val sigset_t : sigset_t Ctypes.typ end ocaml-posix-4.0.2/modules/signal/test/000077500000000000000000000000001515131525300176555ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/signal/test/autogenerated_tests.ml000066400000000000000000000052011515131525300242560ustar00rootroot00000000000000(* Error handling tests for posix-signal *) open Posix_signal (* Test that signal operations work correctly *) let test_sigemptyset_success () = Printf.printf "Testing sigemptyset (success case)...\n%!"; let _sigset = sigemptyset () in Printf.printf " ✓ sigemptyset succeeded\n%!" let test_sigaddset_success () = Printf.printf "Testing sigaddset (success case)...\n%!"; let sigset = sigemptyset () in sigaddset sigset `Sigint; sigaddset sigset `Sigterm; Printf.printf " ✓ sigaddset succeeded for valid signals\n%!" let test_sigismember_success () = Printf.printf "Testing sigismember (success case)...\n%!"; let sigset = sigemptyset () in sigaddset sigset `Sigint; let is_member = sigismember sigset `Sigint in assert is_member; let not_member = sigismember sigset `Sigterm in assert (not not_member); Printf.printf " ✓ sigismember correctly identifies members\n%!" let test_pthread_sigmask_success () = Printf.printf "Testing pthread_sigmask (success case)...\n%!"; let sigset = sigemptyset () in sigaddset sigset `Sigint; let old = pthread_sigmask `Sig_block (Some sigset) in ignore old; let _ = pthread_sigmask `Sig_unblock (Some sigset) in Printf.printf " ✓ pthread_sigmask block/unblock succeeded\n%!" let test_sigprocmask_success () = Printf.printf "Testing sigprocmask (success case)...\n%!"; let sigset = sigemptyset () in sigaddset sigset `Sigusr1; let old = sigprocmask `Sig_block (Some sigset) in ignore old; let _ = sigprocmask `Sig_unblock (Some sigset) in Printf.printf " ✓ sigprocmask block/unblock succeeded\n%!" let test_sigprocmask_query () = Printf.printf "Testing sigprocmask query (None argument)...\n%!"; let current_mask = sigprocmask `Sig_setmask None in ignore current_mask; Printf.printf " ✓ sigprocmask query succeeded\n%!" (* Test combining multiple signals *) let test_multiple_signals () = Printf.printf "Testing multiple signal operations...\n%!"; let sigset = sigemptyset () in List.iter (fun sig_ -> sigaddset sigset sig_) [`Sigint; `Sigterm; `Sigusr1; `Sigusr2; `Sigchld]; List.iter (fun sig_ -> assert (sigismember sigset sig_)) [`Sigint; `Sigterm; `Sigusr1; `Sigusr2; `Sigchld]; assert (not (sigismember sigset `Sigpipe)); Printf.printf " ✓ Multiple signal operations succeeded\n%!" let () = Printf.printf "\n=== POSIX Signal Error Handling Tests ===\n\n%!"; test_sigemptyset_success (); test_sigaddset_success (); test_sigismember_success (); test_pthread_sigmask_success (); test_sigprocmask_success (); test_sigprocmask_query (); test_multiple_signals (); Printf.printf "\n✓ All signal tests passed!\n%!" ocaml-posix-4.0.2/modules/signal/test/dune000066400000000000000000000004601515131525300205330ustar00rootroot00000000000000(executable (name test) (libraries posix-signal)) (rule (alias citest) (package posix-signal) (action (run %{exe:test.exe}))) (executable (name autogenerated_tests) (libraries posix-signal unix)) (rule (alias citest) (package posix-signal) (action (run %{exe:autogenerated_tests.exe}))) ocaml-posix-4.0.2/modules/signal/test/test.ml000066400000000000000000000003461515131525300211710ustar00rootroot00000000000000open Posix_signal let () = let sigset = sigemptyset () in sigaddset sigset `Sigint; ignore (sigprocmask `Sig_setmask (Some sigset)); let old_mask = sigprocmask `Sig_setmask None in assert (sigismember old_mask `Sigint) ocaml-posix-4.0.2/modules/socket-unix/000077500000000000000000000000001515131525300176725ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket-unix/CHANGES000066400000000000000000000006031515131525300206640ustar00rootroot000000000000003.0.0 (2025-04-20) ===== * Adapt to new `posix-socket` API 2.2.0 (2025-01-30) ===== * Fix copy code in `getaddrinfo`. 2.1.0 (2025-01-16) ===== * Added `posix-math2` * Invoke `wine64` only when available. * Added `sockaddr_len` in `ocaml-posix`. * Add support for string and optional `port. * Add support for `hints`. 2.0.2 (2023-02-08) ===== **posix-time2** * Added `clock_nanosleep` ocaml-posix-4.0.2/modules/socket-unix/README.md000066400000000000000000000011051515131525300211460ustar00rootroot00000000000000# posix-socket-unix This module provides OCaml ctypes bindings to system-specific low-level socket structure and data-types. The interface is implemented using [ocaml-ctypes](https://github.com/ocamllabs/ocaml-ctypes) and is intended to exposed the machine-specific, low-level details of the most important parts of socket implementations. [Posix_socket_unix](src/posix_socket_unix.mli) provides the API specific to `Unix` systems, mostly the `sockaddr_u` structure. API common to both `Unix` and `Win32` systems are defined in the parent `posix-socket` module. Happy hacking! ocaml-posix-4.0.2/modules/socket-unix/src/000077500000000000000000000000001515131525300204615ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket-unix/src/constants/000077500000000000000000000000001515131525300224755ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket-unix/src/constants/dune000066400000000000000000000002271515131525300233540ustar00rootroot00000000000000(library (name posix_socket_unix_constants) (public_name posix-socket-unix.constants) (enabled_if (= %{os_type} Unix)) (libraries ctypes.stubs)) ocaml-posix-4.0.2/modules/socket-unix/src/constants/posix_socket_unix_constants.ml000066400000000000000000000002201515131525300306720ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct let af_unix = S.constant "AF_UNIX" S.int let sun_path_len = S.constant "SUN_PATH_LEN" S.int end ocaml-posix-4.0.2/modules/socket-unix/src/dune000066400000000000000000000007021515131525300213360ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_socket_unix) (public_name posix-socket-unix) (synopsis "posix-socket-unix provides access to unix-specific sockaddr_un") (enabled_if (= %{os_type} Unix)) (libraries unix posix-errno ctypes posix-socket posix-socket-unix.types)) (rule (targets posix_socket_unix_generated_types.ml) (deps (:gen ./generator/gen_types_c)) (action (system "%{gen} > %{targets}"))) ocaml-posix-4.0.2/modules/socket-unix/src/generator/000077500000000000000000000000001515131525300224475ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket-unix/src/generator/dune000066400000000000000000000015251515131525300233300ustar00rootroot00000000000000(executable (name gen_types_c) (modules gen_types_c) (libraries posix-socket-unix.types posix-base)) (rule (targets gen_types.c) (action (run ./gen_types_c.exe %{targets}))) (rule (targets gen_types_c) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-socket-unix.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/socket-unix/src/generator/gen_constants_c.ml000066400000000000000000000004141515131525300261470ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_socket_unix_constants.Def let c_headers = {| #include #include #define SUN_PATH_LEN (sizeof(((struct sockaddr_un *)0)->sun_path)) |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/socket-unix/src/generator/gen_types_c.ml000066400000000000000000000003351515131525300253010ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_socket_unix_types.Def let c_headers = {| #include #include #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/socket-unix/src/posix_socket_unix.ml000066400000000000000000000027251515131525300245760ustar00rootroot00000000000000open Ctypes open Posix_socket include Posix_socket_unix_types module Types = Posix_socket_unix_types.Def (Posix_socket_unix_generated_types) type sockaddr_un = Types.sockaddr_un let sockaddr_un_t = Types.sockaddr_un_t let from_ptr t ptr = from_voidp t (to_voidp ptr) module SockaddrUnix = struct include Types.SockaddrUnix let from_sockaddr_storage = from_ptr t let sun_path_len = sun_path_len end let to_unix_sockaddr s = match !@(s |-> Sockaddr.sa_family) with | id when id = af_unix -> let s = from_ptr SockaddrUnix.t s in let path = !@(s |-> SockaddrUnix.sun_path) in let len = strnlen (CArray.start path) (Unsigned.Size_t.of_int (CArray.length path)) in let path = string_from_ptr (CArray.start path) ~length:(Unsigned.Size_t.to_int len) in Unix.ADDR_UNIX path | _ -> to_unix_sockaddr s let from_unix_sockaddr = function | Unix.ADDR_UNIX path -> let ss = sockaddr_storage () in let path = if String.length path > sun_path_len then String.sub path 0 sun_path_len else path in let ret = ref [] in String.iter (fun c -> ret := c :: !ret) path; let path = CArray.of_list char (List.rev !ret) in let s = SockaddrUnix.from_sockaddr_storage ss in s |-> SockaddrUnix.sun_family <-@ af_unix; s |-> SockaddrUnix.sun_path <-@ path; from_ptr Sockaddr.t ss | sockaddr -> from_unix_sockaddr sockaddr ocaml-posix-4.0.2/modules/socket-unix/src/posix_socket_unix.mli000066400000000000000000000031141515131525300247400ustar00rootroot00000000000000(** POSIX Unix domain socket bindings. This module provides OCaml bindings for Unix domain sockets (AF_UNIX), extending the {!Posix_socket} module with Unix-specific socket address types. Unix domain sockets provide local inter-process communication using filesystem paths as addresses. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_un.h.html} sys/un.h}. *) open Ctypes open Posix_socket (** {1 Address Family} *) (** Unix domain socket address family (AF_UNIX). *) val af_unix : sa_family_t (** {1 Unix Socket Address} The [sockaddr_un] structure for Unix domain sockets. *) module SockaddrUnix : sig type t val t : t structure typ val sun_family : (sa_family_t, t structure) field val sun_path : (char carray, t structure) field val sun_path_len : int val from_sockaddr_storage : sockaddr_storage ptr -> t structure ptr end (** Type alias for Unix domain socket address. *) type sockaddr_un = SockaddrUnix.t structure (** Ctypes representation of sockaddr_un. *) val sockaddr_un_t : sockaddr_un typ (** {1 Unix Module Interoperability} *) (** Convert a [Unix.sockaddr] to a POSIX socket address. Supports [Unix.ADDR_UNIX] addresses. @param addr The Unix socket address to convert. @return A pointer to the equivalent POSIX sockaddr. *) val from_unix_sockaddr : Unix.sockaddr -> sockaddr ptr (** Convert a POSIX socket address to [Unix.sockaddr]. @param addr The POSIX socket address to convert. @return The equivalent [Unix.ADDR_UNIX] address. *) val to_unix_sockaddr : sockaddr ptr -> Unix.sockaddr ocaml-posix-4.0.2/modules/socket-unix/src/types/000077500000000000000000000000001515131525300216255ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket-unix/src/types/dune000066400000000000000000000005231515131525300225030ustar00rootroot00000000000000(library (name posix_socket_unix_types) (public_name posix-socket-unix.types) (enabled_if (= %{os_type} Unix)) (libraries posix-socket.types posix-socket-unix.constants ctypes.stubs)) (rule (targets posix_socket_unix_generated_constants.ml) (deps (:gen ../generator/gen_constants_c)) (action (system "%{gen} > %{targets}"))) ocaml-posix-4.0.2/modules/socket-unix/src/types/posix_socket_unix_types.ml000066400000000000000000000011651515131525300271630ustar00rootroot00000000000000open Ctypes open Posix_socket_types module Constants = Posix_socket_unix_constants.Def (Posix_socket_unix_generated_constants) include Constants let af_unix = Sa_family.of_int af_unix module Def (S : Cstubs.Types.TYPE) = struct let sa_family_t = S.lift_typ sa_family_t module SockaddrUnix = struct type t = unit let t = S.structure "sockaddr_un" let sun_family = S.field t "sun_family" sa_family_t let sun_path = S.field t "sun_path" (S.array sun_path_len S.char) let () = S.seal t end type sockaddr_un = SockaddrUnix.t structure let sockaddr_un_t : sockaddr_un S.typ = SockaddrUnix.t end ocaml-posix-4.0.2/modules/socket-unix/src/types/posix_socket_unix_types.mli000066400000000000000000000006261515131525300273350ustar00rootroot00000000000000open Ctypes open Posix_socket_types val af_unix : sa_family_t val sun_path_len : int module Def (S : Cstubs.Types.TYPE) : sig module SockaddrUnix : sig type t val t : t structure S.typ val sun_family : (sa_family_t, t structure) S.field val sun_path : (char carray, t structure) S.field end type sockaddr_un = SockaddrUnix.t structure val sockaddr_un_t : sockaddr_un S.typ end ocaml-posix-4.0.2/modules/socket-unix/test/000077500000000000000000000000001515131525300206515ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket-unix/test/dune000066400000000000000000000002201515131525300215210ustar00rootroot00000000000000(executable (name test) (libraries posix-socket-unix)) (rule (alias citest) (package posix-socket-unix) (action (run %{exe:test.exe}))) ocaml-posix-4.0.2/modules/socket-unix/test/test.ml000066400000000000000000000010241515131525300221570ustar00rootroot00000000000000open Ctypes open Posix_socket open Posix_socket_unix let from_ptr t ptr = from_voidp t (to_voidp ptr) let () = let sockaddr = from_unix_sockaddr (Unix.ADDR_UNIX "/path/to/socket") in let sockaddr_un = from_ptr SockaddrUnix.t sockaddr in Printf.printf "sockaddr_un.sun_family = %d\n%!" (Sa_family.to_int !@(sockaddr_un |-> SockaddrUnix.sun_family)); let unix_socket = to_unix_sockaddr sockaddr in match unix_socket with | Unix.ADDR_UNIX path -> Printf.printf "Unix.ADDR_UNIX(%S)\n%!" path | _ -> assert false ocaml-posix-4.0.2/modules/socket/000077500000000000000000000000001515131525300167115ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/CHANGES000066400000000000000000000004371515131525300177100ustar00rootroot000000000000003.0.1 (unreleased) ===== * Fix socket len in `getaddrinfo`. 3.0.0 (2025-04-20) ===== * Remove full struct support for `SockaddrStorage`, only allocate by size. * Use native API to convert back and forth to OCaml socketaddr 2.2.0 (2025-01-30) ===== * Fix copy code in `getaddrinfo`. ocaml-posix-4.0.2/modules/socket/README.md000066400000000000000000000022341515131525300201710ustar00rootroot00000000000000# posix-socket This module provides OCaml ctypes bindings to system-specific low-level socket structure and data-types. The interface is implemented using [ocaml-ctypes](https://github.com/ocamllabs/ocaml-ctypes) and is intended to exposed the machine-specific, low-level details of the most important parts of socket implementations. [Posix_socket](src/posix_socket.mli) provides an API compatible for both `Unix` and `Win32` systems. On POSIX systems, the following headers define the bound types and structures: * [sys/sock.h](https://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/socket.h.html) * [sys/un.h](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/un.h.html) * [netinet/in.h](https://pubs.opengroup.org/onlinepubs/009695399/basedefs/netinet/in.h.html) On windows systems, the following headers define the bound types and structures: * [winsock.h](https://docs.microsoft.com/en-us/windows/win32/api/winsock/) * [ws2tcpip.h](https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/) Its API mirrors as much as possible the original POSIX definitions, including integers representation (network bytes order, host byte order). Happy hacking! ocaml-posix-4.0.2/modules/socket/examples/000077500000000000000000000000001515131525300205275ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/examples/dune000066400000000000000000000001221515131525300214000ustar00rootroot00000000000000(executable (name getaddrinfo) (modules getaddrinfo) (libraries posix-socket)) ocaml-posix-4.0.2/modules/socket/examples/getaddrinfo.ml000066400000000000000000000011511515131525300233450ustar00rootroot00000000000000open Ctypes open Posix_socket let from_ptr t ptr = from_voidp t (to_voidp ptr) let () = let host = Sys.argv.(1) in let resolved_addresses = getaddrinfo ~port:(`String Sys.argv.(2)) host in List.iter (fun sockaddr -> Printf.printf "sockaddr.sa_family = %d\n%!" (Sa_family.to_int !@(sockaddr |-> Sockaddr.sa_family)); let sockaddr_in = from_ptr SockaddrInet.t sockaddr in Printf.printf "sockaddr_in.sin_addr.s_addr = %d\n%!" (Unsigned.UInt32.to_int (ntohl !@(sockaddr_in |-> SockaddrInet.sin_addr |-> SockaddrInet.s_addr)))) resolved_addresses ocaml-posix-4.0.2/modules/socket/src/000077500000000000000000000000001515131525300175005ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/src/config/000077500000000000000000000000001515131525300207455ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/src/config/discover.ml000066400000000000000000000012641515131525300231200ustar00rootroot00000000000000module C = Configurator.V1 let has_caml_unix_get_sockaddr_c = {| #ifdef _WIN32 #include #endif #include #include int main() { union sock_addr_union sockaddr; socklen_param_type addr_len; value s; caml_unix_get_sockaddr(s, &sockaddr, &addr_len); return 0; } |} let () = C.main ~name:"posix-socket" (fun c -> let has_caml_unix_get_sockaddr = C.c_test c ~link_flags:["-lcamlrun"] has_caml_unix_get_sockaddr_c in C.C_define.gen_header_file c ~fname:"posix_socket_stubs.h" [ ( "HAS_CAML_UNIX_GET_SOCKADDR", C.C_define.Value.Switch has_caml_unix_get_sockaddr ); ]) ocaml-posix-4.0.2/modules/socket/src/config/dune000066400000000000000000000000751515131525300216250ustar00rootroot00000000000000(executable (name discover) (libraries dune.configurator)) ocaml-posix-4.0.2/modules/socket/src/constants/000077500000000000000000000000001515131525300215145ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/src/constants/dune000066400000000000000000000004471515131525300223770ustar00rootroot00000000000000(library (name posix_socket_constants) (public_name posix-socket.constants) (libraries ctypes.stubs)) (rule (targets posix_eai_errno_constants.ml) (deps ../generator/gen_eai_errno_constants.exe) (action (with-stdout-to %{targets} (run ../generator/gen_eai_errno_constants.exe)))) ocaml-posix-4.0.2/modules/socket/src/constants/posix_socket_constants.ml000066400000000000000000000021531515131525300266550ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct include Posix_eai_errno_constants.Def (S) let af_inet = S.constant "AF_INET" S.int let af_inet6 = S.constant "AF_INET6" S.int let af_unix = S.constant "AF_UNIX" S.int let af_unspec = S.constant "AF_UNSPEC" S.int let sa_family_t_len = S.constant "SA_FAMILY_T_LEN" S.int let sockaddr_storage_len = S.constant "SOCKADDR_STORAGE_LEN" S.int let sock_dgram = S.constant "SOCK_DGRAM" S.int let sock_stream = S.constant "SOCK_STREAM" S.int let sock_seqpacket = S.constant "SOCK_SEQPACKET" S.int let socklen_t_len = S.constant "SOCKLEN_T_LEN" S.int let ni_maxserv = S.constant "NI_MAXSERV" S.int let ni_maxhost = S.constant "NI_MAXHOST" S.int let ni_numerichost = S.constant "NI_NUMERICHOST" S.int let ni_numericserv = S.constant "NI_NUMERICSERV" S.int let ipproto_ip = S.constant "IPPROTO_IP" S.int let ipproto_ipv6 = S.constant "IPPROTO_IPV6" S.int let ipproto_icmp = S.constant "IPPROTO_ICMP" S.int let ipproto_raw = S.constant "IPPROTO_RAW" S.int let ipproto_tcp = S.constant "IPPROTO_TCP" S.int let ipproto_udp = S.constant "IPPROTO_UDP" S.int end ocaml-posix-4.0.2/modules/socket/src/dune000066400000000000000000000023331515131525300203570ustar00rootroot00000000000000(env (dev (flags (:standard -g -warn-error -A)))) (library (name posix_socket) (public_name posix-socket) (synopsis "posix-socket provides access to the features exposed in sys/socket.h") (foreign_stubs (language c) (names posix_socket_generated_stubs posix_socket_stubs) (extra_deps posix_socket_stubs.h)) (libraries unix ctypes posix-socket.types posix-socket.stubs)) (rule (targets posix_socket_stubs.h) (action (run ./config/discover.exe))) (rule (targets posix_socket_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_socket_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) (rule (targets posix_eai_errno_is_native_impl.ml) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps ../../../base/exec_path (:gen ./generator/target_is_native_detector.exe)) (action (with-stdout-to %{targets} (system "%{read:../../../base/exec_path} %{ocaml-config:system} %{gen}")))) (rule (targets posix_eai_errno_is_native_impl.ml) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps (:gen ./generator/target_is_native_detector.exe)) (action (with-stdout-to %{targets} (run %{gen})))) ocaml-posix-4.0.2/modules/socket/src/generator/000077500000000000000000000000001515131525300214665ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/src/generator/dune000066400000000000000000000036061515131525300223510ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-socket.stubs posix-base)) (executable (name gen_types_c) (modules gen_types_c) (libraries posix-socket.types posix-base)) (rule (targets gen_types.c) (action (run ./gen_types_c.exe %{targets}))) (rule (targets gen_types_c_target.exe) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-socket.constants posix-base eai_errno_defaults)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c_target.exe) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (library (name eai_errno_defaults) (libraries str posix_base) (modules eai_errno_defaults)) (executable (name gen_eai_errno_constants) (modules gen_eai_errno_constants) (libraries eai_errno_defaults)) (executable (name gen_eai_errno_type) (modules gen_eai_errno_type) (libraries eai_errno_defaults)) (executable (name gen_eai_errno_conversions) (modules gen_eai_errno_conversions) (libraries eai_errno_defaults)) (executable (name gen_is_native_detector) (modules gen_is_native_detector) (libraries eai_errno_defaults)) (rule (targets target_is_native_detector.c) (action (with-stdout-to %{targets} (run ./gen_is_native_detector.exe)))) (executable (name gen_get_value) (modules gen_get_value) (libraries eai_errno_defaults posix-socket)) (rule (targets target_is_native_detector.exe) (deps target_is_native_detector.c) (action (run %{ocaml-config:c_compiler} -o %{targets} target_is_native_detector.c))) ocaml-posix-4.0.2/modules/socket/src/generator/eai_errno_defaults.ml000066400000000000000000000073221515131525300256560ustar00rootroot00000000000000type eai_errno_def = { name : string; default : int; overrides : (string list * int) list; } let eai_errno_defs = [ { name = "ADDRFAMILY"; default = 1; overrides = [] }; { name = "AGAIN"; default = -3; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 2); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 11002); ]; }; { name = "BADFLAGS"; default = -1; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 3); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 10022); ]; }; { name = "FAIL"; default = -4; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 4); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 11003); ]; }; { name = "FAMILY"; default = -6; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 5); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 10047); ]; }; { name = "MEMORY"; default = -10; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 6); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 8); ]; }; { name = "NODATA"; default = 7; overrides = [(["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 11004)]; }; { name = "NONAME"; default = -2; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 8); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 11001); ]; }; { name = "SERVICE"; default = -8; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 9); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 10109); ]; }; { name = "SOCKTYPE"; default = -7; overrides = [ (["macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"], 10); (["win32"; "win64"; "cygwin"; "mingw"; "mingw64"], 10044); ]; }; { name = "SYSTEM"; default = -11; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 11 ); ]; }; { name = "BADHINTS"; default = 12; overrides = [] }; { name = "PROTOCOL"; default = 13; overrides = [] }; { name = "OVERFLOW"; default = -12; overrides = [ ( [ "macosx"; "freebsd"; "openbsd"; "netbsd"; "dragonfly"; "win32"; "win64"; "cygwin"; "mingw"; "mingw64"; ], 14 ); ]; }; ] (* Get the eai_errno value for a given system *) let get_value_for_system system eai_errno_def = (* Check if any override matches the current system *) let rec find_override = function | [] -> eai_errno_def.default | (systems, value) :: rest -> if List.mem system systems then value else find_override rest in find_override eai_errno_def.overrides (* Get platform-specific eai_errno defaults based on system *) let get_eai_errno_defaults system = List.map (fun def -> (def.name, get_value_for_system system def)) eai_errno_defs (* Main eai_errno defaults to use for this build *) let eai_errno_defaults = get_eai_errno_defaults Posix_base.System_detect.system ocaml-posix-4.0.2/modules/socket/src/generator/eai_errno_defaults.mli000066400000000000000000000002711515131525300260230ustar00rootroot00000000000000type eai_errno_def = { name : string; default : int; overrides : (string list * int) list; } val eai_errno_defs : eai_errno_def list val eai_errno_defaults : (string * int) list ocaml-posix-4.0.2/modules/socket/src/generator/gen_constants_c.ml000066400000000000000000000016731515131525300251760ustar00rootroot00000000000000let generate_eai_errno_defaults_c () = let defs = List.map (fun (name, value) -> Printf.sprintf "#ifndef EAI_%s\n#define EAI_%s %d\n#endif\n" name name value) Eai_errno_defaults.eai_errno_defaults in String.concat "\n" defs module Types = Posix_base.Generators.Types (struct module Types = Posix_socket_constants.Def let c_headers = Printf.sprintf {| #ifdef _WIN32 #include #include #else #include #include #include #include #include #endif %s #define SA_FAMILY_T_LEN (sizeof(((struct sockaddr*)0)->sa_family)) #define SOCKLEN_T_LEN (sizeof(socklen_t)) #define SOCKADDR_STORAGE_LEN (sizeof(struct sockaddr_storage)) #ifndef NI_MAXHOST #define NI_MAXHOST 1025 #endif #ifndef NI_MAXSERV #define NI_MAXSERV 32 #endif |} (generate_eai_errno_defaults_c ()) end) let () = Types.gen () ocaml-posix-4.0.2/modules/socket/src/generator/gen_eai_errno_constants.ml000066400000000000000000000010611515131525300267060ustar00rootroot00000000000000let generate_constant_definition () = let names = List.map (fun (def : Eai_errno_defaults.eai_errno_def) -> def.name) Eai_errno_defaults.eai_errno_defs in let lines = ["module Def (S : Cstubs.Types.TYPE) = struct"] in let let_lines = List.map (fun name -> Printf.sprintf "let eai_%s = S.constant \"EAI_%s\" S.int\n" (String.lowercase_ascii name) name) names in lines @ let_lines @ ["end"] let () = let type_def = generate_constant_definition () in List.iter print_endline type_def ocaml-posix-4.0.2/modules/socket/src/generator/gen_eai_errno_conversions.ml000066400000000000000000000033571515131525300272540ustar00rootroot00000000000000(* Generator for errno conversion functions *) let generate_header () = [ "(* Generated errno conversion functions *)"; "open Posix_socket_constants.Def (Posix_socket_generated_constants)"; ""; ] let generate_of_int_function () = let variants = List.map (fun (def : Eai_errno_defaults.eai_errno_def) -> def.name) Eai_errno_defaults.eai_errno_defs in let lines = ["(** Convert eai_errno code to variant *)"; "let error_of_int n ="] in (* First errno without 'else' *) let first_name = List.hd variants in let const_name = String.lowercase_ascii first_name in let first_line = Printf.sprintf " if n = eai_%s then `%s" const_name first_name in (* Rest of the errnos *) let rest_variants = List.tl variants in let condition_lines = List.map (fun name -> let const_name = String.lowercase_ascii name in Printf.sprintf " else if n = eai_%s then `%s" const_name name) rest_variants in lines @ [first_line] @ condition_lines @ [" else `UNKNOWN n"] let generate_to_int_function () = let variants = List.map (fun (def : Eai_errno_defaults.eai_errno_def) -> def.name) Eai_errno_defaults.eai_errno_defs in let lines = [""; "(** Convert variant to errno code *)"; "let int_of_error = function"] in let case_lines = List.map (fun name -> let const_name = String.lowercase_ascii name in Printf.sprintf " | `%s -> eai_%s" name const_name) variants in lines @ case_lines @ [" | `UNKNOWN n -> n"] let () = let header = generate_header () in let of_int = generate_of_int_function () in let to_int = generate_to_int_function () in let output = header @ of_int @ to_int in List.iter print_endline output ocaml-posix-4.0.2/modules/socket/src/generator/gen_eai_errno_type.ml000066400000000000000000000014531515131525300256600ustar00rootroot00000000000000(* Generator for the errno polymorphic variant type *) let generate_type_definition () = let variants = List.map (fun (def : Eai_errno_defaults.eai_errno_def) -> def.name) Eai_errno_defaults.eai_errno_defs in let lines = [ "(** Comprehensive eai_errno type covering Linux, BSD, macOS, and \ Windows values *)"; "type error = ["; ] in (* Generate polymorphic variant constructors from errno_defs *) let variant_lines = List.mapi (fun i name -> let sep = if i = 0 then " " else "| " in " " ^ sep ^ "`" ^ name) variants in (* Add unknown directly *) lines @ variant_lines @ [" (* Unknown *)"; " | `UNKNOWN of int"; "]"] let () = let type_def = generate_type_definition () in List.iter print_endline type_def ocaml-posix-4.0.2/modules/socket/src/generator/gen_get_value.ml000066400000000000000000000012731515131525300246270ustar00rootroot00000000000000(* Generate get_value function for tests using errno_defs *) let generate_get_value () = (* Generate cases from errno_defs (not errno_defaults) to get all errno names *) let cases = List.map (fun (def : Eai_errno_defaults.eai_errno_def) -> Printf.sprintf " | \"%s\" -> `%s" def.name def.name) Eai_errno_defaults.eai_errno_defs in Printf.sprintf {|(* Auto-generated function - do not edit manually *) (* Generated from errno_defaults.mli using gen_get_value *) (* Function to get system errno value from errno name *) let get_value = function %s | _ -> failwith "Unknown errno" |} (String.concat "\n" cases) let () = print_endline (generate_get_value ()) ocaml-posix-4.0.2/modules/socket/src/generator/gen_is_native_detector.ml000066400000000000000000000014721515131525300265270ustar00rootroot00000000000000(* Generate C program that outputs OCaml is_native pattern matching *) let generate_is_native_detector_c () = let names = List.map fst Eai_errno_defaults.eai_errno_defaults in let cases = List.map (fun name -> Printf.sprintf {|#ifdef EAI_%s printf(" | `%s -> true\n"); #else printf(" | `%s -> false\n"); #endif|} name name name) names in Printf.sprintf {|#include #ifdef _WIN32 #include #include #else #include #endif int main() { printf("(* Auto-generated file - do not edit manually *)\n\n"); printf("let is_native = function\n"); %s printf(" | `UNKNOWN _ -> false\n"); return 0; }|} (String.concat "\n" cases) let () = let c_code = generate_is_native_detector_c () in print_endline c_code ocaml-posix-4.0.2/modules/socket/src/generator/gen_stubs.ml000066400000000000000000000006551515131525300240170ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_socket_stubs.Def let c_headers = {| #ifdef _WIN32 #include #include #else #include #include #include #include #endif #include #include |} let concurrency = Cstubs.unlocked let prefix = "posix_socket" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/socket/src/generator/gen_types_c.ml000066400000000000000000000005011515131525300243130ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_socket_types.Def let c_headers = {| #ifdef _WIN32 #include #include #else #include #include #include #include #endif |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/socket/src/posix_socket.ml000066400000000000000000000104161515131525300225460ustar00rootroot00000000000000open Ctypes include Posix_socket_types include Posix_socket_stubs.Def (Posix_socket_generated_stubs) include Posix_eai_errno_is_native_impl type sockaddr_storage = unit let sockaddr_storage () = to_voidp (allocate_n char ~count:sockaddr_storage_len) type socket_type = int let socket_type_t = int let from_sockaddr_storage t ptr = from_voidp t (to_voidp ptr) exception Error of error let strerror err = strerror (int_of_error err) let () = Printexc.register_printer (function | Error err -> Some (Printf.sprintf "Posix_socket.Error(%s)" (strerror err)) | _ -> None) module Addrinfo = Types.Addrinfo module Sockaddr = struct include Types.Sockaddr let from_sockaddr_storage = from_sockaddr_storage t end type sockaddr = Sockaddr.t structure let sockaddr_t = Sockaddr.t type in_port = Unsigned.uint16 let in_port_t = uint16_t module SockaddrInet = struct include Types.SockaddrInet let from_sockaddr_storage = from_sockaddr_storage t end type sockaddr_in = SockaddrInet.t structure let sockaddr_in_t = SockaddrInet.t module SockaddrInet6 = struct include Types.SockaddrInet6 let from_sockaddr_storage = from_sockaddr_storage t end type sockaddr_in6 = SockaddrInet6.t structure let sockaddr_in6_t = SockaddrInet6.t let sockaddr_len s = if is_null s then 0 else ( match !@(s |-> Sockaddr.sa_family) with | id when id = af_inet -> sizeof sockaddr_in_t | id when id = af_inet6 -> sizeof sockaddr_in6_t | id -> failwith (Printf.sprintf "Unsupported socket family: %x" (Sa_family.to_int id))) let getnameinfo sockaddr_ptr = let s = allocate_n char ~count:ni_maxhost in let p = allocate_n char ~count:ni_maxserv in match getnameinfo sockaddr_ptr (Socklen.of_int (sockaddr_len sockaddr_ptr)) s (Socklen.of_int ni_maxhost) p (Socklen.of_int ni_maxserv) (ni_numerichost lor ni_numericserv) with | 0 -> let host = let length = Unsigned.Size_t.to_int (strnlen s (Unsigned.Size_t.of_int ni_maxhost)) in string_from_ptr s ~length in let port = let length = Unsigned.Size_t.to_int (strnlen p (Unsigned.Size_t.of_int ni_maxserv)) in let port = string_from_ptr p ~length in try int_of_string port with _ -> ( match getservbyname p null with | ptr when is_null ptr -> failwith "getnameinfo" | ptr -> Unsigned.UInt16.to_int (ntohs !@(ptr |-> Types.Servent.s_port))) in (host, port) | n -> raise (Error (error_of_int n)) let getaddrinfo = let get_sockaddr p = let finalise () = ignore (Sys.opaque_identity p) in let rec get_ptrs ~cur p = if is_null !@p then List.rev cur else ( let addrinfo = !@p in let sockaddr = !@(addrinfo |-> Types.Addrinfo.ai_addr) in Gc.finalise_last finalise sockaddr; get_ptrs ~cur:(sockaddr :: cur) (addrinfo |-> Types.Addrinfo.ai_next)) in get_ptrs ~cur:[] p in fun ?hints ?port host -> let port = match port with | Some (`Int port) -> let s = string_of_int port in let c = CArray.of_string s in CArray.start c | Some (`String s) -> let c = CArray.of_string s in CArray.start c | None -> from_voidp char null in let p = allocate_n ~finalise:(fun p -> let p = !@p in if not (is_null p) then freeaddrinfo p) (ptr Addrinfo.t) ~count:1 in let hints = Option.value ~default:(from_voidp Types.Addrinfo.t null) hints in match getaddrinfo host port hints p with | 0 -> get_sockaddr p | n -> raise (Error (error_of_int n)) external alloc_sockaddr : _ Cstubs_internals.fatptr -> int -> Unix.sockaddr = "posix_socket_alloc_sockaddr" let fatptr = function Cstubs_internals.CPointer s -> s let to_unix_sockaddr s = alloc_sockaddr (fatptr s) (sockaddr_len s) external get_sockaddr : Unix.sockaddr -> _ Cstubs_internals.fatptr -> unit = "posix_socket_get_sockaddr" let from_unix_sockaddr s = let storage = sockaddr_storage () in get_sockaddr s (fatptr storage); Sockaddr.from_sockaddr_storage storage ocaml-posix-4.0.2/modules/socket/src/posix_socket.mli000066400000000000000000000307061515131525300227230ustar00rootroot00000000000000(** POSIX socket interface bindings. This module provides OCaml bindings to the POSIX socket API defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html} sys/socket.h} and {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netdb.h.html} netdb.h}. It includes functions for address resolution, byte order conversion, and socket address manipulation. *) open Ctypes (** {1 Error Handling} Error codes returned by address resolution functions like {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html} getaddrinfo} and {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getnameinfo.html} getnameinfo}. *) (** Address resolution error codes (EAI_* constants). *) type error = [ `ADDRFAMILY (** Address family not supported *) | `AGAIN (** Temporary failure in name resolution *) | `BADFLAGS (** Invalid flags value *) | `BADHINTS (** Invalid hints value *) | `FAIL (** Non-recoverable failure in name resolution *) | `FAMILY (** Address family not supported *) | `MEMORY (** Memory allocation failure *) | `NODATA (** No address associated with hostname *) | `NONAME (** Name or service not known *) | `PROTOCOL (** Resolved protocol is unknown *) | `SOCKTYPE (** Socket type not supported *) | `OVERFLOW (** Argument buffer overflow *) | `SERVICE (** Service not supported for socket type *) | `SYSTEM (** System error, check errno *) | `UNKNOWN of int (** Unknown error code *) ] (** Convert an error to its integer representation. *) val int_of_error : error -> int (** Convert an integer to an error code. *) val error_of_int : int -> error (** Returns [true] if this error code is natively defined on this platform. *) val is_native : error -> bool (** Return a human-readable error message. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/gai_strerror.html} gai_strerror(3)}. *) val strerror : error -> string (** Exception raised by address resolution functions on error. *) exception Error of error (** {1 Byte Order Conversion} Functions for converting between network byte order (big-endian) and host byte order. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/htonl.html} byteorder(3)}. *) (** Convert 32-bit integer from network to host byte order. *) val ntohl : Unsigned.uint32 -> Unsigned.uint32 (** Convert 16-bit integer from network to host byte order. *) val ntohs : Unsigned.uint16 -> Unsigned.uint16 (** Convert 32-bit integer from host to network byte order. *) val htonl : Unsigned.uint32 -> Unsigned.uint32 (** Convert 16-bit integer from host to network byte order. *) val htons : Unsigned.uint16 -> Unsigned.uint16 (** {1 Socket Types} Socket type constants used when creating sockets. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html} socket(2)}. *) (** Abstract type representing socket types. *) type socket_type (** Ctypes representation of socket_type. *) val socket_type_t : socket_type typ (** Datagram socket (connectionless, unreliable). Used with UDP. *) val sock_dgram : socket_type (** Stream socket (connection-oriented, reliable). Used with TCP. *) val sock_stream : socket_type (** Sequenced packet socket (connection-oriented, reliable, message boundaries preserved). *) val sock_seqpacket : socket_type (** {1 Address Families} Socket address family constants. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html} sys/socket.h}. *) (** Module for the [sa_family] field type. *) module Sa_family = Posix_socket_types.Sa_family (** Type alias for address family. *) type sa_family_t = Sa_family.t (** Ctypes representation of sa_family_t. *) val sa_family_t : sa_family_t typ (** IPv4 address family (AF_INET). *) val af_inet : sa_family_t (** IPv6 address family (AF_INET6). *) val af_inet6 : sa_family_t (** Unspecified address family (AF_UNSPEC). Used to request any address family. *) val af_unspec : sa_family_t (** {1 Name Resolution Constants} Constants for {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getnameinfo.html} getnameinfo(3)}. *) (** Maximum length of a service name string. *) val ni_maxserv : int (** Maximum length of a host name string. *) val ni_maxhost : int (** Return numeric form of the host address. *) val ni_numerichost : int (** Return numeric form of the service (port number). *) val ni_numericserv : int (** {1 Protocol Constants} IP protocol numbers for use with sockets. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html} netinet/in.h}. *) (** Internet Protocol (IP). *) val ipproto_ip : int (** Internet Protocol version 6 (IPv6). *) val ipproto_ipv6 : int (** Internet Control Message Protocol (ICMP). *) val ipproto_icmp : int (** Raw IP packets. *) val ipproto_raw : int (** Transmission Control Protocol (TCP). *) val ipproto_tcp : int (** User Datagram Protocol (UDP). *) val ipproto_udp : int (** {1 Socket Length Type} The [socklen_t] type used for socket address lengths. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html} sys/socket.h}. *) (** Unsigned module for socklen_t arithmetic. *) module Socklen : Unsigned.S (** Abstract socklen_t type. *) type socklen_t (** Ctypes representation of socklen_t. *) val socklen_t : socklen_t typ (** {1 Socket Address Storage} Generic socket address storage large enough to hold any socket address type. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html} sockaddr_storage}. *) (** Abstract type for socket address storage. *) type sockaddr_storage (** Allocate a new socket address storage structure. *) val sockaddr_storage : unit -> sockaddr_storage ptr (** Size of sockaddr_storage in bytes. *) val sockaddr_storage_len : int (** {1 Generic Socket Address} The generic [sockaddr] structure. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html} sockaddr}. *) (** Generic socket address structure. *) module Sockaddr : sig (** Abstract sockaddr type. *) type t (** Ctypes structure type. *) val t : t structure typ (** Address family field. *) val sa_family : (sa_family_t, t structure) field (** Convert from sockaddr_storage to sockaddr. *) val from_sockaddr_storage : sockaddr_storage ptr -> t structure ptr end (** Type alias for sockaddr structure. *) type sockaddr = Sockaddr.t structure (** Ctypes representation of sockaddr. *) val sockaddr_t : sockaddr typ (** Return the actual length of a socket address based on its family. *) val sockaddr_len : sockaddr ptr -> int (** {1 Address Info} The [addrinfo] structure used by getaddrinfo. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html} getaddrinfo(3)}. *) (** Address information structure returned by [getaddrinfo]. *) module Addrinfo : sig (** Abstract addrinfo type. *) type t (** Ctypes structure type. *) val t : t structure typ (** Input flags (AI_* constants). *) val ai_flags : (int, t structure) field (** Address family (AF_* constants). *) val ai_family : (int, t structure) field (** Socket type (SOCK_* constants). *) val ai_socktype : (socket_type, t structure) field (** Protocol (IPPROTO_* constants). *) val ai_protocol : (int, t structure) field (** Length of socket address. *) val ai_addrlen : (socklen_t, t structure) field (** Socket address. *) val ai_addr : (sockaddr ptr, t structure) field (** Next addrinfo in linked list. *) val ai_next : (t structure ptr, t structure) field end (** {1 Port Type} *) (** Port number type (16-bit unsigned integer in network byte order). *) type in_port = Unsigned.uint16 (** Ctypes representation of in_port_t. *) val in_port_t : Unsigned.uint16 typ (** {1 IPv4 Socket Address} The [sockaddr_in] structure for IPv4 addresses. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html} netinet/in.h}. *) (** IPv4 socket address structure. *) module SockaddrInet : sig (** IPv4 address type (32-bit). *) type in_addr = Unsigned.uint32 (** Ctypes representation of in_addr_t. *) val in_addr_t : in_addr typ (** Ctypes representation of struct in_addr. *) val in_addr : in_addr structure typ (** The s_addr field containing the IPv4 address. *) val s_addr : (in_addr, in_addr structure) field (** Abstract sockaddr_in type. *) type t (** Ctypes structure type. *) val t : t structure typ (** Address family (always AF_INET). *) val sin_family : (sa_family_t, t structure) field (** Port number in network byte order. *) val sin_port : (in_port, t structure) field (** IPv4 address. *) val sin_addr : (in_addr structure, t structure) field (** Convert from sockaddr_storage to sockaddr_in. *) val from_sockaddr_storage : sockaddr_storage ptr -> t structure ptr end (** Type alias for IPv4 socket address. *) type sockaddr_in = SockaddrInet.t structure (** Ctypes representation of sockaddr_in. *) val sockaddr_in_t : sockaddr_in typ (** {1 IPv6 Socket Address} The [sockaddr_in6] structure for IPv6 addresses. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html} netinet/in.h}. *) (** IPv6 socket address structure. *) module SockaddrInet6 : sig (** IPv6 address type (128-bit). *) type in6_addr (** Ctypes representation of struct in6_addr. *) val in6_addr : in6_addr structure typ (** The s6_addr field containing the IPv6 address bytes. *) val s6_addr : (in6_addr, in6_addr structure) field (** Abstract sockaddr_in6 type. *) type t (** Ctypes structure type. *) val t : t structure typ (** Address family (always AF_INET6). *) val sin6_family : (sa_family_t, t structure) field (** Port number in network byte order. *) val sin6_port : (in_port, t structure) field (** IPv6 flow information. *) val sin6_flowinfo : (Unsigned.uint32, t structure) field (** IPv6 address. *) val sin6_addr : (in6_addr structure, t structure) field (** Scope ID for link-local addresses. *) val sin6_scope_id : (Unsigned.uint32, t structure) field (** Convert from sockaddr_storage to sockaddr_in6. *) val from_sockaddr_storage : sockaddr_storage ptr -> t structure ptr end (** Type alias for IPv6 socket address. *) type sockaddr_in6 = SockaddrInet6.t structure (** Ctypes representation of sockaddr_in6. *) val sockaddr_in6_t : sockaddr_in6 typ (** {1 Address Resolution Functions} *) (** Convert a socket address to a hostname and port number. This is a wrapper around {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getnameinfo.html} getnameinfo(3)}. @param sockaddr The socket address to convert. @return A tuple [(hostname, port)]. @raise Error if the conversion fails. *) val getnameinfo : sockaddr ptr -> string * int (** Resolve a hostname to a list of socket addresses. This is a wrapper around {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html} getaddrinfo(3)}. @param hints Optional hints to filter results. @param port Optional port number or service name. @param hostname The hostname to resolve. @return A list of socket addresses. @raise Error if resolution fails. Example: {[ let addresses = getaddrinfo ~port:(`Int 443) "example.com" in List.iter (fun addr -> let host, port = getnameinfo addr in Printf.printf "%s:%d\n" host port) addresses ]} *) val getaddrinfo : ?hints:Addrinfo.t structure ptr -> ?port:[ `Int of int | `String of string ] -> string -> sockaddr ptr list (** {1 Utility Functions} *) (** Calculate the length of a null-terminated string up to a maximum. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/strnlen.html} strnlen(3)}. *) val strnlen : char ptr -> Unsigned.size_t -> Unsigned.size_t (** {1 Unix Module Interoperability} Functions for converting between [Unix.sockaddr] and POSIX socket addresses. *) (** Convert a [Unix.sockaddr] to a POSIX socket address. @param addr The Unix socket address to convert. @return A pointer to the equivalent POSIX sockaddr. *) val from_unix_sockaddr : Unix.sockaddr -> sockaddr ptr (** Convert a POSIX socket address to [Unix.sockaddr]. @param addr The POSIX socket address to convert. @return The equivalent Unix socket address. *) val to_unix_sockaddr : sockaddr ptr -> Unix.sockaddr ocaml-posix-4.0.2/modules/socket/src/posix_socket_stubs.c000066400000000000000000000021211515131525300235720ustar00rootroot00000000000000#ifdef _WIN32 #include #endif #include #include #include #include "ctypes_cstubs_internals.h" #include "posix_socket_stubs.h" CAMLprim value posix_socket_get_sockaddr(value socket, value socket_storage) { CAMLparam2(socket, socket_storage); union sock_addr_union *sockaddr = CTYPES_ADDR_OF_FATPTR(socket_storage); socklen_param_type addr_len; #ifdef HAS_CAML_UNIX_GET_SOCKADDR caml_unix_get_sockaddr(socket, sockaddr, &addr_len); #else get_sockaddr(socket, sockaddr, &addr_len); #endif CAMLreturn(Val_unit); } CAMLprim value posix_socket_alloc_sockaddr(value socket_addr_ptr, value socket_addr_len) { CAMLparam2(socket_addr_ptr, socket_addr_len); union sock_addr_union *sockaddr = CTYPES_ADDR_OF_FATPTR(socket_addr_ptr); size_t sockaddr_len = Int_val(socket_addr_len); #ifdef HAS_CAML_UNIX_GET_SOCKADDR value socket = acaml_unix_alloc_sockaddr(sockaddr, sockaddr_len, -1); #else value socket = alloc_sockaddr(sockaddr, sockaddr_len, -1); #endif CAMLreturn(socket); } ocaml-posix-4.0.2/modules/socket/src/stubs/000077500000000000000000000000001515131525300206405ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/src/stubs/dune000066400000000000000000000013211515131525300215130ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_socket_stubs) (public_name posix-socket.stubs) (libraries posix-socket.types ctypes.stubs)) (rule (targets posix_socket_generated_types.ml) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps ../../../../base/exec_path (:gen ../generator/gen_types_c_target.exe)) (action (with-stdout-to %{targets} (system "%{read:../../../../base/exec_path} %{ocaml-config:system} %{gen}")))) (rule (targets posix_socket_generated_types.ml) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps (:gen ../generator/gen_types_c_target.exe)) (action (with-stdout-to %{targets} (run %{gen})))) ocaml-posix-4.0.2/modules/socket/src/stubs/posix_socket_stubs.ml000066400000000000000000000021641515131525300251270ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F open Posix_socket_types module Types = Posix_socket_types.Def (Posix_socket_generated_types) open Types let const_void_ptr = typedef (ptr void) "const void *" let getnameinfo = foreign "getnameinfo" (ptr sockaddr_t @-> socklen_t @-> ptr char @-> socklen_t @-> ptr char @-> socklen_t @-> int @-> returning int) let getaddrinfo = foreign "getaddrinfo" (string @-> ptr char @-> ptr Addrinfo.t @-> ptr (ptr Addrinfo.t) @-> returning int) let freeaddrinfo = foreign "freeaddrinfo" (ptr Addrinfo.t @-> returning void) let getservbyname = foreign "getservbyname" (ptr char @-> ptr void @-> returning (ptr Servent.t)) let strerror = foreign "gai_strerror" (int @-> returning string) let strnlen = foreign "strnlen" (ptr char @-> size_t @-> returning size_t) let htonl = foreign "htonl" (uint32_t @-> returning uint32_t) let htons = foreign "htons" (uint16_t @-> returning uint16_t) let ntohs = foreign "ntohs" (uint16_t @-> returning uint16_t) let ntohl = foreign "ntohl" (uint32_t @-> returning uint32_t) end ocaml-posix-4.0.2/modules/socket/src/types/000077500000000000000000000000001515131525300206445ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/src/types/dune000066400000000000000000000021431515131525300215220ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_socket_types) (public_name posix-socket.types) (libraries posix-socket.constants posix-base ctypes.stubs)) (rule (targets posix_socket_generated_constants.ml) (enabled_if (<> %{ocaml-config:host} %{ocaml-config:target})) (deps ../../../../base/exec_path (:gen ../generator/gen_constants_c_target.exe)) (action (with-stdout-to %{targets} (system "%{read:../../../../base/exec_path} %{ocaml-config:system} %{gen}")))) (rule (targets posix_socket_generated_constants.ml) (enabled_if (= %{ocaml-config:host} %{ocaml-config:target})) (deps (:gen ../generator/gen_constants_c_target.exe)) (action (with-stdout-to %{targets} (run %{gen})))) (rule (targets posix_eai_errno_type.ml) (deps ../generator/gen_eai_errno_type.exe) (action (with-stdout-to %{targets} (run ../generator/gen_eai_errno_type.exe)))) (rule (targets posix_eai_errno_conversions.ml) (deps ../generator/gen_eai_errno_conversions.exe) (action (with-stdout-to %{targets} (run ../generator/gen_eai_errno_conversions.exe)))) ocaml-posix-4.0.2/modules/socket/src/types/posix_socket_types.ml000066400000000000000000000061061515131525300251370ustar00rootroot00000000000000open Ctypes module Constants = Posix_socket_constants.Def (Posix_socket_generated_constants) include Posix_eai_errno_type include Posix_eai_errno_conversions let socklen : (module Posix_base.Types.Unsigned) = Posix_base.Types.mkUnsigned ~name:"socklen_t" ~size:Constants.socklen_t_len module Socklen = (val socklen : Posix_base.Types.Unsigned) type socklen_t = Socklen.t let socklen_t = Socklen.t let sa_family : (module Posix_base.Types.Unsigned) = Posix_base.Types.mkUnsigned ~name:"sa_family_t" ~size:Constants.sa_family_t_len module Sa_family = (val sa_family : Posix_base.Types.Unsigned) type sa_family_t = Sa_family.t let sa_family_t = Sa_family.t include Constants let af_inet = Sa_family.of_int af_inet let af_inet6 = Sa_family.of_int af_inet6 let af_unspec = Sa_family.of_int af_unspec module Def (S : Cstubs.Types.TYPE) = struct let sa_family_t = S.lift_typ sa_family_t let socklen_t = S.lift_typ socklen_t module Sockaddr = struct type t = unit let t = S.structure "sockaddr" let sa_family = S.field t "sa_family" sa_family_t let () = S.seal t end type sockaddr = Sockaddr.t structure let sockaddr_t : sockaddr S.typ = Sockaddr.t module Addrinfo = struct type t = unit let t = S.structure "addrinfo" let ai_flags = S.field t "ai_flags" S.int let ai_family = S.field t "ai_family" S.int let ai_socktype = S.field t "ai_socktype" S.int let ai_protocol = S.field t "ai_protocol" S.int let ai_addrlen = S.field t "ai_addrlen" socklen_t let ai_addr = S.field t "ai_addr" (S.ptr Sockaddr.t) let ai_next = S.field t "ai_next" (S.ptr t) let () = S.seal t end module Servent = struct type t = unit let t = S.structure "servent" let s_port = S.field t "s_port" S.uint16_t let () = S.seal t end type in_port = Unsigned.uint16 let in_port_t = S.uint16_t module SockaddrInet = struct type in_addr = Unsigned.uint32 let in_addr_t = S.uint32_t let in_addr = S.structure "in_addr" let s_addr = S.field in_addr "s_addr" in_addr_t let () = S.seal in_addr type t = unit let t = S.structure "sockaddr_in" let sin_family = S.field t "sin_family" sa_family_t let sin_port = S.field t "sin_port" in_port_t let sin_addr = S.field t "sin_addr " in_addr let () = S.seal t end type sockaddr_in = SockaddrInet.t structure let sockaddr_in_t : sockaddr_in S.typ = SockaddrInet.t module SockaddrInet6 = struct type in6_addr = Unsigned.uint8 carray let in6_addr = S.structure "in6_addr" let s6_addr = S.field in6_addr "s6_addr" (S.array 16 S.uint8_t) let () = S.seal in6_addr type t = unit let t = S.structure "sockaddr_in6" let sin6_family = S.field t "sin6_family" sa_family_t let sin6_port = S.field t "sin6_port" in_port_t let sin6_flowinfo = S.field t "sin6_flowinfo" S.uint32_t let sin6_addr = S.field t "sin6_addr" in6_addr let sin6_scope_id = S.field t "sin6_scope_id" S.uint32_t let () = S.seal t end type sockaddr_in6 = SockaddrInet6.t structure let sockaddr_in6_t : sockaddr_in6 S.typ = SockaddrInet6.t end ocaml-posix-4.0.2/modules/socket/src/types/posix_socket_types.mli000066400000000000000000000046471515131525300253200ustar00rootroot00000000000000open Ctypes module Sa_family : Unsigned.S type error = Posix_eai_errno_type.error val int_of_error : error -> int val error_of_int : int -> error type sa_family_t = Sa_family.t include module type of Posix_socket_constants.Def (Posix_socket_generated_constants) val sa_family_t : sa_family_t typ val af_inet : sa_family_t val af_inet6 : sa_family_t val af_unspec : sa_family_t module Socklen : Unsigned.S type socklen_t = Socklen.t val socklen_t : socklen_t typ module Def (S : Cstubs.Types.TYPE) : sig module Sockaddr : sig type t val t : t structure S.typ val sa_family : (sa_family_t, t structure) S.field end type sockaddr = Sockaddr.t structure val sockaddr_t : sockaddr S.typ module Addrinfo : sig type t val t : t structure S.typ val ai_flags : (int, t structure) S.field val ai_family : (int, t structure) S.field val ai_socktype : (int, t structure) S.field val ai_protocol : (int, t structure) S.field val ai_addrlen : (socklen_t, t structure) S.field val ai_addr : (sockaddr ptr, t structure) S.field val ai_next : (t structure ptr, t structure) S.field end module Servent : sig type t val t : t structure S.typ val s_port : (Unsigned.uint16, t structure) S.field end type in_port = Unsigned.uint16 val in_port_t : Unsigned.uint16 S.typ module SockaddrInet : sig type in_addr = Unsigned.uint32 val in_addr_t : Unsigned.uint32 S.typ val in_addr : in_addr structure S.typ val s_addr : (in_addr, in_addr structure) S.field type t val t : t structure S.typ val sin_family : (sa_family_t, t structure) S.field val sin_port : (in_port, t structure) S.field val sin_addr : (in_addr structure, t structure) S.field end type sockaddr_in = SockaddrInet.t structure val sockaddr_in_t : sockaddr_in S.typ module SockaddrInet6 : sig type in6_addr = Unsigned.uint8 carray val in6_addr : in6_addr structure S.typ val s6_addr : (in6_addr, in6_addr structure) S.field type t val t : t structure S.typ val sin6_family : (sa_family_t, t structure) S.field val sin6_port : (in_port, t structure) S.field val sin6_flowinfo : (Unsigned.uint32, t structure) S.field val sin6_addr : (in6_addr structure, t structure) S.field val sin6_scope_id : (Unsigned.uint32, t structure) S.field end type sockaddr_in6 = SockaddrInet6.t structure val sockaddr_in6_t : sockaddr_in6 S.typ end ocaml-posix-4.0.2/modules/socket/test/000077500000000000000000000000001515131525300176705ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/socket/test/dune000066400000000000000000000010211515131525300205400ustar00rootroot00000000000000(executable (name test) (libraries posix-socket)) (rule (alias citest) (package posix-socket) (action (run %{exe:test.exe}))) (rule (targets test_get_value.ml) (deps (:gen ../src/generator/gen_get_value.exe)) (action (with-stdout-to %{targets} (run %{gen})))) (executable (name test_eai_errno_defaults) (modules test_eai_errno_defaults test_get_value) (libraries posix-socket eai_errno_defaults unix)) (rule (alias citest) (package posix-socket) (action (run %{exe:test_eai_errno_defaults.exe}))) ocaml-posix-4.0.2/modules/socket/test/test.ml000066400000000000000000000032371515131525300212060ustar00rootroot00000000000000open Ctypes open Posix_socket let () = Printf.printf "sizeof(socklen_t) = %d\n%!" (sizeof socklen_t) let from_ptr t ptr = from_voidp t (to_voidp ptr) let () = let inet_addr = Unix.inet_addr_of_string "0.0.0.1" in let sockaddr = from_unix_sockaddr (Unix.ADDR_INET (inet_addr, 80)) in Printf.printf "sockaddr.sa_family = %d\n%!" (Sa_family.to_int !@(sockaddr |-> Sockaddr.sa_family)); let sockaddr_in = from_ptr SockaddrInet.t sockaddr in Printf.printf "sockaddr_in.sin_addr.s_addr = %d\n%!" (Unsigned.UInt32.to_int (ntohl !@(sockaddr_in |-> SockaddrInet.sin_addr |-> SockaddrInet.s_addr))); let unix_socket = to_unix_sockaddr sockaddr in match unix_socket with | Unix.ADDR_INET (inet_addr, port) -> Printf.printf "Unix.ADDR_INET(%S,%d)\n%!" (Unix.string_of_inet_addr inet_addr) port | _ -> assert false let () = match getaddrinfo "google.com" with | exception Posix_socket.Error `AGAIN -> () | sockaddr :: _ -> let name, port = getnameinfo sockaddr in Printf.printf "Socket name: %s, port: %d\n%!" name port | _ -> assert false let () = match getaddrinfo "/invalid" with | exception Posix_socket.Error v -> Printf.printf "As expected, got exception %s for invalid getaddrinfo call!\n%!" (Posix_socket.strerror v) | _ -> assert false let () = match getnameinfo Ctypes.(coerce (ptr void) (ptr Sockaddr.t) null) with | exception Posix_socket.Error v -> Printf.printf "As expected exception %s for invalid getaddrinfo call!\n%!" (Posix_socket.strerror v) | _ -> assert false let () = Gc.full_major (); Gc.full_major () ocaml-posix-4.0.2/modules/socket/test/test_eai_errno_defaults.ml000066400000000000000000000052341515131525300251170ustar00rootroot00000000000000open Posix_socket (* get_value is now generated from eai_errno_defaults.mli in Test_get_value module *) let () = Printf.printf "=== POSIX Errno Default Values Test ===\n\n"; (* Print system information *) Printf.printf "Platform: system=%s\n\n" Posix_base.System_detect.system; Printf.printf "Comparing default eai errno values with system values...\n\n"; (* Compare regular eai errno values *) Printf.printf "eai_errno constants:\n"; Printf.printf "%-20s | %-10s | %-10s | %-10s | %s\n" "Name" "Default" "System" "Native" "Status"; Printf.printf "%s\n" (String.make 77 '-'); let matching = ref 0 in let different = ref 0 in let different_list = ref [] in List.iter (fun (name, default_value) -> let value = Test_get_value.get_value name in let int_value = Posix_socket.int_of_error value in let is_native_val = is_native value in let native_str = if is_native_val then "YES" else "NO" in let status, mark = if int_value = default_value then ( incr matching; ("MATCH", " ")) else ( incr different; different_list := (name, default_value, int_value) :: !different_list; ("DIFFERENT", "**")) in Printf.printf "%s%-20s | %-10d | %-10d | %-10s | %s\n" mark name default_value int_value native_str status) Eai_errno_defaults.eai_errno_defaults; (* Summary *) Printf.printf "\n=== Summary ===\n"; Printf.printf "Total eai_errno constants tested: %d\n" (List.length Eai_errno_defaults.eai_errno_defaults); Printf.printf "Values matching defaults: %d\n" !matching; Printf.printf "Values different from defaults: %d\n" !different; if !different > 0 then ( Printf.printf "\nValues that differ from defaults:\n"; List.iter (fun (name, default_val, system_val) -> Printf.printf " %-20s: default=%d, system=%d (diff=%d)\n" name default_val system_val (system_val - default_val)) (List.rev !different_list)); Printf.printf "\nNote: The 'Native' column shows whether the eai errno is natively\n"; Printf.printf "defined by the system (YES) or using a placeholder fallback (NO).\n"; Printf.printf "\nValues that match the defaults may either:\n"; Printf.printf " 1. Be natively defined by the system with that value, OR\n"; Printf.printf " 2. Not be defined by the system and use the fallback default value\n"; Printf.printf "\nValues that differ from defaults are definitely defined by the system.\n"; Printf.printf "Use the is_native() function to distinguish between cases 1 and 2.\n"; Printf.printf "\nTest completed successfully (informational only, no failures)\n" ocaml-posix-4.0.2/modules/stat/000077500000000000000000000000001515131525300163745ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/stat/CHANGES000066400000000000000000000010161515131525300173650ustar00rootroot000000000000003.2.0 (unreleased) * Initial release of posix-stat module * Provides bindings to sys/stat.h * Includes stat/fstat/lstat for file status queries * Includes chmod/fchmod for permission changes * Includes mkdir/mkfifo for file creation * Includes umask for permission mask control * Includes modern *at family of functions (fstatat, fchmodat, mkdirat, mkfifoat) * Integration with posix-time2 for timespec timestamps * Comprehensive file type test functions (s_isreg, s_isdir, etc.) * Unix-only module (not available on Windows) ocaml-posix-4.0.2/modules/stat/src/000077500000000000000000000000001515131525300171635ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/stat/src/constants/000077500000000000000000000000001515131525300211775ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/stat/src/constants/dune000066400000000000000000000002621515131525300220550ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_stat_constants) (public_name posix-stat.constants) (libraries posix-base posix-types ctypes.stubs)) ocaml-posix-4.0.2/modules/stat/src/constants/posix_stat_constants.ml000066400000000000000000000027251515131525300260300ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct let mode_t = S.lift_typ Posix_types.mode_t (* File type mask and constants *) let s_ifmt = S.constant "S_IFMT" mode_t let s_ifreg = S.constant "S_IFREG" mode_t let s_ifdir = S.constant "S_IFDIR" mode_t let s_iflnk = S.constant "S_IFLNK" mode_t let s_ifchr = S.constant "S_IFCHR" mode_t let s_ifblk = S.constant "S_IFBLK" mode_t let s_ififo = S.constant "S_IFIFO" mode_t let s_ifsock = S.constant "S_IFSOCK" mode_t (* Special mode bits *) let s_isuid = S.constant "S_ISUID" mode_t let s_isgid = S.constant "S_ISGID" mode_t let s_isvtx = S.constant "S_ISVTX" mode_t (* Owner permissions *) let s_irwxu = S.constant "S_IRWXU" mode_t let s_irusr = S.constant "S_IRUSR" mode_t let s_iwusr = S.constant "S_IWUSR" mode_t let s_ixusr = S.constant "S_IXUSR" mode_t (* Group permissions *) let s_irwxg = S.constant "S_IRWXG" mode_t let s_irgrp = S.constant "S_IRGRP" mode_t let s_iwgrp = S.constant "S_IWGRP" mode_t let s_ixgrp = S.constant "S_IXGRP" mode_t (* Other permissions *) let s_irwxo = S.constant "S_IRWXO" mode_t let s_iroth = S.constant "S_IROTH" mode_t let s_iwoth = S.constant "S_IWOTH" mode_t let s_ixoth = S.constant "S_IXOTH" mode_t (* *at function flags *) let at_fdcwd = S.constant "AT_FDCWD" S.int let at_symlink_nofollow = S.constant "AT_SYMLINK_NOFOLLOW" S.int let at_removedir = S.constant "AT_REMOVEDIR" S.int let at_eaccess = S.constant "AT_EACCESS" S.int end ocaml-posix-4.0.2/modules/stat/src/dune000066400000000000000000000010751515131525300200440ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_stat) (public_name posix-stat) (synopsis "posix-stat provides access to the features exposed in sys/stat.h") (foreign_stubs (language c) (names posix_stat_generated_stubs)) (libraries ctypes posix-types posix-errno posix-time2 posix-stat.types posix-stat.stubs)) (rule (targets posix_stat_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_stat_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) ocaml-posix-4.0.2/modules/stat/src/generator/000077500000000000000000000000001515131525300211515ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/stat/src/generator/dune000066400000000000000000000016451515131525300220350ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-stat.stubs posix-base)) (executable (name gen_types_c) (modules gen_types_c) (libraries posix-stat.types posix-base)) (rule (targets gen_types.c) (action (run ./gen_types_c.exe %{targets}))) (rule (targets gen_types_c) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-stat.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/stat/src/generator/gen_constants_c.ml000066400000000000000000000003261515131525300246530ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_stat_constants.Def let c_headers = {| #include #include #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/stat/src/generator/gen_stubs.ml000066400000000000000000000004231515131525300234730ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_stat_stubs.Def let c_headers = {| #include #include #include |} let concurrency = Cstubs.unlocked let prefix = "posix_stat" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/stat/src/generator/gen_types_c.ml000066400000000000000000000006031515131525300240010ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_stat_types.Def let c_headers = {| #include #include #include #include /* Platform compatibility for macOS */ #ifdef __APPLE__ #define st_atim st_atimespec #define st_mtim st_mtimespec #define st_ctim st_ctimespec #endif |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/stat/src/posix_stat.ml000066400000000000000000000103431515131525300217130ustar00rootroot00000000000000open Ctypes include Posix_stat_stubs.Def (Posix_stat_generated_stubs) include Posix_stat_types (* File type test functions - implement as OCaml functions *) let s_isreg mode = Posix_types.Mode.(equal (logand mode s_ifmt) s_ifreg) let s_isdir mode = Posix_types.Mode.(equal (logand mode s_ifmt) s_ifdir) let s_islnk mode = Posix_types.Mode.(equal (logand mode s_ifmt) s_iflnk) let s_ischr mode = Posix_types.Mode.(equal (logand mode s_ifmt) s_ifchr) let s_isblk mode = Posix_types.Mode.(equal (logand mode s_ifmt) s_ifblk) let s_isfifo mode = Posix_types.Mode.(equal (logand mode s_ifmt) s_ififo) let s_issock mode = Posix_types.Mode.(equal (logand mode s_ifmt) s_ifsock) (* High-level stat type *) type stat = { st_dev : Posix_types.dev_t; st_ino : Posix_types.ino_t; st_mode : Posix_types.mode_t; st_nlink : Posix_types.nlink_t; st_uid : Posix_types.uid_t; st_gid : Posix_types.gid_t; st_rdev : Posix_types.dev_t; st_size : Posix_types.off_t; st_atim : Posix_time2.Timespec.t; st_mtim : Posix_time2.Timespec.t; st_ctim : Posix_time2.Timespec.t; st_blksize : Posix_types.blksize_t; st_blocks : Posix_types.blkcnt_t; } (* Helper to convert C struct stat to OCaml record *) let from_stat stat_ptr = let get f = getf stat_ptr f in let get_timespec f = let ts = get f in let tv_sec = Posix_types.Time.to_int64 (getf ts Types.Time2_types.Timespec.tv_sec) in let tv_nsec = Signed.Long.to_int64 (getf ts Types.Time2_types.Timespec.tv_nsec) in Posix_time2.Timespec.create tv_sec tv_nsec in { st_dev = get Types.Stat.st_dev; st_ino = get Types.Stat.st_ino; st_mode = get Types.Stat.st_mode; st_nlink = get Types.Stat.st_nlink; st_uid = get Types.Stat.st_uid; st_gid = get Types.Stat.st_gid; st_rdev = get Types.Stat.st_rdev; st_size = get Types.Stat.st_size; st_atim = get_timespec Types.Stat.st_atim; st_mtim = get_timespec Types.Stat.st_mtim; st_ctim = get_timespec Types.Stat.st_ctim; st_blksize = get Types.Stat.st_blksize; st_blocks = get Types.Stat.st_blocks; } (* Helper to convert Unix.file_descr to int *) external fd_to_int : Unix.file_descr -> int = "%identity" (* stat functions *) let stat path = let st = make Types.Stat.t in ignore (Posix_errno.raise_on_neg ~call:"stat" (fun () -> stat path (addr st))); from_stat st let fstat fd = let st = make Types.Stat.t in ignore (Posix_errno.raise_on_neg ~call:"fstat" (fun () -> fstat (fd_to_int fd) (addr st))); from_stat st let lstat path = let st = make Types.Stat.t in ignore (Posix_errno.raise_on_neg ~call:"lstat" (fun () -> lstat path (addr st))); from_stat st (* chmod functions *) let chmod path mode = ignore (Posix_errno.raise_on_neg ~call:"chmod" (fun () -> chmod path mode)) let fchmod fd mode = ignore (Posix_errno.raise_on_neg ~call:"fchmod" (fun () -> fchmod (fd_to_int fd) mode)) (* Directory and special file creation *) let mkdir path mode = ignore (Posix_errno.raise_on_neg ~call:"mkdir" (fun () -> mkdir path mode)) let mkfifo path mode = ignore (Posix_errno.raise_on_neg ~call:"mkfifo" (fun () -> mkfifo path mode)) (* *at functions with optional arguments *) let fstatat ?(dirfd = Unix.stdin) ?(flags = []) path = let st = make Types.Stat.t in let fd_int = if dirfd = Unix.stdin then at_fdcwd else fd_to_int dirfd in let flags_int = List.fold_left ( lor ) 0 flags in ignore (Posix_errno.raise_on_neg ~call:"fstatat" (fun () -> fstatat fd_int path (addr st) flags_int)); from_stat st let fchmodat ?(dirfd = Unix.stdin) ?(flags = []) path mode = let fd_int = if dirfd = Unix.stdin then at_fdcwd else fd_to_int dirfd in let flags_int = List.fold_left ( lor ) 0 flags in ignore (Posix_errno.raise_on_neg ~call:"fchmodat" (fun () -> fchmodat fd_int path mode flags_int)) let mkdirat ?(dirfd = Unix.stdin) path mode = let fd_int = if dirfd = Unix.stdin then at_fdcwd else fd_to_int dirfd in ignore (Posix_errno.raise_on_neg ~call:"mkdirat" (fun () -> mkdirat fd_int path mode)) let mkfifoat ?(dirfd = Unix.stdin) path mode = let fd_int = if dirfd = Unix.stdin then at_fdcwd else fd_to_int dirfd in ignore (Posix_errno.raise_on_neg ~call:"mkfifoat" (fun () -> mkfifoat fd_int path mode)) ocaml-posix-4.0.2/modules/stat/src/posix_stat.mli000066400000000000000000000213371515131525300220710ustar00rootroot00000000000000(** POSIX file status and permissions. This module provides OCaml bindings to POSIX file status functions defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html} sys/stat.h}. It includes functions for querying file metadata, changing permissions, and creating directories and special files. {2 Example} {[ (* Get file information *) let info = stat "/etc/passwd" in Printf.printf "Size: %Ld bytes\n" (Posix_types.Off.to_int64 info.st_size); (* Check if it's a regular file *) if s_isreg info.st_mode then print_endline "Regular file" ]} *) (** {1 File Type Constants} Constants for the file type portion of [st_mode]. Use {!s_ifmt} to mask out the file type bits. *) (** File type mask. Use as [Posix_types.Mode.logand mode s_ifmt]. *) val s_ifmt : Posix_types.mode_t (** Regular file (S_IFREG). *) val s_ifreg : Posix_types.mode_t (** Directory (S_IFDIR). *) val s_ifdir : Posix_types.mode_t (** Symbolic link (S_IFLNK). *) val s_iflnk : Posix_types.mode_t (** Character device (S_IFCHR). *) val s_ifchr : Posix_types.mode_t (** Block device (S_IFBLK). *) val s_ifblk : Posix_types.mode_t (** FIFO/named pipe (S_IFIFO). *) val s_ififo : Posix_types.mode_t (** Socket (S_IFSOCK). *) val s_ifsock : Posix_types.mode_t (** {1 Permission Bit Constants} Constants for file permission bits in [st_mode]. *) (** {2 Special Mode Bits} *) (** Set-user-ID on execution (S_ISUID). *) val s_isuid : Posix_types.mode_t (** Set-group-ID on execution (S_ISGID). *) val s_isgid : Posix_types.mode_t (** Sticky bit (S_ISVTX). On directories, restricts file deletion. *) val s_isvtx : Posix_types.mode_t (** {2 Owner Permissions} *) (** Owner: read, write, execute (S_IRWXU = 0o700). *) val s_irwxu : Posix_types.mode_t (** Owner: read permission (S_IRUSR = 0o400). *) val s_irusr : Posix_types.mode_t (** Owner: write permission (S_IWUSR = 0o200). *) val s_iwusr : Posix_types.mode_t (** Owner: execute permission (S_IXUSR = 0o100). *) val s_ixusr : Posix_types.mode_t (** {2 Group Permissions} *) (** Group: read, write, execute (S_IRWXG = 0o070). *) val s_irwxg : Posix_types.mode_t (** Group: read permission (S_IRGRP = 0o040). *) val s_irgrp : Posix_types.mode_t (** Group: write permission (S_IWGRP = 0o020). *) val s_iwgrp : Posix_types.mode_t (** Group: execute permission (S_IXGRP = 0o010). *) val s_ixgrp : Posix_types.mode_t (** {2 Others Permissions} *) (** Others: read, write, execute (S_IRWXO = 0o007). *) val s_irwxo : Posix_types.mode_t (** Others: read permission (S_IROTH = 0o004). *) val s_iroth : Posix_types.mode_t (** Others: write permission (S_IWOTH = 0o002). *) val s_iwoth : Posix_types.mode_t (** Others: execute permission (S_IXOTH = 0o001). *) val s_ixoth : Posix_types.mode_t (** {1 File Type Test Functions} These functions test the [st_mode] field to determine file type. They are equivalent to the POSIX S_IS* macros. *) (** [s_isreg mode] returns [true] if [mode] indicates a regular file. *) val s_isreg : Posix_types.mode_t -> bool (** [s_isdir mode] returns [true] if [mode] indicates a directory. *) val s_isdir : Posix_types.mode_t -> bool (** [s_islnk mode] returns [true] if [mode] indicates a symbolic link. *) val s_islnk : Posix_types.mode_t -> bool (** [s_ischr mode] returns [true] if [mode] indicates a character device. *) val s_ischr : Posix_types.mode_t -> bool (** [s_isblk mode] returns [true] if [mode] indicates a block device. *) val s_isblk : Posix_types.mode_t -> bool (** [s_isfifo mode] returns [true] if [mode] indicates a FIFO/named pipe. *) val s_isfifo : Posix_types.mode_t -> bool (** [s_issock mode] returns [true] if [mode] indicates a socket. *) val s_issock : Posix_types.mode_t -> bool (** {1 File Status Structure} *) (** File status information returned by {!stat}, {!fstat}, and {!lstat}. Corresponds to POSIX [struct stat]. *) type stat = { st_dev : Posix_types.dev_t; st_ino : Posix_types.ino_t; st_mode : Posix_types.mode_t; st_nlink : Posix_types.nlink_t; st_uid : Posix_types.uid_t; st_gid : Posix_types.gid_t; st_rdev : Posix_types.dev_t; st_size : Posix_types.off_t; st_atim : Posix_time2.Timespec.t; st_mtim : Posix_time2.Timespec.t; st_ctim : Posix_time2.Timespec.t; st_blksize : Posix_types.blksize_t; st_blocks : Posix_types.blkcnt_t; } (** {1 File Status Functions} *) (** Get file status, following symbolic links. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html} stat(2)}. @raise Unix.Unix_error on failure. *) val stat : string -> stat (** Get file status for an open file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstat.html} fstat(2)}. @raise Unix.Unix_error on failure. *) val fstat : Unix.file_descr -> stat (** Get file status without following symbolic links. Returns information about the symbolic link itself, not its target. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/lstat.html} lstat(2)}. @raise Unix.Unix_error on failure. *) val lstat : string -> stat (** {1 Permission Functions} *) (** Change file permissions. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html} chmod(2)}. @raise Unix.Unix_error on failure. *) val chmod : string -> Posix_types.mode_t -> unit (** Change file permissions using a file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmod.html} fchmod(2)}. @raise Unix.Unix_error on failure. *) val fchmod : Unix.file_descr -> Posix_types.mode_t -> unit (** {1 File Creation} *) (** Create a directory. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html} mkdir(2)}. @raise Unix.Unix_error on failure. *) val mkdir : string -> Posix_types.mode_t -> unit (** Create a FIFO (named pipe). See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html} mkfifo(3)}. @raise Unix.Unix_error on failure. *) val mkfifo : string -> Posix_types.mode_t -> unit (** {1 File Creation Mask} *) (** Set the file mode creation mask. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/umask.html} umask(2)}. The umask is used to turn off permission bits when creating files. For example, [umask (Mode.of_int 0o022)] prevents group and others write permissions on newly created files. @return The previous umask value. *) val umask : Posix_types.mode_t -> Posix_types.mode_t (** {1 Directory-Relative Operations} These functions operate relative to a directory file descriptor, providing protection against certain race conditions (TOCTOU). See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatat.html} *at(2)} functions. *) (** Use current working directory as the base for relative paths. Pass this as [dirfd] to use CWD like the non-[*at] functions. *) val at_fdcwd : int (** Flag: do not follow symbolic links. *) val at_symlink_nofollow : int (** Flag: remove directory instead of file (for unlinkat). *) val at_removedir : int (** Flag: use effective IDs for access checks (for faccessat). *) val at_eaccess : int (** Like {!stat}/{!lstat} but relative to a directory file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatat.html} fstatat(2)}. @param dirfd Base directory (default: current working directory). @param flags May include {!at_symlink_nofollow} to not follow symlinks. @raise Unix.Unix_error on failure. *) val fstatat : ?dirfd:Unix.file_descr -> ?flags:int list -> string -> stat (** Like {!chmod} but relative to a directory file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html} fchmodat(2)}. @param dirfd Base directory (default: current working directory). @param flags Optional flags. @raise Unix.Unix_error on failure. *) val fchmodat : ?dirfd:Unix.file_descr -> ?flags:int list -> string -> Posix_types.mode_t -> unit (** Like {!mkdir} but relative to a directory file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdirat.html} mkdirat(2)}. @param dirfd Base directory (default: current working directory). @raise Unix.Unix_error on failure. *) val mkdirat : ?dirfd:Unix.file_descr -> string -> Posix_types.mode_t -> unit (** Like {!mkfifo} but relative to a directory file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html} mkfifoat(3)}. @param dirfd Base directory (default: current working directory). @raise Unix.Unix_error on failure. *) val mkfifoat : ?dirfd:Unix.file_descr -> string -> Posix_types.mode_t -> unit ocaml-posix-4.0.2/modules/stat/src/stubs/000077500000000000000000000000001515131525300203235ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/stat/src/stubs/dune000066400000000000000000000004561515131525300212060ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_stat_stubs) (public_name posix-stat.stubs) (libraries posix-stat.types posix-types ctypes.stubs)) (rule (targets posix_stat_generated_types.ml) (action (with-stdout-to %{targets} (run ../generator/gen_types_c)))) ocaml-posix-4.0.2/modules/stat/src/stubs/posix_stat_stubs.ml000066400000000000000000000024221515131525300242720ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F module Types = Posix_stat_types.Def (Posix_stat_generated_types) open Types (* stat family *) let stat = foreign "stat" (string @-> ptr Stat.t @-> returning int) let fstat = foreign "fstat" (int @-> ptr Stat.t @-> returning int) let lstat = foreign "lstat" (string @-> ptr Stat.t @-> returning int) (* chmod family *) let chmod = foreign "chmod" (string @-> Posix_types.mode_t @-> returning int) let fchmod = foreign "fchmod" (int @-> Posix_types.mode_t @-> returning int) (* Directory and special file creation *) let mkdir = foreign "mkdir" (string @-> Posix_types.mode_t @-> returning int) let mkfifo = foreign "mkfifo" (string @-> Posix_types.mode_t @-> returning int) (* umask *) let umask = foreign "umask" (Posix_types.mode_t @-> returning Posix_types.mode_t) (* *at functions *) let fstatat = foreign "fstatat" (int @-> string @-> ptr Stat.t @-> int @-> returning int) let fchmodat = foreign "fchmodat" (int @-> string @-> Posix_types.mode_t @-> int @-> returning int) let mkdirat = foreign "mkdirat" (int @-> string @-> Posix_types.mode_t @-> returning int) let mkfifoat = foreign "mkfifoat" (int @-> string @-> Posix_types.mode_t @-> returning int) end ocaml-posix-4.0.2/modules/stat/src/types/000077500000000000000000000000001515131525300203275ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/stat/src/types/dune000066400000000000000000000005411515131525300212050ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_stat_types) (public_name posix-stat.types) (libraries posix-stat.constants posix-base posix-types posix-time2.types ctypes.stubs)) (rule (targets posix_stat_generated_constants.ml) (action (with-stdout-to %{targets} (run ../generator/gen_constants_c)))) ocaml-posix-4.0.2/modules/stat/src/types/posix_stat_types.ml000066400000000000000000000044161515131525300243070ustar00rootroot00000000000000open Ctypes module Constants = Posix_stat_constants.Def (Posix_stat_generated_constants) (* Re-export constants *) let s_ifmt = Constants.s_ifmt let s_ifreg = Constants.s_ifreg let s_ifdir = Constants.s_ifdir let s_iflnk = Constants.s_iflnk let s_ifchr = Constants.s_ifchr let s_ifblk = Constants.s_ifblk let s_ififo = Constants.s_ififo let s_ifsock = Constants.s_ifsock let s_isuid = Constants.s_isuid let s_isgid = Constants.s_isgid let s_isvtx = Constants.s_isvtx let s_irwxu = Constants.s_irwxu let s_irusr = Constants.s_irusr let s_iwusr = Constants.s_iwusr let s_ixusr = Constants.s_ixusr let s_irwxg = Constants.s_irwxg let s_irgrp = Constants.s_irgrp let s_iwgrp = Constants.s_iwgrp let s_ixgrp = Constants.s_ixgrp let s_irwxo = Constants.s_irwxo let s_iroth = Constants.s_iroth let s_iwoth = Constants.s_iwoth let s_ixoth = Constants.s_ixoth let at_fdcwd = Constants.at_fdcwd let at_symlink_nofollow = Constants.at_symlink_nofollow let at_removedir = Constants.at_removedir let at_eaccess = Constants.at_eaccess module Def (S : Cstubs.Types.TYPE) = struct (* Import timespec type from posix-time2 *) module Time2_types = Posix_time2_types.Def (S) module Stat = struct type t = unit let t = S.structure "stat" (* Required POSIX fields *) let st_dev = S.field t "st_dev" (S.lift_typ Posix_types.dev_t) let st_ino = S.field t "st_ino" (S.lift_typ Posix_types.ino_t) let st_mode = S.field t "st_mode" (S.lift_typ Posix_types.mode_t) let st_nlink = S.field t "st_nlink" (S.lift_typ Posix_types.nlink_t) let st_uid = S.field t "st_uid" (S.lift_typ Posix_types.uid_t) let st_gid = S.field t "st_gid" (S.lift_typ Posix_types.gid_t) let st_rdev = S.field t "st_rdev" (S.lift_typ Posix_types.dev_t) let st_size = S.field t "st_size" (S.lift_typ Posix_types.off_t) (* Timespec timestamps *) let st_atim = S.field t "st_atim" Time2_types.Timespec.t let st_mtim = S.field t "st_mtim" Time2_types.Timespec.t let st_ctim = S.field t "st_ctim" Time2_types.Timespec.t (* XSI optional fields *) let st_blksize = S.field t "st_blksize" (S.lift_typ Posix_types.blksize_t) let st_blocks = S.field t "st_blocks" (S.lift_typ Posix_types.blkcnt_t) let () = S.seal t end type stat = Stat.t structure let stat_t : stat S.typ = Stat.t end ocaml-posix-4.0.2/modules/stat/src/types/posix_stat_types.mli000066400000000000000000000040201515131525300244470ustar00rootroot00000000000000open Ctypes (** File type constants *) val s_ifmt : Posix_types.mode_t val s_ifreg : Posix_types.mode_t val s_ifdir : Posix_types.mode_t val s_iflnk : Posix_types.mode_t val s_ifchr : Posix_types.mode_t val s_ifblk : Posix_types.mode_t val s_ififo : Posix_types.mode_t val s_ifsock : Posix_types.mode_t (** Special mode bits *) val s_isuid : Posix_types.mode_t val s_isgid : Posix_types.mode_t val s_isvtx : Posix_types.mode_t (** Permission bits *) val s_irwxu : Posix_types.mode_t val s_irusr : Posix_types.mode_t val s_iwusr : Posix_types.mode_t val s_ixusr : Posix_types.mode_t val s_irwxg : Posix_types.mode_t val s_irgrp : Posix_types.mode_t val s_iwgrp : Posix_types.mode_t val s_ixgrp : Posix_types.mode_t val s_irwxo : Posix_types.mode_t val s_iroth : Posix_types.mode_t val s_iwoth : Posix_types.mode_t val s_ixoth : Posix_types.mode_t (** *at function flags *) val at_fdcwd : int val at_symlink_nofollow : int val at_removedir : int val at_eaccess : int (** Structure definitions *) module Def (S : Cstubs.Types.TYPE) : sig module Time2_types : module type of Posix_time2_types.Def (S) module Stat : sig type t val t : t structure S.typ val st_dev : (Posix_types.dev_t, t structure) S.field val st_ino : (Posix_types.ino_t, t structure) S.field val st_mode : (Posix_types.mode_t, t structure) S.field val st_nlink : (Posix_types.nlink_t, t structure) S.field val st_uid : (Posix_types.uid_t, t structure) S.field val st_gid : (Posix_types.gid_t, t structure) S.field val st_rdev : (Posix_types.dev_t, t structure) S.field val st_size : (Posix_types.off_t, t structure) S.field val st_atim : (Time2_types.Timespec.t structure, t structure) S.field val st_mtim : (Time2_types.Timespec.t structure, t structure) S.field val st_ctim : (Time2_types.Timespec.t structure, t structure) S.field val st_blksize : (Posix_types.blksize_t, t structure) S.field val st_blocks : (Posix_types.blkcnt_t, t structure) S.field end type stat = Stat.t structure val stat_t : stat S.typ end ocaml-posix-4.0.2/modules/stat/test/000077500000000000000000000000001515131525300173535ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/stat/test/dune000066400000000000000000000002071515131525300202300ustar00rootroot00000000000000(executable (name test) (libraries posix-stat unix)) (rule (alias citest) (package posix-stat) (action (run %{exe:test.exe}))) ocaml-posix-4.0.2/modules/stat/test/test.ml000066400000000000000000000056211515131525300206700ustar00rootroot00000000000000open Posix_stat let test_stat () = Printf.printf "Testing stat on current directory...\n%!"; let st = stat "." in assert (s_isdir st.st_mode); Printf.printf " ✓ Current directory inode: %s\n%!" (Posix_types.Ino.to_string st.st_ino); Printf.printf " ✓ Current directory is detected as directory\n%!" let test_file_type_tests () = Printf.printf "\nTesting file type detection functions...\n%!"; let st = stat "." in assert (s_isdir st.st_mode); assert (not (s_isreg st.st_mode)); assert (not (s_islnk st.st_mode)); Printf.printf " ✓ File type tests work correctly\n%!" let test_constants () = Printf.printf "\nTesting permission constants...\n%!"; let mode = Posix_types.Mode.(logor s_irusr (logor s_iwusr s_irgrp)) in assert (Posix_types.Mode.(compare mode zero) > 0); Printf.printf " ✓ Permission constants work\n%!" let test_mkdir () = Printf.printf "\nTesting mkdir and rmdir...\n%!"; let temp_dir = "test_dir_" ^ string_of_int (Unix.getpid ()) in let mode = Posix_types.Mode.(logor s_irwxu (logor s_irgrp s_ixgrp)) in mkdir temp_dir mode; let st = stat temp_dir in assert (s_isdir st.st_mode); Unix.rmdir temp_dir; Printf.printf " ✓ mkdir/rmdir test passed\n%!" let test_chmod () = Printf.printf "\nTesting chmod...\n%!"; let temp_file = "test_file_" ^ string_of_int (Unix.getpid ()) in let fd = Unix.openfile temp_file [Unix.O_CREAT; Unix.O_WRONLY] 0o644 in Unix.close fd; let mode_rw = Posix_types.Mode.(logor s_irusr s_iwusr) in chmod temp_file mode_rw; let st = stat temp_file in assert (s_isreg st.st_mode); Unix.unlink temp_file; Printf.printf " ✓ chmod test passed\n%!" let test_fstat () = Printf.printf "\nTesting fstat...\n%!"; let fd = Unix.openfile "." [Unix.O_RDONLY] 0 in let st = fstat fd in assert (s_isdir st.st_mode); Unix.close fd; Printf.printf " ✓ fstat test passed\n%!" let test_lstat () = Printf.printf "\nTesting lstat...\n%!"; let st = lstat "." in assert (s_isdir st.st_mode); Printf.printf " ✓ lstat test passed\n%!" let test_umask () = Printf.printf "\nTesting umask...\n%!"; let old_mask = umask Posix_types.Mode.zero in let _ = umask old_mask in Printf.printf " ✓ umask test passed\n%!" let test_at_functions () = Printf.printf "\nTesting *at functions...\n%!"; let temp_dir = "test_at_dir_" ^ string_of_int (Unix.getpid ()) in let mode = Posix_types.Mode.(logor s_irwxu (logor s_irgrp s_ixgrp)) in (* Test fstatat with AT_FDCWD *) mkdirat temp_dir mode; let st = fstatat temp_dir in assert (s_isdir st.st_mode); Unix.rmdir temp_dir; Printf.printf " ✓ *at functions test passed\n%!" let () = Printf.printf "=== Running posix-stat tests ===\n\n%!"; test_stat (); test_file_type_tests (); test_constants (); test_mkdir (); test_chmod (); test_fstat (); test_lstat (); test_umask (); test_at_functions (); Printf.printf "\n=== All tests passed! ===\n%!" ocaml-posix-4.0.2/modules/time2/000077500000000000000000000000001515131525300164415ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/time2/CHANGES000066400000000000000000000005071515131525300174360ustar00rootroot000000000000002.2.0 (2025-01-30) ===== * Fix copy code in `getaddrinfo`. 2.1.0 (2025-01-16) ===== * Added `posix-math2` * Invoke `wine64` only when available. * Added `sockaddr_len` in `ocaml-posix`. * Add support for string and optional `port. * Add support for `hints`. 2.0.2 (2023-02-08) ===== **posix-time2** * Added `clock_nanosleep` ocaml-posix-4.0.2/modules/time2/README.md000066400000000000000000000016751515131525300177310ustar00rootroot00000000000000# posix-time2 This module provides OCaml ctypes bindings to system-specific low-level time-related structures, functions and data-types. The interface is implemented using [ocaml-ctypes](https://github.com/ocamllabs/ocaml-ctypes) and is intended to exposed the machine-specific, low-level details of the most important parts of socket implementations. The C API bound in this module are defined on POSIX systems by the following files: * [time.h](https://pubs.opengroup.org/onlinepubs/009695399/basedefs/time.h.html) * [sys/time.h](https://pubs.opengroup.org/onlinepubs/7908799/xsh/systime.h.html) The low-level API mirrors as much as possible the original POSIX definitions. It is defined in [posix_time2_types.mli](src/types/posix_time2_types.mli). This API can be used to build further C bindings using `ocaml-ctypes`. [posix_time2.mli](src/posix_time2.mli) provides a high-level API compatible exported from the low-level bindings. Happy hacking! ocaml-posix-4.0.2/modules/time2/src/000077500000000000000000000000001515131525300172305ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/time2/src/constants/000077500000000000000000000000001515131525300212445ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/time2/src/constants/dune000066400000000000000000000001631515131525300221220ustar00rootroot00000000000000(library (name posix_time2_constants) (public_name posix-time2.constants) (libraries posix-types ctypes.stubs)) ocaml-posix-4.0.2/modules/time2/src/constants/posix_time2_constants.ml000066400000000000000000000013661515131525300261420ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct let clockid_t = S.lift_typ Posix_types.clockid_t let clock_process_cputime_id = S.constant "CLOCK_PROCESS_CPUTIME_ID" clockid_t let clock_thread_cputime_id = S.constant "CLOCK_THREAD_CPUTIME_ID" clockid_t let clock_monotonic = S.constant "CLOCK_MONOTONIC" clockid_t let clock_realtime = S.constant "CLOCK_REALTIME" clockid_t let itimer_real = S.constant "ITIMER_REAL" S.int let itimer_virtual = S.constant "ITIMER_VIRTUAL" S.int let itimer_prof = S.constant "ITIMER_PROF" S.int let fd_setsize = S.constant "FD_SETSIZE" S.int let fd_set_size = S.constant "FD_SET_SIZE" S.int let fd_set_alignment = S.constant "FD_SET_ALIGNMENT" S.int let timer_abstime = S.constant "TIMER_ABSTIME" S.int end ocaml-posix-4.0.2/modules/time2/src/dune000066400000000000000000000010331515131525300201030ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_time2) (public_name posix-time2) (synopsis "posix-time2 provides access to POSIX's time-related APIs") (foreign_stubs (language c) (names posix_time2_generated_stubs)) (libraries unix ctypes posix-errno posix-time2.types posix-time2.stubs)) (rule (targets posix_time2_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_time2_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) ocaml-posix-4.0.2/modules/time2/src/generator/000077500000000000000000000000001515131525300212165ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/time2/src/generator/dune000066400000000000000000000016501515131525300220760ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-time2.stubs posix-base)) (executable (name gen_types_c) (modules gen_types_c) (libraries posix-time2.types posix-base)) (rule (targets gen_types.c) (action (run ./gen_types_c.exe %{targets}))) (rule (targets gen_types_c) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-time2.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/time2/src/generator/gen_constants_c.ml000066400000000000000000000010301515131525300247110ustar00rootroot00000000000000module Constants = Posix_base.Generators.Types (struct module Types = Posix_time2_constants.Def let c_headers = {| #include #include // Some macos are missing these defines: #ifdef __MACH__ #ifndef CLOCK_REALTIME #define CLOCK_REALTIME 0 #endif #ifndef CLOCK_MONOTONIC #define CLOCK_MONOTONIC 1 #endif #ifndef TIMER_ABSTIME #define TIMER_ABSTIME 1 #endif #endif #define FD_SET_SIZE sizeof(fd_set) #define FD_SET_ALIGNMENT offsetof(struct { char c; fd_set x; }, x) |} end) let () = Constants.gen () ocaml-posix-4.0.2/modules/time2/src/generator/gen_stubs.ml000066400000000000000000000030121515131525300235350ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_time2_stubs.Def let c_headers = {| #include #include static inline void ocaml_posix_time2_fd_zero(fd_set *fdset) { FD_ZERO(fdset); } static inline void ocaml_posix_time2_fd_set(int fd, fd_set *fdset) { FD_SET(fd, fdset); } static inline int ocaml_posix_time2_fd_isset(int fd, fd_set *fdset) { return FD_ISSET(fd, fdset); } static inline void ocaml_posix_time2_fd_clr(int fd, fd_set *fdset) { FD_CLR(fd, fdset); } #if defined(__MACH__) && !defined(__gnu_hurd__) #define TIMING_GIGA (1000000000) /* timespec difference (monotonic) right - left */ inline void timespec_monodiff_rml(struct timespec *ts_out, const struct timespec *ts_in) { ts_out->tv_sec = ts_in->tv_sec - ts_out->tv_sec; ts_out->tv_nsec = ts_in->tv_nsec - ts_out->tv_nsec; if (ts_out->tv_nsec < 0) { ts_out->tv_sec = ts_out->tv_sec - 1; ts_out->tv_nsec = ts_out->tv_nsec + TIMING_GIGA; } } inline int clock_nanosleep(clock_t clock_id, int flags, const struct timespec *req, struct timespec *rem) { struct timespec ts_delta; if (flags == 0) { // clock_id is ignored in this case return nanosleep(req, rem); } int retval = clock_gettime(clock_id, &ts_delta ); if (retval != 0) return retval; timespec_monodiff_rml(&ts_delta, req); return nanosleep(&ts_delta, NULL); } #endif |} let concurrency = Cstubs.unlocked let prefix = "posix_time2" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/time2/src/generator/gen_types_c.ml000066400000000000000000000002671515131525300240540ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_time2_types.Def let c_headers = {| #include #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/time2/src/posix_time2.ml000066400000000000000000000262611515131525300220330ustar00rootroot00000000000000open Ctypes include Posix_time2_stubs.Def (Posix_time2_generated_stubs) module Timespec = struct type t = { tv_sec : int64; tv_nsec : int64 } let to_timespec timespec = let get f = getf timespec f in { tv_sec = Posix_types.Time.to_int64 (get Types.Timespec.tv_sec); tv_nsec = Signed.Long.to_int64 (get Types.Timespec.tv_nsec); } let from_timespec { tv_sec; tv_nsec } = let timespec = make Types.Timespec.t in setf timespec Types.Timespec.tv_sec (Posix_types.Time.of_int64 tv_sec); setf timespec Types.Timespec.tv_nsec (Signed.Long.of_int64 tv_nsec); timespec let max_nsec = 1000000000L let compare x y = match Int64.compare x.tv_sec y.tv_sec with | 0 -> Int64.compare x.tv_nsec y.tv_nsec | d -> d let create sec nsec = let rec normalize sec nsec = if nsec < Int64.zero then normalize (Int64.pred sec) (Int64.add nsec max_nsec) else if nsec >= max_nsec then normalize (Int64.succ sec) (Int64.sub nsec max_nsec) else (sec, nsec) in let tv_sec, tv_nsec = normalize sec nsec in { tv_sec; tv_nsec } let add x y = create Int64.(add x.tv_sec y.tv_sec) Int64.(add x.tv_nsec y.tv_nsec) let sub x y = create Int64.(sub x.tv_sec y.tv_sec) Int64.(sub x.tv_nsec y.tv_nsec) let add_sec sec t = { t with tv_sec = Int64.add t.tv_sec sec } let sub_sec sec t = { t with tv_sec = Int64.sub t.tv_sec sec } let add_nsec nsec t = create t.tv_sec (Int64.add t.tv_nsec nsec) let sub_nsec nsec t = create t.tv_sec (Int64.sub t.tv_nsec nsec) let to_string t = Printf.sprintf "%Ld.%09Ld" t.tv_sec t.tv_nsec end module Timeval = struct type t = { tv_sec : int64; tv_usec : int64 } let to_timeval timeval = let get f = getf timeval f in { tv_sec = Posix_types.Time.to_int64 (get Types.Timeval.tv_sec); tv_usec = Posix_types.Suseconds.to_int64 (get Types.Timeval.tv_usec); } let from_timeval { tv_sec; tv_usec } = let timeval = make Types.Timeval.t in setf timeval Types.Timeval.tv_sec (Posix_types.Time.of_int64 tv_sec); setf timeval Types.Timeval.tv_usec (Posix_types.Suseconds.of_int64 tv_usec); timeval let max_usec = 1000000L let compare x y = match Int64.compare x.tv_sec y.tv_sec with | 0 -> Int64.compare x.tv_usec y.tv_usec | d -> d let create sec usec = let rec normalize sec usec = if usec < Int64.zero then normalize (Int64.pred sec) (Int64.add usec max_usec) else if usec >= max_usec then normalize (Int64.succ sec) (Int64.sub usec max_usec) else (sec, usec) in let tv_sec, tv_usec = normalize sec usec in { tv_sec; tv_usec } let add x y = create Int64.(add x.tv_sec y.tv_sec) Int64.(add x.tv_usec y.tv_usec) let sub x y = create Int64.(sub x.tv_sec y.tv_sec) Int64.(sub x.tv_usec y.tv_usec) let add_sec sec t = { t with tv_sec = Int64.add t.tv_sec sec } let sub_sec sec t = { t with tv_sec = Int64.sub t.tv_sec sec } let add_usec usec t = create t.tv_sec (Int64.add t.tv_usec usec) let sub_usec usec t = create t.tv_sec (Int64.sub t.tv_usec usec) let to_string t = Printf.sprintf "%Ld.%06Ld" t.tv_sec t.tv_usec end module Tm = struct type t = { tm_sec : int; tm_min : int; tm_hour : int; tm_mday : int; tm_mon : int; tm_year : int; tm_wday : int; tm_yday : int; tm_isdst : int; } let to_tm tm = let get f = getf tm f in { tm_sec = get Types.Tm.tm_sec; tm_min = get Types.Tm.tm_min; tm_hour = get Types.Tm.tm_hour; tm_mday = get Types.Tm.tm_mday; tm_mon = get Types.Tm.tm_mon; tm_year = get Types.Tm.tm_year; tm_wday = get Types.Tm.tm_wday; tm_yday = get Types.Tm.tm_yday; tm_isdst = get Types.Tm.tm_isdst; } let from_tm tm = let _tm = make Types.Tm.t in setf _tm Types.Tm.tm_sec tm.tm_sec; setf _tm Types.Tm.tm_min tm.tm_min; setf _tm Types.Tm.tm_hour tm.tm_hour; setf _tm Types.Tm.tm_mday tm.tm_mday; setf _tm Types.Tm.tm_mon tm.tm_mon; setf _tm Types.Tm.tm_year tm.tm_year; setf _tm Types.Tm.tm_wday tm.tm_wday; setf _tm Types.Tm.tm_yday tm.tm_yday; setf _tm Types.Tm.tm_isdst tm.tm_isdst; _tm let create tm_sec tm_min tm_hour tm_mday tm_mon tm_year tm_wday tm_yday tm_isdst = let in_range a b x = a <= x && x <= b in if in_range 0 61 tm_sec && in_range 0 59 tm_min && in_range 0 23 tm_hour && in_range 0 31 tm_mday && in_range 0 11 tm_mon && in_range 0 6 tm_wday && in_range 0 365 tm_yday then Some { tm_sec; tm_min; tm_hour; tm_mday; tm_mon; tm_year; tm_wday; tm_yday; tm_isdst; } else None let compare x y = match compare x.tm_year y.tm_year with | 0 -> ( match compare x.tm_mon y.tm_mon with | 0 -> ( match compare x.tm_mday y.tm_mday with | 0 -> ( match compare x.tm_hour y.tm_hour with | 0 -> ( match compare x.tm_min y.tm_min with | 0 -> compare x.tm_sec y.tm_sec | d -> d) | d -> d) | d -> d) | d -> d) | d -> d end module Itimerval = struct type t = { it_interval : Timeval.t; it_value : Timeval.t } let to_itimerval itimerval = let get f = getf itimerval f in { it_interval = Timeval.to_timeval (get Types.Itimerval.it_interval); it_value = Timeval.to_timeval (get Types.Itimerval.it_value); } let from_itimerval { it_interval; it_value } = let itimerval = make Types.Itimerval.t in setf itimerval Types.Itimerval.it_interval (Timeval.from_timeval it_interval); setf itimerval Types.Itimerval.it_value (Timeval.from_timeval it_value); itimerval end module Itimerspec = struct type t = { it_interval : Timespec.t; it_value : Timespec.t } end type clock = [ `Realtime | `Monotonic | `Process_cputime | `Thread_cputime ] let clock_id_of_clock = function | `Realtime -> Posix_time2_types.clock_realtime | `Monotonic -> Posix_time2_types.clock_monotonic | `Process_cputime -> Posix_time2_types.clock_process_cputime_id | `Thread_cputime -> Posix_time2_types.clock_thread_cputime_id let asctime tm = asctime (addr (Tm.from_tm tm)) let clock_getres clock = Posix_errno.raise_on_none ~call:"clock_getres" (fun () -> let clock_id = clock_id_of_clock clock in let v = allocate_n Types.Timespec.t ~count:1 in match clock_getres clock_id v with | 0 -> Some (Timespec.to_timespec !@v) | _ -> None) let clock_gettime clock = Posix_errno.raise_on_none ~call:"clock_gettime" (fun () -> let clock_id = clock_id_of_clock clock in let v = allocate_n Types.Timespec.t ~count:1 in match clock_gettime clock_id v with | 0 -> Some (Timespec.to_timespec !@v) | _ -> None) let clock_settime clock timespec = Posix_errno.raise_on_none ~call:"clock_settime" (fun () -> let clock_id = clock_id_of_clock clock in let timespec = Timespec.from_timespec timespec in match clock_settime clock_id (addr timespec) with | 0 -> Some () | _ -> None) let ctime time = ctime (Ctypes.allocate Posix_types.time_t (Posix_types.Time.of_int64 time)) let gmtime time = Posix_errno.raise_on_none ~call:"gmtime" (fun () -> let time = Posix_types.Time.of_int64 time in match gmtime (Ctypes.allocate Posix_types.time_t time) with | ptr when is_null ptr -> None | ptr -> Some (Tm.to_tm !@ptr)) let localtime time = Posix_errno.raise_on_none ~call:"localtime" (fun () -> let time = Posix_types.Time.of_int64 time in match localtime (Ctypes.allocate Posix_types.time_t time) with | ptr when is_null ptr -> None | ptr -> Some (Tm.to_tm !@ptr)) let mktime tm = Posix_errno.raise_on_none ~call:"mktime" (fun () -> let tm = Tm.from_tm tm in let time = mktime (addr tm) in match Posix_types.Time.to_int64 time with | -1L -> None | time -> Some time) let nanosleep timespec = Posix_errno.raise_on_none ~call:"nanosleep" (fun () -> let timespec = Timespec.from_timespec timespec in match nanosleep (addr timespec) null with 0 -> Some () | _ -> None) let clock_nanosleep ~absolute ~clock timespec = Posix_errno.raise_on_none ~call:"clock_nanosleep" (fun () -> let timespec = Timespec.from_timespec timespec in let absolute = if absolute then Posix_time2_types.timer_abstime else 0 in let clock_id = clock_id_of_clock clock in match clock_nanosleep clock_id absolute (addr timespec) null with | 0 -> Some () | _ -> None) type itimer = [ `Real | `Virtual | `Prof ] let int_of_itimer = function | `Real -> Posix_time2_types.itimer_real | `Virtual -> Posix_time2_types.itimer_virtual | `Prof -> Posix_time2_types.itimer_prof let setitimer timer v = Posix_errno.raise_on_none ~call:"setitimer" (fun () -> let v = Itimerval.from_itimerval v in let old = allocate_n Types.Itimerval.t ~count:1 in match setitimer (int_of_itimer timer) (addr v) old with | x when x < 0 -> None | _ -> Some (Itimerval.to_itimerval !@old)) let getitimer timer = Posix_errno.raise_on_none ~call:"getitimer" (fun () -> let v = allocate_n Types.Itimerval.t ~count:1 in match getitimer (int_of_itimer timer) v with | x when x < 0 -> None | _ -> Some (Itimerval.to_itimerval !@v)) let gettimeofday () = Posix_errno.raise_on_none ~call:"gettimeofday" (fun () -> let timeval = allocate_n Types.Timeval.t ~count:1 in match gettimeofday timeval null with | x when x < 0 -> None | _ -> Some (Timeval.to_timeval !@timeval)) let select r w e timeval = Posix_errno.raise_on_none ~call:"select" (fun () -> let maxfd = ref (-1) in let mk_fd_set l = let set = allocate_n Posix_time2_types.fd_set ~count:1 in fd_zero set; List.iter (fun fd -> let fd = Obj.magic fd in if fd > Posix_time2_types.fd_setsize then failwith "invalid Unix.file_descriptor!"; if fd > !maxfd then maxfd := fd; fd_set fd set) l; set in let r_set = mk_fd_set r in let w_set = mk_fd_set w in let e_set = mk_fd_set e in let timeval = match timeval with | None -> from_voidp Types.Timeval.t null | Some timeval -> addr (Timeval.from_timeval timeval) in match select (!maxfd + 1) r_set w_set e_set timeval with | x when x < 0 -> None | _ -> let get_fd_set l fd_set = List.filter (fun fd -> fd_isset (Obj.magic fd) fd_set <> 0) l in Some (get_fd_set r r_set, get_fd_set w w_set, get_fd_set e e_set)) let utimes ~last_access ~last_modification path = Posix_errno.raise_on_none ~call:"utimes" (fun () -> let array = CArray.of_list Types.Timeval.t [ Timeval.from_timeval last_access; Timeval.from_timeval last_modification; ] in match utimes path (CArray.start array) with | x when x < 0 -> None | _ -> Some ()) ocaml-posix-4.0.2/modules/time2/src/posix_time2.mli000066400000000000000000000213301515131525300221740ustar00rootroot00000000000000(** POSIX time and clock functions. This module provides OCaml bindings to POSIX time functions defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html} time.h} and {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_time.h.html} sys/time.h}. It includes high-precision time structures, clock access, timers, and time conversion functions. *) (** {1 Time Structures} *) (** POSIX timespec: time with nanosecond precision. *) module Timespec : sig (** Time value with seconds and nanoseconds. A normalized value has [tv_nsec] between [0] and [999999999] (inclusive). *) type t = private { tv_sec : int64; tv_nsec : int64 } (** [create sec nsec] creates a new normalized timespec. *) val create : int64 -> int64 -> t (** [add t1 t2] adds two timespec values, returning a normalized result. *) val add : t -> t -> t (** [sub t1 t2] subtracts [t2] from [t1], returning a normalized result. *) val sub : t -> t -> t (** [add_sec s t] adds [s] seconds to [t]. *) val add_sec : int64 -> t -> t (** [add_nsec ns t] adds [ns] nanoseconds to [t]. *) val add_nsec : int64 -> t -> t (** [sub_sec s t] subtracts [s] seconds from [t]. *) val sub_sec : int64 -> t -> t (** [sub_nsec ns t] subtracts [ns] nanoseconds from [t]. *) val sub_nsec : int64 -> t -> t (** [to_string t] returns a string in the form ["sec.nsec"]. *) val to_string : t -> string (** [compare t1 t2] compares two time values. Returns [0] if equal, negative if [t1 < t2], positive if [t1 > t2]. *) val compare : t -> t -> int end (** Interval timer specification using timespec. *) module Itimerspec : sig type t = { it_interval : Timespec.t; (** Timer interval *) it_value : Timespec.t; (** Initial expiration *) } end (** POSIX timeval: time with microsecond precision. *) module Timeval : sig (** Time value with seconds and microseconds. A normalized value has [tv_usec] between [0] and [999999] (inclusive). *) type t = private { tv_sec : int64; tv_usec : int64 } (** [create sec usec] creates a new normalized timeval. *) val create : int64 -> int64 -> t (** [add t1 t2] adds two timeval values, returning a normalized result. *) val add : t -> t -> t (** [sub t1 t2] subtracts [t2] from [t1], returning a normalized result. *) val sub : t -> t -> t (** [add_sec s t] adds [s] seconds to [t]. *) val add_sec : int64 -> t -> t (** [add_usec us t] adds [us] microseconds to [t]. *) val add_usec : int64 -> t -> t (** [sub_sec s t] subtracts [s] seconds from [t]. *) val sub_sec : int64 -> t -> t (** [sub_usec us t] subtracts [us] microseconds from [t]. *) val sub_usec : int64 -> t -> t (** [to_string t] returns a string in the form ["sec.usec"]. *) val to_string : t -> string (** [compare t1 t2] compares two time values. Returns [0] if equal, negative if [t1 < t2], positive if [t1 > t2]. *) val compare : t -> t -> int end (** POSIX broken-down time structure. *) module Tm : sig (** Broken-down time with fields for seconds [0-60], minutes [0-59], hours [0-23], day of month [1-31], month [0-11], years since 1900, day of week [0-6] (Sunday = 0), day of year [0-365], and daylight saving flag (positive if DST, 0 if not, negative if unknown). *) type t = private { tm_sec : int; tm_min : int; tm_hour : int; tm_mday : int; tm_mon : int; tm_year : int; tm_wday : int; tm_yday : int; tm_isdst : int; } (** [create sec min hour mday mon year wday yday isdst] creates a new broken-down time value. Returns [None] if arguments are invalid. *) val create : int -> int -> int -> int -> int -> int -> int -> int -> int -> t option (** [compare t1 t2] compares two time values considering year, month, day, hour, minute, second in that order. *) val compare : t -> t -> int end (** Interval timer value using timeval. *) module Itimerval : sig type t = { it_interval : Timeval.t; (** Timer interval *) it_value : Timeval.t; (** Current value *) } end (** {1 Clock Types} *) (** Clock identifiers for {!clock_gettime} and related functions. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html} clock_getres(3)}. *) type clock = [ `Realtime (** System-wide real-time clock *) | `Monotonic (** Monotonic clock that cannot be set *) | `Process_cputime (** CPU time consumed by the process *) | `Thread_cputime (** CPU time consumed by the thread *) ] (** {1 Clock Functions} *) (** Convert broken-down time to a string. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/asctime.html} asctime(3)}. *) val asctime : Tm.t -> string (** Get clock resolution. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html} clock_getres(3)}. *) val clock_getres : clock -> Timespec.t (** Get current time from a clock. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html} clock_gettime(3)}. *) val clock_gettime : clock -> Timespec.t (** Set a clock's time (requires appropriate privileges). See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_settime.html} clock_settime(3)}. *) val clock_settime : clock -> Timespec.t -> unit (** Convert Unix timestamp to a date/time string. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/ctime.html} ctime(3)}. *) val ctime : int64 -> string (** Convert Unix timestamp to broken-down UTC time. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/gmtime.html} gmtime(3)}. *) val gmtime : int64 -> Tm.t (** Convert Unix timestamp to broken-down local time. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime.html} localtime(3)}. *) val localtime : int64 -> Tm.t (** Convert broken-down time to Unix timestamp. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/mktime.html} mktime(3)}. *) val mktime : Tm.t -> int64 (** {1 Sleep Functions} *) (** High-resolution sleep. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html} nanosleep(3)}. *) val nanosleep : Timespec.t -> unit (** High-resolution sleep with clock selection. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_nanosleep.html} clock_nanosleep(3)}. @param absolute If [true], sleep until the specified absolute time. If [false], sleep for the specified duration. @param clock The clock to use for timing. *) val clock_nanosleep : absolute:bool -> clock:clock -> Timespec.t -> unit (** {1 Interval Timers} *) (** Interval timer types for {!getitimer} and {!setitimer}. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getitimer.html} getitimer(3)}. *) type itimer = [ `Real (** ITIMER_REAL: decrements in real time, delivers SIGALRM *) | `Virtual (** ITIMER_VIRTUAL: decrements in process virtual time, delivers SIGVTALRM *) | `Prof (** ITIMER_PROF: decrements in process time, delivers SIGPROF *) ] (** Get the value of an interval timer. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getitimer.html} getitimer(3)}. *) val getitimer : itimer -> Itimerval.t (** Set an interval timer and return its previous value. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setitimer.html} setitimer(3)}. *) val setitimer : itimer -> Itimerval.t -> Itimerval.t (** {1 Time of Day} *) (** Get the current time of day. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/gettimeofday.html} gettimeofday(3)}. *) val gettimeofday : unit -> Timeval.t (** {1 I/O Multiplexing} *) (** Synchronous I/O multiplexing. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html} select(2)}. @param readfds File descriptors to check for readability. @param writefds File descriptors to check for writability. @param exceptfds File descriptors to check for exceptions. @param timeout Maximum time to wait, or [None] to block indefinitely. @return Triple of ready file descriptors [(readable, writable, exceptions)]. *) val select : Unix.file_descr list -> Unix.file_descr list -> Unix.file_descr list -> Timeval.t option -> Unix.file_descr list * Unix.file_descr list * Unix.file_descr list (** {1 File Times} *) (** Set file access and modification times. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimes.html} utimes(3)}. @param ~last_access date and time of last access @param ~last_modification date and time of last modification @param path Path to the file. *) val utimes : last_access:Timeval.t -> last_modification:Timeval.t -> string -> unit ocaml-posix-4.0.2/modules/time2/src/stubs/000077500000000000000000000000001515131525300203705ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/time2/src/stubs/dune000066400000000000000000000004621515131525300212500ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_time2_stubs) (public_name posix-time2.stubs) (libraries posix-types posix-time2.types ctypes.stubs)) (rule (targets posix_time2_generated_types.ml) (action (with-stdout-to %{targets} (run ../generator/gen_types_c)))) ocaml-posix-4.0.2/modules/time2/src/stubs/posix_time2_stubs.ml000066400000000000000000000042131515131525300244040ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F module Types = Posix_time2_types.Def (Posix_time2_generated_types) open Types let asctime = foreign "asctime" (ptr Tm.t @-> returning string) let clock_getres = foreign "clock_getres" (Posix_types.clockid_t @-> ptr Timespec.t @-> returning int) let clock_gettime = foreign "clock_gettime" (Posix_types.clockid_t @-> ptr Timespec.t @-> returning int) let clock_settime = foreign "clock_settime" (Posix_types.clockid_t @-> ptr Timespec.t @-> returning int) let ctime = foreign "ctime" (ptr Posix_types.time_t @-> returning string) let gmtime = foreign "gmtime" (ptr Posix_types.time_t @-> returning (ptr Tm.t)) let localtime = foreign "localtime" (ptr Posix_types.time_t @-> returning (ptr Tm.t)) let mktime = foreign "mktime" (ptr Tm.t @-> returning Posix_types.time_t) let nanosleep = foreign "nanosleep" (ptr Timespec.t @-> ptr void @-> returning int) let clock_nanosleep = foreign "clock_nanosleep" (Posix_types.clockid_t @-> int @-> ptr Timespec.t @-> ptr void @-> returning int) let getitimer = foreign "getitimer" (int @-> ptr Itimerval.t @-> returning int) let setitimer = foreign "setitimer" (int @-> ptr Itimerval.t @-> ptr Itimerval.t @-> returning int) let gettimeofday = foreign "gettimeofday" (ptr Timeval.t @-> ptr void @-> returning int) let fd_zero = foreign "ocaml_posix_time2_fd_zero" (ptr Posix_time2_types.fd_set @-> returning void) let fd_set = foreign "ocaml_posix_time2_fd_set" (int @-> ptr Posix_time2_types.fd_set @-> returning void) let fd_isset = foreign "ocaml_posix_time2_fd_isset" (int @-> ptr Posix_time2_types.fd_set @-> returning int) let fd_clr = foreign "ocaml_posix_time2_fd_clr" (int @-> ptr Posix_time2_types.fd_set @-> returning void) let select = foreign "select" (int @-> ptr Posix_time2_types.fd_set @-> ptr Posix_time2_types.fd_set @-> ptr Posix_time2_types.fd_set @-> ptr Timeval.t @-> returning int) let utimes = foreign "utimes" (string @-> ptr Timeval.t @-> returning int) end ocaml-posix-4.0.2/modules/time2/src/types/000077500000000000000000000000001515131525300203745ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/time2/src/types/dune000066400000000000000000000004751515131525300212600ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_time2_types) (public_name posix-time2.types) (libraries posix-time2.constants posix-base ctypes.stubs)) (rule (targets posix_time2_generated_constants.ml) (action (with-stdout-to %{targets} (run ../generator/gen_constants_c)))) ocaml-posix-4.0.2/modules/time2/src/types/posix_time2_types.ml000066400000000000000000000027071515131525300244220ustar00rootroot00000000000000open Ctypes module Constants = Posix_time2_constants.Def (Posix_time2_generated_constants) include Constants type fd_set = unit Ctypes.abstract let fd_set = Ctypes.abstract ~name:"fd_set" ~size:fd_set_size ~alignment:fd_set_alignment module Def (S : Cstubs.Types.TYPE) = struct module Tm = struct type t = unit let t = S.structure "tm" let tm_sec = S.field t "tm_sec" S.int let tm_min = S.field t "tm_min" S.int let tm_hour = S.field t "tm_hour" S.int let tm_mday = S.field t "tm_mday" S.int let tm_mon = S.field t "tm_mon" S.int let tm_year = S.field t "tm_year" S.int let tm_wday = S.field t "tm_wday" S.int let tm_yday = S.field t "tm_yday" S.int let tm_isdst = S.field t "tm_isdst" S.int let () = S.seal t end module Timespec = struct type t = unit let t = S.structure "timespec" let tv_sec = S.field t "tv_sec" (S.lift_typ Posix_types.time_t) let tv_nsec = S.field t "tv_nsec" (S.lift_typ long) let () = S.seal t end module Timeval = struct type t = unit let t = S.structure "timeval" let tv_sec = S.field t "tv_sec" (S.lift_typ Posix_types.time_t) let tv_usec = S.field t "tv_usec" (S.lift_typ Posix_types.suseconds_t) let () = S.seal t end module Itimerval = struct type t = unit let t = S.structure "itimerval" let it_interval = S.field t "it_interval" Timeval.t let it_value = S.field t "it_value" Timeval.t let () = S.seal t end end ocaml-posix-4.0.2/modules/time2/src/types/posix_time2_types.mli000066400000000000000000000026561515131525300245760ustar00rootroot00000000000000open Ctypes val itimer_real : int val itimer_virtual : int val itimer_prof : int type fd_set val fd_set : fd_set typ val fd_setsize : int val clock_monotonic : Posix_types.clockid_t val clock_realtime : Posix_types.clockid_t val clock_process_cputime_id : Posix_types.clockid_t val clock_thread_cputime_id : Posix_types.clockid_t val timer_abstime : int module Def (S : Cstubs.Types.TYPE) : sig module Tm : sig type t val t : t structure S.typ val tm_sec : (int, t structure) S.field val tm_min : (int, t structure) S.field val tm_hour : (int, t structure) S.field val tm_mday : (int, t structure) S.field val tm_mon : (int, t structure) S.field val tm_year : (int, t structure) S.field val tm_wday : (int, t structure) S.field val tm_yday : (int, t structure) S.field val tm_isdst : (int, t structure) S.field end module Timespec : sig type t val t : t structure S.typ val tv_sec : (Posix_types.time_t, t structure) S.field val tv_nsec : (Signed.long, t structure) S.field end module Timeval : sig type t val t : t structure S.typ val tv_sec : (Posix_types.time_t, t structure) S.field val tv_usec : (Posix_types.suseconds_t, t structure) S.field end module Itimerval : sig type t val t : t structure S.typ val it_interval : (Timeval.t structure, t structure) S.field val it_value : (Timeval.t structure, t structure) S.field end end ocaml-posix-4.0.2/modules/time2/test/000077500000000000000000000000001515131525300174205ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/time2/test/autogenerated_tests.ml000066400000000000000000000166521515131525300240350ustar00rootroot00000000000000(* Error handling tests for posix-time2 *) open Posix_time2 let sprint_timespec { Timespec.tv_sec; tv_nsec } = Printf.sprintf "tv_sec: %Li, tv_nsec: %Li" tv_sec tv_nsec let sprint_timeval { Timeval.tv_sec; tv_usec } = Printf.sprintf "tv_sec: %Li, tv_usec: %Li" tv_sec tv_usec (* Test clock_getres with valid clocks *) let test_clock_getres_valid () = Printf.printf "Testing clock_getres (success cases)...\n%!"; List.iter (fun (name, clock) -> try let res = clock_getres clock in Printf.printf " ✓ clock_getres %s: %s\n%!" name (sprint_timespec res) with Unix.Unix_error (err, fn, _) -> Printf.printf " ⚠ clock_getres %s not available: %s (%s)\n%!" name fn (Unix.error_message err)) [ ("Realtime", `Realtime); ("Monotonic", `Monotonic); ("Process_cputime", `Process_cputime); ("Thread_cputime", `Thread_cputime); ] (* Test clock_gettime with valid clocks *) let test_clock_gettime_valid () = Printf.printf "Testing clock_gettime (success cases)...\n%!"; List.iter (fun (name, clock) -> try let time = clock_gettime clock in Printf.printf " ✓ clock_gettime %s: %s\n%!" name (sprint_timespec time) with Unix.Unix_error (err, fn, _) -> Printf.printf " ⚠ clock_gettime %s not available: %s (%s)\n%!" name fn (Unix.error_message err)) [ ("Realtime", `Realtime); ("Monotonic", `Monotonic); ("Process_cputime", `Process_cputime); ("Thread_cputime", `Thread_cputime); ] (* Test nanosleep with invalid values should fail *) let test_nanosleep_invalid () = Printf.printf "Testing nanosleep (error cases)...\n%!"; (* Test with negative nsec - should fail with EINVAL *) let invalid_timespec = Timespec.create 0L (-1L) in (try nanosleep invalid_timespec; Printf.printf " ✗ nanosleep with negative nsec should have failed\n%!"; assert false with Unix.Unix_error (Unix.EINVAL, "nanosleep", _) -> Printf.printf " ✓ nanosleep correctly rejected negative nsec (EINVAL)\n%!"); (* Test with nsec >= 1000000000 Note: The Timespec.create function normalizes values, so we can't directly create an invalid timespec. This is actually good design - the type system prevents invalid values. *) Printf.printf " ℹ Timespec.create normalizes values, preventing nsec >= 1e9 at \ construction\n\ %!" (* Test nanosleep with valid value *) let test_nanosleep_valid () = Printf.printf "Testing nanosleep (success case)...\n%!"; let short_sleep = Timespec.create 0L 10000000L in (* 10ms *) nanosleep short_sleep; Printf.printf " ✓ nanosleep succeeded with valid timespec\n%!" (* Test gettimeofday *) let test_gettimeofday () = Printf.printf "Testing gettimeofday...\n%!"; let tv = gettimeofday () in Printf.printf " ✓ gettimeofday: %s\n%!" (sprint_timeval tv); assert (tv.tv_sec > 0L) (* Test gmtime with valid and edge case times *) let test_gmtime () = Printf.printf "Testing gmtime...\n%!"; (* Test with current time *) let tv = gettimeofday () in let tm = gmtime tv.tv_sec in Printf.printf " ✓ gmtime succeeded for current time: year=%d\n%!" (tm.Tm.tm_year + 1900); (* Test with epoch *) let tm_epoch = gmtime 0L in assert (tm_epoch.Tm.tm_year = 70); (* 1970 *) Printf.printf " ✓ gmtime succeeded for epoch: 1970-01-01\n%!"; (* Test with far future *) let tm_future = gmtime 2000000000L in (* May 18, 2033 *) assert (tm_future.Tm.tm_year >= 133); Printf.printf " ✓ gmtime succeeded for far future date\n%!" (* Test localtime *) let test_localtime () = Printf.printf "Testing localtime...\n%!"; let tv = gettimeofday () in let tm = localtime tv.tv_sec in Printf.printf " ✓ localtime succeeded: year=%d\n%!" (tm.Tm.tm_year + 1900) (* Test mktime with valid and invalid times *) let test_mktime () = Printf.printf "Testing mktime...\n%!"; (* Create a valid time structure *) match Tm.create 0 0 12 1 0 124 1 0 0 (* 2024-01-01 12:00:00, Monday, day 0 of year *) with | Some tm -> let time = mktime tm in Printf.printf " ✓ mktime succeeded: %Ld\n%!" time; assert (time > 0L) | None -> Printf.printf " ✗ Failed to create valid tm structure\n%!"; assert false (* Test setitimer and getitimer *) let test_itimer () = Printf.printf "Testing setitimer/getitimer...\n%!"; let timer = { Itimerval.it_interval = Timeval.create 0L 0L; it_value = Timeval.create 0L 100000L; } in let old = setitimer `Real timer in Printf.printf " ✓ setitimer succeeded\n%!"; ignore old; let current = getitimer `Real in Printf.printf " ✓ getitimer succeeded: value=%Ld.%06Ld\n%!" current.it_value.tv_sec current.it_value.tv_usec; (* Disable the timer *) let disable_timer = { Itimerval.it_interval = Timeval.create 0L 0L; it_value = Timeval.create 0L 0L; } in ignore (setitimer `Real disable_timer) (* Test select with timeout *) let test_select_timeout () = Printf.printf "Testing select with timeout...\n%!"; let timeout = Timeval.create 0L 10000L in (* 10ms timeout *) let r, w, e = select [] [] [] (Some timeout) in assert (r = []); assert (w = []); assert (e = []); Printf.printf " ✓ select timeout succeeded\n%!" (* Test select with invalid fd should fail *) let test_select_invalid_fd () = Printf.printf "Testing select with invalid fd (error case)...\n%!"; (* Create an invalid file descriptor *) let invalid_fd = Unix.openfile "/dev/null" [Unix.O_RDONLY] 0o644 in Unix.close invalid_fd; (* Now it's invalid *) try ignore (select [invalid_fd] [] [] None); Printf.printf " ✗ select with invalid fd should have failed\n%!"; (* Some systems may not error on this *) Printf.printf " ⚠ (or system doesn't error on closed fd)\n%!" with Unix.Unix_error (Unix.EBADF, "select", _) -> Printf.printf " ✓ select correctly rejected invalid fd (EBADF)\n%!" (* Test utimes on a valid file *) let test_utimes_valid () = Printf.printf "Testing utimes (success case)...\n%!"; let temp_file = Filename.temp_file "posix_time2_test" ".tmp" in let access_time = Timeval.create 1000000000L 0L in (* Jan 9, 2001 *) let modification_time = Timeval.create 1100000000L 0L in (* Nov 9, 2004 *) utimes ~last_access:access_time ~last_modification:modification_time temp_file; Sys.remove temp_file; Printf.printf " ✓ utimes succeeded on valid file\n%!" (* Test utimes on non-existent file should fail *) let test_utimes_invalid () = Printf.printf "Testing utimes (error case)...\n%!"; let nonexistent = "/tmp/this_file_should_not_exist_posix_time2_test_12345" in let new_time = Timeval.create 1000000000L 0L in try utimes ~last_access:new_time ~last_modification:new_time nonexistent; Printf.printf " ✗ utimes on non-existent file should have failed\n%!"; assert false with Unix.Unix_error (Unix.ENOENT, "utimes", _) -> Printf.printf " ✓ utimes correctly rejected non-existent file (ENOENT)\n%!" let () = Printf.printf "\n=== POSIX Time2 Error Handling Tests ===\n\n%!"; test_clock_getres_valid (); test_clock_gettime_valid (); test_nanosleep_valid (); test_nanosleep_invalid (); test_gettimeofday (); test_gmtime (); test_localtime (); test_mktime (); test_itimer (); test_select_timeout (); test_select_invalid_fd (); test_utimes_valid (); test_utimes_invalid (); Printf.printf "\n✓ All time2 error tests passed!\n%!" ocaml-posix-4.0.2/modules/time2/test/dune000066400000000000000000000005111515131525300202730ustar00rootroot00000000000000(executable (name test) (libraries posix-time2 threads compiler-libs.common)) (rule (alias citest) (package posix-time2) (action (run %{exe:test.exe}))) (executable (name autogenerated_tests) (libraries posix-time2 unix)) (rule (alias citest) (package posix-time2) (action (run %{exe:autogenerated_tests.exe}))) ocaml-posix-4.0.2/modules/time2/test/test.ml000066400000000000000000000040511515131525300207310ustar00rootroot00000000000000open Posix_time2 let sprint_timespec { Timespec.tv_sec; tv_nsec } = Printf.sprintf "tv_sec: %Li, tv_nsec: %Li" tv_sec tv_nsec let sprint_timeval { Timeval.tv_sec; tv_usec } = Printf.sprintf "tv_sec: %Li, tv_usec: %Li" tv_sec tv_usec let sprint_itimerval { Itimerval.it_interval; it_value } = Printf.sprintf "it_interval: { %s } , it_value = { %s }" (sprint_timeval it_interval) (sprint_timeval it_value) let timer1 = { Itimerval.it_interval = Timeval.create 1982L 0L; it_value = Timeval.create 0L 0L; } let timer2 = { Itimerval.it_interval = Timeval.create 0L 0L; it_value = Timeval.create 2020L 0L; } let () = let timer = setitimer `Real timer1 in Printf.printf "setitimer: %s\n%!" (sprint_itimerval timer); let timer = getitimer `Real in Printf.printf "getitimer: %s\n%!" (sprint_itimerval timer); let timer = setitimer `Real timer2 in Printf.printf "setitimer: %s\n%!" (sprint_itimerval timer); let timer = setitimer `Real timer1 in Printf.printf "setitimer: %s\n%!" (sprint_itimerval timer); Printf.printf "gettimeofday: %s\n%!" (sprint_timeval (gettimeofday ())); Printf.printf "Sleeping 1s..\n%!"; nanosleep (Timespec.create 1L 0L); let r, w = Unix.pipe () in let th = Thread.create (fun () -> match select [r] [] [] None with | [x], [], [] when x = r -> Printf.printf "Done waiting on read socket!\n%!" | _ -> assert false) () in ignore (Unix.write w (Bytes.of_string " ") 0 1); Thread.join th; let timespec = clock_getres `Monotonic in Printf.printf "Monotonic time clock resolution: %s\n%!" (sprint_timespec timespec); let timespec = clock_gettime `Monotonic in Printf.printf "Monotonic time time: %s\n%!" (sprint_timespec timespec); if Config.system <> "gnu" then ( let timespec = clock_getres `Process_cputime in Printf.printf "Process clock resolution: %s\n%!" (sprint_timespec timespec); let timespec = clock_gettime `Process_cputime in Printf.printf "Process time: %s\n%!" (sprint_timespec timespec)) ocaml-posix-4.0.2/modules/types/000077500000000000000000000000001515131525300165655ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/types/CHANGES000066400000000000000000000005071515131525300175620ustar00rootroot000000000000002.2.0 (2025-01-30) ===== * Fix copy code in `getaddrinfo`. 2.1.0 (2025-01-16) ===== * Added `posix-math2` * Invoke `wine64` only when available. * Added `sockaddr_len` in `ocaml-posix`. * Add support for string and optional `port. * Add support for `hints`. 2.0.2 (2023-02-08) ===== **posix-time2** * Added `clock_nanosleep` ocaml-posix-4.0.2/modules/types/src/000077500000000000000000000000001515131525300173545ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/types/src/constants/000077500000000000000000000000001515131525300213705ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/types/src/constants/dune000066400000000000000000000001471515131525300222500ustar00rootroot00000000000000(library (name posix_types_constants) (public_name posix-types.constants) (libraries ctypes.stubs)) ocaml-posix-4.0.2/modules/types/src/constants/posix_types_constants.ml000066400000000000000000000065661515131525300264210ustar00rootroot00000000000000let number_types = [ "blkcnt_t"; "blksize_t"; "clock_t"; "clockid_t"; "dev_t"; "fsblkcnt_t"; "fsfilcnt_t"; "gid_t"; "id_t"; "ino_t"; "key_t"; "mode_t"; "nlink_t"; "off_t"; "pid_t"; "size_t"; "ssize_t"; "suseconds_t"; "time_t"; "uid_t"; ] let abstract_types = [ "useconds_t"; "pthread_attr_t"; "pthread_cond_t"; "pthread_condattr_t"; "pthread_key_t"; "pthread_mutex_t"; "pthread_mutexattr_t"; "pthread_once_t"; "pthread_rwlock_t"; "pthread_rwlockattr_t"; "pthread_t"; ] module Def (S : Cstubs.Types.TYPE) = struct let blkcnt_t_size = S.constant "BLKCNT_T_SIZE" S.int let blksize_t_size = S.constant "BLKSIZE_T_SIZE" S.int let clock_t_size = S.constant "CLOCK_T_SIZE" S.int let clockid_t_size = S.constant "CLOCKID_T_SIZE" S.int let is_clock_t_float = S.constant "IS_CLOCK_T_FLOAT" S.bool let dev_t_size = S.constant "DEV_T_SIZE" S.int let fsblkcnt_t_size = S.constant "FSBLKCNT_T_SIZE" S.int let fsfilcnt_t_size = S.constant "FSFILCNT_T_SIZE" S.int let gid_t_size = S.constant "GID_T_SIZE" S.int let id_t_size = S.constant "ID_T_SIZE" S.int let ino_t_size = S.constant "INO_T_SIZE" S.int let key_t_size = S.constant "KEY_T_SIZE" S.int let is_key_t_float = S.constant "IS_KEY_T_FLOAT" S.bool let mode_t_size = S.constant "MODE_T_SIZE" S.int let nlink_t_size = S.constant "NLINK_T_SIZE" S.int let off_t_size = S.constant "OFF_T_SIZE" S.int let pid_t_size = S.constant "PID_T_SIZE" S.int let size_t_size = S.constant "SIZE_T_SIZE" S.int let ssize_t_size = S.constant "SSIZE_T_SIZE" S.int let suseconds_t_size = S.constant "SUSECONDS_T_SIZE" S.int let time_t_size = S.constant "TIME_T_SIZE" S.int let is_time_t_float = S.constant "IS_TIME_T_FLOAT" S.bool let uid_t_size = S.constant "UID_T_SIZE" S.int let useconds_t_size = S.constant "USECONDS_T_SIZE" S.int let pthread_attr_t_alignment = S.constant "PTHREAD_ATTR_T_ALIGNMENT" S.int let pthread_cond_t_alignment = S.constant "PTHREAD_COND_T_ALIGNMENT" S.int let pthread_condattr_t_alignment = S.constant "PTHREAD_CONDATTR_T_ALIGNMENT" S.int let pthread_key_t_alignment = S.constant "PTHREAD_KEY_T_ALIGNMENT" S.int let pthread_mutex_t_alignment = S.constant "PTHREAD_MUTEX_T_ALIGNMENT" S.int let pthread_mutexattr_t_alignment = S.constant "PTHREAD_MUTEXATTR_T_ALIGNMENT" S.int let pthread_once_t_alignment = S.constant "PTHREAD_ONCE_T_ALIGNMENT" S.int let pthread_rwlock_t_alignment = S.constant "PTHREAD_RWLOCK_T_ALIGNMENT" S.int let pthread_rwlockattr_t_alignment = S.constant "PTHREAD_RWLOCKATTR_T_ALIGNMENT" S.int let pthread_t_alignment = S.constant "PTHREAD_T_ALIGNMENT" S.int let pthread_attr_t_size = S.constant "PTHREAD_ATTR_T_SIZE" S.int let pthread_cond_t_size = S.constant "PTHREAD_COND_T_SIZE" S.int let pthread_condattr_t_size = S.constant "PTHREAD_CONDATTR_T_SIZE" S.int let pthread_key_t_size = S.constant "PTHREAD_KEY_T_SIZE" S.int let pthread_mutex_t_size = S.constant "PTHREAD_MUTEX_T_SIZE" S.int let pthread_mutexattr_t_size = S.constant "PTHREAD_MUTEXATTR_T_SIZE" S.int let pthread_once_t_size = S.constant "PTHREAD_ONCE_T_SIZE" S.int let pthread_rwlock_t_size = S.constant "PTHREAD_RWLOCK_T_SIZE" S.int let pthread_rwlockattr_t_size = S.constant "PTHREAD_RWLOCKATTR_T_SIZE" S.int let pthread_t_size = S.constant "PTHREAD_T_SIZE" S.int end ocaml-posix-4.0.2/modules/types/src/dune000066400000000000000000000006001515131525300202260ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_types) (public_name posix-types) (synopsis "posix-types provides access to POSIX's types defined in ") (libraries ctypes posix-types.constants posix-base)) (rule (targets posix_types_generated_constants.ml) (action (with-stdout-to %{targets} (run ./generator/gen_constants_c)))) ocaml-posix-4.0.2/modules/types/src/generator/000077500000000000000000000000001515131525300213425ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/types/src/generator/dune000066400000000000000000000006621515131525300222240ustar00rootroot00000000000000(executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-types.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/types/src/generator/gen_constants_c.ml000066400000000000000000000020201515131525300250350ustar00rootroot00000000000000module Constants = Posix_base.Generators.Types (struct module Types = Posix_types_constants.Def let defines = String.concat "\n" (List.map (fun t -> let name = String.uppercase_ascii t in Printf.sprintf "\n\ #define %s_SIZE sizeof(%s)\n\ #define IS_%s_FLOAT ((float)((%s)1.23f) == 1.23f)" name t name t) Posix_types_constants.number_types @ List.map (fun t -> let name = String.uppercase_ascii t in Printf.sprintf "\n\ #define %s_SIZE sizeof(%s)\n\ #define %s_ALIGNMENT offsetof(struct { char c; %s x; }, x)" name t name t) Posix_types_constants.abstract_types) let c_headers = Printf.sprintf "\n\ #include \n\ #include \n\ #include \n\n\ #define POSIX_TYPES_LFS64 (sizeof(off_t) > 4)\n\n\ %s" defines end) let () = Constants.gen () ocaml-posix-4.0.2/modules/types/src/posix_types.ml000066400000000000000000000144071515131525300223020ustar00rootroot00000000000000open Posix_base.Types module Constants = Posix_types_constants.Def (Posix_types_generated_constants) open Constants let clock : (module Arithmetic) = mkArithmetic ~name:"clock_t" ~size:clock_t_size ~is_float:is_clock_t_float module Clock = (val clock : Arithmetic) type clock_t = Clock.t let clock_t = Clock.t let time : (module Arithmetic) = mkArithmetic ~name:"time_t" ~size:time_t_size ~is_float:is_time_t_float module Time = (val time : Arithmetic) type time_t = Time.t let time_t = Time.t let key : (module Arithmetic) = mkArithmetic ~name:"key_t" ~size:key_t_size ~is_float:is_key_t_float module Key = (val key : Arithmetic) type key_t = Key.t let key_t = Key.t let blkcnt : (module Signed) = mkSigned ~name:"blkcnt_t" ~size:blkcnt_t_size module Blkcnt = (val blkcnt : Signed) type blkcnt_t = Blkcnt.t let blkcnt_t = Blkcnt.t let blksize : (module Signed) = mkSigned ~name:"blksize_t" ~size:blksize_t_size module Blksize = (val blksize : Signed) type blksize_t = Blksize.t let blksize_t = Blksize.t let clockid : (module Unsigned) = mkUnsigned ~name:"clockid_t" ~size:clockid_t_size module Clockid = (val clockid : Unsigned) type clockid_t = Clockid.t let clockid_t = Clockid.t let dev : (module Unsigned) = mkUnsigned ~name:"dev_t" ~size:dev_t_size module Dev = (val dev : Unsigned) type dev_t = Dev.t let dev_t = Dev.t let fsblkcnt : (module Unsigned) = mkUnsigned ~name:"fsblkcnt_t" ~size:fsblkcnt_t_size module Fsblkcnt = (val fsblkcnt : Unsigned) type fsblkcnt_t = Fsblkcnt.t let fsblkcnt_t = Fsblkcnt.t let fsfilcnt : (module Unsigned) = mkUnsigned ~name:"fsfilcnt_t" ~size:fsfilcnt_t_size module Fsfilcnt = (val fsfilcnt : Unsigned) type fsfilcnt_t = Fsfilcnt.t let fsfilcnt_t = Fsfilcnt.t let gid : (module Unsigned) = mkUnsigned ~name:"gid_t" ~size:gid_t_size module Gid = (val gid : Unsigned) type gid_t = Gid.t let gid_t = Gid.t let id : (module Unsigned) = mkUnsigned ~name:"id_t" ~size:id_t_size module Id = (val id : Unsigned) type id_t = Id.t let id_t = Id.t let ino : (module Unsigned) = mkUnsigned ~name:"ino_t" ~size:ino_t_size module Ino = (val ino : Unsigned) type ino_t = Ino.t let ino_t = Ino.t let mode : (module Unsigned) = mkUnsigned ~name:"mode_t" ~size:mode_t_size module Mode = (val mode : Unsigned) type mode_t = Mode.t let mode_t = Mode.t let nlink : (module Unsigned) = mkUnsigned ~name:"nlink_t" ~size:nlink_t_size module Nlink = (val nlink : Unsigned) type nlink_t = Nlink.t let nlink_t = Nlink.t let off : (module Signed) = mkSigned ~name:"off_t" ~size:off_t_size module Off = (val off : Signed) type off_t = Off.t let off_t = Off.t let pid : (module Signed) = mkSigned ~name:"pid_t" ~size:pid_t_size module Pid = (val pid : Signed) type pid_t = Pid.t let pid_t = Pid.t let size : (module Unsigned) = mkUnsigned ~name:"size_t" ~size:size_t_size module Size = (val size : Unsigned) type size_t = Size.t let size_t = Size.t let ssize : (module Signed) = mkSigned ~name:"ssize_t" ~size:ssize_t_size module Ssize = (val ssize : Signed) type ssize_t = Ssize.t let ssize_t = Ssize.t let suseconds : (module Signed) = mkSigned ~name:"suseconds_t" ~size:suseconds_t_size module Suseconds = (val suseconds : Signed) type suseconds_t = Suseconds.t let suseconds_t = Suseconds.t let uid : (module Unsigned) = mkUnsigned ~name:"uid_t" ~size:uid_t_size module Uid = (val uid : Unsigned) type uid_t = Uid.t let uid_t = Uid.t let useconds : (module Unsigned) = mkUnsigned ~name:"useconds_t" ~size:useconds_t_size module Useconds = (val useconds : Unsigned) type useconds_t = Useconds.t let useconds_t = Useconds.t module type Abstract = sig type t val t : t Ctypes.typ end let mkAbstract : name:string -> size:int -> alignment:int -> (module Abstract) = fun ~name ~size ~alignment:a : (module Abstract) -> (module struct open Ctypes type t = unit Ctypes.abstract let t = abstract ~name ~size ~alignment:a end) module Pthread = struct module Attr = (val mkAbstract ~name:"pthread_attr_t" ~size:pthread_attr_t_size ~alignment:pthread_attr_t_alignment) module Cond = (val mkAbstract ~name:"pthread_cond_t" ~size:pthread_cond_t_size ~alignment:pthread_cond_t_alignment) module Condattr = (val mkAbstract ~name:"pthread_condattr_t" ~size:pthread_condattr_t_size ~alignment:pthread_condattr_t_alignment) module Key = (val mkAbstract ~name:"pthread_key_t" ~size:pthread_key_t_size ~alignment:pthread_key_t_alignment) module Mutex = (val mkAbstract ~name:"pthread_mutex_t" ~size:pthread_mutex_t_size ~alignment:pthread_mutex_t_alignment) module Mutexattr = (val mkAbstract ~name:"pthread_mutexattr_t" ~size:pthread_mutexattr_t_size ~alignment:pthread_mutexattr_t_alignment) module Once = (val mkAbstract ~name:"pthread_once_t" ~size:pthread_once_t_size ~alignment:pthread_once_t_alignment) module Rwlock = (val mkAbstract ~name:"pthread_rwlock_t" ~size:pthread_rwlock_t_size ~alignment:pthread_rwlock_t_alignment) module Rwlockattr = (val mkAbstract ~name:"pthread_rwlockattr_t" ~size:pthread_rwlockattr_t_size ~alignment:pthread_rwlockattr_t_alignment) module T = (val mkAbstract ~name:"pthread_t" ~size:pthread_t_size ~alignment:pthread_t_alignment) type attr_t = Attr.t type cond_t = Cond.t type condattr_t = Condattr.t type key_t = Key.t type mutex_t = Mutex.t type mutexattr_t = Mutexattr.t type once_t = Once.t type rwlock_t = Rwlock.t type rwlockattr_t = Rwlockattr.t type t = T.t end type pthread_attr_t = Pthread.Attr.t type pthread_cond_t = Pthread.Cond.t type pthread_condattr_t = Pthread.Condattr.t type pthread_key_t = Pthread.Key.t type pthread_mutex_t = Pthread.Mutex.t type pthread_mutexattr_t = Pthread.Mutexattr.t type pthread_once_t = Pthread.Once.t type pthread_rwlock_t = Pthread.Rwlock.t type pthread_rwlockattr_t = Pthread.Rwlockattr.t type pthread_t = Pthread.T.t let pthread_attr_t = Pthread.Attr.t let pthread_cond_t = Pthread.Cond.t let pthread_condattr_t = Pthread.Condattr.t let pthread_key_t = Pthread.Key.t let pthread_mutex_t = Pthread.Mutex.t let pthread_mutexattr_t = Pthread.Mutexattr.t let pthread_once_t = Pthread.Once.t let pthread_rwlock_t = Pthread.Rwlock.t let pthread_rwlockattr_t = Pthread.Rwlockattr.t let pthread_t = Pthread.T.t ocaml-posix-4.0.2/modules/types/src/posix_types.mli000066400000000000000000000072321515131525300224510ustar00rootroot00000000000000open Ctypes open Posix_base.Types (** POSIX types from . This module is used to build further POSIX bindings. See {!Posix_time2_types} for an example. *) (** {2 POSIX arithmetic types} *) (** {3 Base modules} *) module Blkcnt : Signed.S module Blksize : Signed.S module Clock : Arithmetic module Clockid : Unsigned.S module Dev : Unsigned.S module Fsblkcnt : Unsigned.S module Fsfilcnt : Unsigned.S module Gid : Unsigned.S module Id : Unsigned.S module Ino : Unsigned.S module Key : Arithmetic module Mode : Unsigned.S module Nlink : Unsigned.S module Off : Signed.S module Pid : Signed.S module Size : Unsigned.S module Ssize : Signed.S module Time : Arithmetic module Uid : Unsigned.S module Useconds : Unsigned.S module Suseconds : Signed.S (** {3 Types} *) type blkcnt_t = Blkcnt.t type blksize_t = Blksize.t type clock_t = Clock.t type clockid_t = Clockid.t type dev_t = Dev.t type fsblkcnt_t = Fsblkcnt.t type fsfilcnt_t = Fsfilcnt.t type gid_t = Gid.t type id_t = Id.t type ino_t = Ino.t type key_t = Key.t type mode_t = Mode.t type nlink_t = Nlink.t type off_t = Off.t type pid_t = Pid.t type size_t = Size.t type ssize_t = Ssize.t type time_t = Time.t type uid_t = Uid.t type useconds_t = Useconds.t type suseconds_t = Suseconds.t (** {3 Values} *) val blkcnt_t : blkcnt_t typ val blksize_t : blksize_t typ val clock_t : clock_t typ val clockid_t : clockid_t typ val dev_t : dev_t typ val fsblkcnt_t : fsblkcnt_t typ val fsfilcnt_t : fsfilcnt_t typ val gid_t : gid_t typ val id_t : id_t typ val ino_t : ino_t typ val key_t : key_t typ val mode_t : mode_t typ val nlink_t : nlink_t typ val off_t : off_t typ val pid_t : pid_t typ val size_t : size_t typ val ssize_t : ssize_t typ val time_t : time_t typ val uid_t : uid_t typ val useconds_t : useconds_t typ val suseconds_t : suseconds_t typ (** {2 Pthread API} *) (** {3 Base module} *) module Pthread : sig module Attr : sig type t val t : t Ctypes.typ end module Cond : sig type t val t : t Ctypes.typ end module Condattr : sig type t val t : t Ctypes.typ end module Key : sig type t val t : t Ctypes.typ end module Mutex : sig type t val t : t Ctypes.typ end module Mutexattr : sig type t val t : t Ctypes.typ end module Once : sig type t val t : t Ctypes.typ end module Rwlock : sig type t val t : t Ctypes.typ end module Rwlockattr : sig type t val t : t Ctypes.typ end module T : sig type t val t : t Ctypes.typ end type attr_t = Attr.t type cond_t = Cond.t type condattr_t = Condattr.t type key_t = Key.t type mutex_t = Mutex.t type mutexattr_t = Mutexattr.t type once_t = Once.t type rwlock_t = Rwlock.t type rwlockattr_t = Rwlockattr.t type t = T.t end (** {3 Types} *) type pthread_attr_t = Pthread.Attr.t type pthread_cond_t = Pthread.Cond.t type pthread_condattr_t = Pthread.Condattr.t type pthread_key_t = Pthread.Key.t type pthread_mutex_t = Pthread.Mutex.t type pthread_mutexattr_t = Pthread.Mutexattr.t type pthread_once_t = Pthread.Once.t type pthread_rwlock_t = Pthread.Rwlock.t type pthread_rwlockattr_t = Pthread.Rwlockattr.t type pthread_t = Pthread.T.t (** {3 Values} *) val pthread_attr_t : pthread_attr_t Ctypes.typ val pthread_cond_t : pthread_cond_t Ctypes.typ val pthread_condattr_t : pthread_condattr_t Ctypes.typ val pthread_key_t : pthread_key_t Ctypes.typ val pthread_mutex_t : pthread_mutex_t Ctypes.typ val pthread_mutexattr_t : pthread_mutexattr_t Ctypes.typ val pthread_once_t : pthread_once_t Ctypes.typ val pthread_rwlock_t : pthread_rwlock_t Ctypes.typ val pthread_rwlockattr_t : pthread_rwlockattr_t Ctypes.typ val pthread_t : pthread_t Ctypes.typ ocaml-posix-4.0.2/modules/uname/000077500000000000000000000000001515131525300165265ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/uname/CHANGES000066400000000000000000000005071515131525300175230ustar00rootroot000000000000002.2.0 (2025-01-30) ===== * Fix copy code in `getaddrinfo`. 2.1.0 (2025-01-16) ===== * Added `posix-math2` * Invoke `wine64` only when available. * Added `sockaddr_len` in `ocaml-posix`. * Add support for string and optional `port. * Add support for `hints`. 2.0.2 (2023-02-08) ===== **posix-time2** * Added `clock_nanosleep` ocaml-posix-4.0.2/modules/uname/src/000077500000000000000000000000001515131525300173155ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/uname/src/constants/000077500000000000000000000000001515131525300213315ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/uname/src/constants/dune000066400000000000000000000001471515131525300222110ustar00rootroot00000000000000(library (name posix_uname_constants) (public_name posix-uname.constants) (libraries ctypes.stubs)) ocaml-posix-4.0.2/modules/uname/src/constants/posix_uname_constants.ml000066400000000000000000000004611515131525300263070ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct let sysname_len = S.constant "SYSNAME_LEN" S.int let nodename_len = S.constant "NODENAME_LEN" S.int let release_len = S.constant "RELEASE_LEN" S.int let version_len = S.constant "VERSION_LEN" S.int let machine_len = S.constant "MACHINE_LEN" S.int end ocaml-posix-4.0.2/modules/uname/src/dune000066400000000000000000000010511515131525300201700ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_uname) (public_name posix-uname) (synopsis "posix-uname provides access to the features exposed in sys/utsname.h") (foreign_stubs (language c) (names posix_uname_generated_stubs)) (libraries unix ctypes posix-errno posix-uname.types posix-uname.stubs)) (rule (targets posix_uname_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_uname_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) ocaml-posix-4.0.2/modules/uname/src/generator/000077500000000000000000000000001515131525300213035ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/uname/src/generator/dune000066400000000000000000000016501515131525300221630ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-uname.stubs posix-base)) (executable (name gen_types_c) (modules gen_types_c) (libraries posix-uname.types posix-base)) (rule (targets gen_types.c) (action (run ./gen_types_c.exe %{targets}))) (rule (targets gen_types_c) (deps (:c_code ./gen_types.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-uname.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/uname/src/generator/gen_constants_c.ml000066400000000000000000000007371515131525300250130ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_uname_constants.Def let c_headers = {| #include #define SYSNAME_LEN (sizeof(((struct utsname*)0)->sysname)) #define NODENAME_LEN (sizeof(((struct utsname*)0)->nodename)) #define RELEASE_LEN (sizeof(((struct utsname*)0)->release)) #define VERSION_LEN (sizeof(((struct utsname*)0)->version)) #define MACHINE_LEN (sizeof(((struct utsname*)0)->machine)) |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/uname/src/generator/gen_stubs.ml000066400000000000000000000003761515131525300236340ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_uname_stubs.Def let c_headers = {| #include #include |} let concurrency = Cstubs.unlocked let prefix = "posix_uname" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/uname/src/generator/gen_types_c.ml000066400000000000000000000002501515131525300241310ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_uname_types.Def let c_headers = {| #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/uname/src/posix_uname.ml000066400000000000000000000013761515131525300222050ustar00rootroot00000000000000open Ctypes include Posix_uname_stubs.Def (Posix_uname_generated_stubs) type utsname = { sysname : string; nodename : string; release : string; version : string; machine : string; } let from_utsname p = let get f = getf p f in let read f = let p = CArray.start (get f) in string_from_ptr ~length:(strlen p) p in { sysname = read Types.Utsname.sysname; nodename = read Types.Utsname.nodename; release = read Types.Utsname.release; version = read Types.Utsname.version; machine = read Types.Utsname.machine; } let uname () = Posix_errno.raise_on_none ~call:"uname" (fun () -> let p = make Types.Utsname.t in match uname (addr p) with | x when x < 0 -> None | _ -> Some (from_utsname p)) ocaml-posix-4.0.2/modules/uname/src/posix_uname.mli000066400000000000000000000023721515131525300223530ustar00rootroot00000000000000(** POSIX system identification bindings. This module provides OCaml bindings to the POSIX uname function defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_utsname.h.html} sys/utsname.h}. It allows retrieval of system identification information such as the operating system name, version, and hardware architecture. *) (** System identification information returned by {!uname}. This record corresponds to the POSIX [struct utsname]. *) type utsname = { sysname : string; (** Operating system name (e.g., "Linux", "Darwin") *) nodename : string; (** Network node hostname *) release : string; (** Operating system release (e.g., "5.4.0") *) version : string; (** Operating system version *) machine : string; (** Hardware architecture (e.g., "x86_64", "arm64") *) } (** Return system identification information. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/uname.html} uname(2)}. @return A record containing system identification information. @raise Unix.Unix_error on failure. Example: {[ let info = uname () in Printf.printf "Running on %s %s (%s)\n" info.sysname info.release info.machine ]} *) val uname : unit -> utsname ocaml-posix-4.0.2/modules/uname/src/stubs/000077500000000000000000000000001515131525300204555ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/uname/src/stubs/dune000066400000000000000000000004461515131525300213370ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_uname_stubs) (public_name posix-uname.stubs) (libraries posix-uname.types ctypes.stubs)) (rule (targets posix_uname_generated_types.ml) (action (with-stdout-to %{targets} (run ../generator/gen_types_c)))) ocaml-posix-4.0.2/modules/uname/src/stubs/posix_uname_stubs.ml000066400000000000000000000004231515131525300245550ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F module Types = Posix_uname_types.Def (Posix_uname_generated_types) open Types let uname = foreign "uname" (ptr Utsname.t @-> returning int) let strlen = foreign "strlen" (ptr char @-> returning int) end ocaml-posix-4.0.2/modules/uname/src/types/000077500000000000000000000000001515131525300204615ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/uname/src/types/dune000066400000000000000000000004751515131525300213450ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_uname_types) (public_name posix-uname.types) (libraries posix-uname.constants posix-base ctypes.stubs)) (rule (targets posix_uname_generated_constants.ml) (action (with-stdout-to %{targets} (run ../generator/gen_constants_c)))) ocaml-posix-4.0.2/modules/uname/src/types/posix_uname_types.ml000066400000000000000000000011171515131525300245660ustar00rootroot00000000000000module Constants = Posix_uname_constants.Def (Posix_uname_generated_constants) include Constants module Def (S : Cstubs.Types.TYPE) = struct module Utsname = struct type t = unit let t = S.structure "utsname" let sysname = S.field t "sysname" (S.array sysname_len S.char) let nodename = S.field t "nodename" (S.array nodename_len S.char) let release = S.field t "release" (S.array release_len S.char) let version = S.field t "version" (S.array version_len S.char) let machine = S.field t "machine" (S.array machine_len S.char) let () = S.seal t end end ocaml-posix-4.0.2/modules/uname/src/types/posix_uname_types.mli000066400000000000000000000007361515131525300247450ustar00rootroot00000000000000open Ctypes (** Ctypes types for *) module Def (S : Cstubs.Types.TYPE) : sig (** Ctypes type for [struct utsname] *) module Utsname : sig type t val t : t structure S.typ val sysname : (char carray, t structure) S.field val nodename : (char carray, t structure) S.field val release : (char carray, t structure) S.field val version : (char carray, t structure) S.field val machine : (char carray, t structure) S.field end end ocaml-posix-4.0.2/modules/uname/test/000077500000000000000000000000001515131525300175055ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/uname/test/autogenerated_tests.ml000066400000000000000000000057671515131525300241270ustar00rootroot00000000000000(* Error handling tests for posix-uname *) open Posix_uname (* Test uname basic functionality *) let test_uname_success () = Printf.printf "Testing uname (success case)...\n%!"; let { sysname; nodename; release; version; machine } = uname () in Printf.printf " System information:\n%!"; Printf.printf " sysname: %s\n%!" sysname; Printf.printf " nodename: %s\n%!" nodename; Printf.printf " release: %s\n%!" release; Printf.printf " version: %s\n%!" version; Printf.printf " machine: %s\n%!" machine; (* Validate that fields are non-empty *) assert (String.length sysname > 0); assert (String.length machine > 0); Printf.printf " ✓ uname succeeded with valid data\n%!" (* Test that repeated calls return consistent results *) let test_uname_consistency () = Printf.printf "Testing uname consistency...\n%!"; let info1 = uname () in let info2 = uname () in (* System name and machine should be consistent *) assert (info1.sysname = info2.sysname); assert (info1.machine = info2.machine); Printf.printf " ✓ uname returns consistent results\n%!" (* Test expected values on common systems *) let test_uname_expected_values () = Printf.printf "Testing uname expected values...\n%!"; let { sysname; machine; _ } = uname () in (* Check for common Unix-like system names *) let known_systems = ["Linux"; "Darwin"; "FreeBSD"; "OpenBSD"; "NetBSD"; "SunOS"] in let is_known_system = List.mem sysname known_systems in if is_known_system then Printf.printf " ✓ Recognized system: %s\n%!" sysname else Printf.printf " ⚠ Unknown system name (not an error): %s\n%!" sysname; (* Check that machine architecture looks reasonable *) let known_arches = [ "x86_64"; "amd64"; "i386"; "i686"; "arm64"; "aarch64"; "armv7l"; "ppc64le"; "s390x"; "riscv64"; ] in let is_known_arch = List.mem machine known_arches in if is_known_arch then Printf.printf " ✓ Recognized architecture: %s\n%!" machine else Printf.printf " ⚠ Unknown architecture (not an error): %s\n%!" machine (* Note: uname() rarely fails in practice. According to POSIX, it can only fail with: - EFAULT: Invalid buffer pointer (but we control this in the binding) Since we allocate the buffer correctly in our binding, there's no practical way to trigger an error without corrupting memory, which we cannot safely test. The error handling in the binding ensures that if the C function somehow returns an error, it will be properly raised as a Unix_error. *) let () = Printf.printf "\n=== POSIX Uname Error Handling Tests ===\n\n%!"; Printf.printf "Note: uname() has very limited error cases in POSIX (only EFAULT)\n%!"; Printf.printf "and our binding handles buffer allocation safely, so we focus on\n%!"; Printf.printf "testing success cases and data validity.\n\n%!"; test_uname_success (); test_uname_consistency (); test_uname_expected_values (); Printf.printf "\n✓ All uname tests passed!\n%!" ocaml-posix-4.0.2/modules/uname/test/dune000066400000000000000000000004541515131525300203660ustar00rootroot00000000000000(executable (name test) (libraries posix-uname)) (rule (alias citest) (package posix-uname) (action (run %{exe:test.exe}))) (executable (name autogenerated_tests) (libraries posix-uname unix)) (rule (alias citest) (package posix-uname) (action (run %{exe:autogenerated_tests.exe}))) ocaml-posix-4.0.2/modules/uname/test/test.ml000066400000000000000000000003501515131525300210140ustar00rootroot00000000000000open Posix_uname let () = let { sysname; nodename; release; version; machine } = uname () in Printf.printf "sysname: %s\nnodename: %s\nrelease: %s\nversion: %s\nmachine: %s\n%!" sysname nodename release version machine ocaml-posix-4.0.2/modules/unistd/000077500000000000000000000000001515131525300167275ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/unistd/src/000077500000000000000000000000001515131525300175165ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/unistd/src/constants/000077500000000000000000000000001515131525300215325ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/unistd/src/constants/dune000066400000000000000000000002531515131525300224100ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_unistd_constants) (public_name posix-unistd.constants) (libraries posix-types ctypes.stubs)) ocaml-posix-4.0.2/modules/unistd/src/constants/posix_unistd_constants.ml000066400000000000000000000132651515131525300267170ustar00rootroot00000000000000module Def (S : Cstubs.Types.TYPE) = struct let host_name_max = S.constant "HOST_NAME_MAX" S.int let login_name_max = S.constant "LOGIN_NAME_MAX" S.int (* sysconf names - commonly available ones *) let sc_arg_max = S.constant "_SC_ARG_MAX" S.int let sc_child_max = S.constant "_SC_CHILD_MAX" S.int let sc_clk_tck = S.constant "_SC_CLK_TCK" S.int let sc_open_max = S.constant "_SC_OPEN_MAX" S.int let sc_pagesize = S.constant "_SC_PAGESIZE" S.int let sc_page_size = S.constant "_SC_PAGE_SIZE" S.int (* alias for PAGESIZE *) let sc_nprocessors_onln = S.constant "_SC_NPROCESSORS_ONLN" S.int let sc_nprocessors_conf = S.constant "_SC_NPROCESSORS_CONF" S.int let sc_phys_pages = S.constant "_SC_PHYS_PAGES" S.int let sc_stream_max = S.constant "_SC_STREAM_MAX" S.int let sc_tzname_max = S.constant "_SC_TZNAME_MAX" S.int let sc_version = S.constant "_SC_VERSION" S.int let sc_atexit_max = S.constant "_SC_ATEXIT_MAX" S.int let sc_login_name_max = S.constant "_SC_LOGIN_NAME_MAX" S.int let sc_tty_name_max = S.constant "_SC_TTY_NAME_MAX" S.int let sc_host_name_max = S.constant "_SC_HOST_NAME_MAX" S.int let sc_line_max = S.constant "_SC_LINE_MAX" S.int let sc_getgr_r_size_max = S.constant "_SC_GETGR_R_SIZE_MAX" S.int let sc_getpw_r_size_max = S.constant "_SC_GETPW_R_SIZE_MAX" S.int let sc_ngroups_max = S.constant "_SC_NGROUPS_MAX" S.int let sc_re_dup_max = S.constant "_SC_RE_DUP_MAX" S.int let sc_symloop_max = S.constant "_SC_SYMLOOP_MAX" S.int (* POSIX options *) let sc_job_control = S.constant "_SC_JOB_CONTROL" S.int let sc_saved_ids = S.constant "_SC_SAVED_IDS" S.int let sc_fsync = S.constant "_SC_FSYNC" S.int let sc_mapped_files = S.constant "_SC_MAPPED_FILES" S.int let sc_memlock = S.constant "_SC_MEMLOCK" S.int let sc_memlock_range = S.constant "_SC_MEMLOCK_RANGE" S.int let sc_memory_protection = S.constant "_SC_MEMORY_PROTECTION" S.int let sc_priority_scheduling = S.constant "_SC_PRIORITY_SCHEDULING" S.int let sc_synchronized_io = S.constant "_SC_SYNCHRONIZED_IO" S.int let sc_timers = S.constant "_SC_TIMERS" S.int let sc_asynchronous_io = S.constant "_SC_ASYNCHRONOUS_IO" S.int let sc_prioritized_io = S.constant "_SC_PRIORITIZED_IO" S.int let sc_realtime_signals = S.constant "_SC_REALTIME_SIGNALS" S.int let sc_semaphores = S.constant "_SC_SEMAPHORES" S.int let sc_shared_memory_objects = S.constant "_SC_SHARED_MEMORY_OBJECTS" S.int let sc_message_passing = S.constant "_SC_MESSAGE_PASSING" S.int let sc_threads = S.constant "_SC_THREADS" S.int let sc_thread_safe_functions = S.constant "_SC_THREAD_SAFE_FUNCTIONS" S.int let sc_thread_attr_stackaddr = S.constant "_SC_THREAD_ATTR_STACKADDR" S.int let sc_thread_attr_stacksize = S.constant "_SC_THREAD_ATTR_STACKSIZE" S.int let sc_thread_priority_scheduling = S.constant "_SC_THREAD_PRIORITY_SCHEDULING" S.int let sc_thread_prio_inherit = S.constant "_SC_THREAD_PRIO_INHERIT" S.int let sc_thread_prio_protect = S.constant "_SC_THREAD_PRIO_PROTECT" S.int let sc_thread_process_shared = S.constant "_SC_THREAD_PROCESS_SHARED" S.int (* POSIX.2 constants *) let sc_2_version = S.constant "_SC_2_VERSION" S.int let sc_2_c_bind = S.constant "_SC_2_C_BIND" S.int let sc_2_c_dev = S.constant "_SC_2_C_DEV" S.int let sc_bc_base_max = S.constant "_SC_BC_BASE_MAX" S.int let sc_bc_dim_max = S.constant "_SC_BC_DIM_MAX" S.int let sc_bc_scale_max = S.constant "_SC_BC_SCALE_MAX" S.int let sc_bc_string_max = S.constant "_SC_BC_STRING_MAX" S.int let sc_coll_weights_max = S.constant "_SC_COLL_WEIGHTS_MAX" S.int let sc_expr_nest_max = S.constant "_SC_EXPR_NEST_MAX" S.int (* X/Open constants *) let sc_xopen_version = S.constant "_SC_XOPEN_VERSION" S.int let sc_xopen_crypt = S.constant "_SC_XOPEN_CRYPT" S.int let sc_xopen_enh_i18n = S.constant "_SC_XOPEN_ENH_I18N" S.int let sc_xopen_shm = S.constant "_SC_XOPEN_SHM" S.int let sc_xopen_unix = S.constant "_SC_XOPEN_UNIX" S.int (* pathconf names *) let pc_link_max = S.constant "_PC_LINK_MAX" S.int let pc_max_canon = S.constant "_PC_MAX_CANON" S.int let pc_max_input = S.constant "_PC_MAX_INPUT" S.int let pc_name_max = S.constant "_PC_NAME_MAX" S.int let pc_path_max = S.constant "_PC_PATH_MAX" S.int let pc_pipe_buf = S.constant "_PC_PIPE_BUF" S.int let pc_no_trunc = S.constant "_PC_NO_TRUNC" S.int let pc_vdisable = S.constant "_PC_VDISABLE" S.int let pc_chown_restricted = S.constant "_PC_CHOWN_RESTRICTED" S.int let pc_async_io = S.constant "_PC_ASYNC_IO" S.int let pc_prio_io = S.constant "_PC_PRIO_IO" S.int let pc_sync_io = S.constant "_PC_SYNC_IO" S.int let pc_filesizebits = S.constant "_PC_FILESIZEBITS" S.int let pc_2_symlinks = S.constant "_PC_2_SYMLINKS" S.int let pc_symlink_max = S.constant "_PC_SYMLINK_MAX" S.int (* lockf commands *) let f_ulock = S.constant "F_ULOCK" S.int let f_lock = S.constant "F_LOCK" S.int let f_tlock = S.constant "F_TLOCK" S.int let f_test = S.constant "F_TEST" S.int (* confstr names *) let cs_path = S.constant "_CS_PATH" S.int (* whence values for lseek (also in Unix but good to have) *) let seek_set = S.constant "SEEK_SET" S.int let seek_cur = S.constant "SEEK_CUR" S.int let seek_end = S.constant "SEEK_END" S.int (* access mode flags *) let r_ok = S.constant "R_OK" S.int let w_ok = S.constant "W_OK" S.int let x_ok = S.constant "X_OK" S.int let f_ok = S.constant "F_OK" S.int (* Standard file descriptors *) let stdin_fileno = S.constant "STDIN_FILENO" S.int let stdout_fileno = S.constant "STDOUT_FILENO" S.int let stderr_fileno = S.constant "STDERR_FILENO" S.int (* NULL constant (for completeness, though not typically needed in OCaml) *) (* let null = S.constant "NULL" S.int *) (* Not needed - use from_voidp *) end ocaml-posix-4.0.2/modules/unistd/src/dune000066400000000000000000000017621515131525300204020ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_unistd) (public_name posix-unistd) (synopsis "posix-unistd provides access to POSIX unistd.h APIs") (foreign_stubs (language c) (names posix_unistd_generated_stubs posix_unistd_generated_stubs_unlocked)) (libraries unix posix-errno ctypes posix-unistd.constants posix-unistd.stubs posix-unistd.stubs_unlocked)) (rule (targets posix_unistd_generated_stubs.c) (action (run ./generator/gen_stubs.exe c %{targets}))) (rule (targets posix_unistd_generated_stubs.ml) (action (run ./generator/gen_stubs.exe ml %{targets}))) (rule (targets posix_unistd_generated_stubs_unlocked.c) (action (run ./generator/gen_stubs_unlocked.exe c %{targets}))) (rule (targets posix_unistd_generated_stubs_unlocked.ml) (action (run ./generator/gen_stubs_unlocked.exe ml %{targets}))) (rule (targets posix_unistd_generated_constants.ml) (action (with-stdout-to %{targets} (run ./generator/gen_constants_c)))) ocaml-posix-4.0.2/modules/unistd/src/generator/000077500000000000000000000000001515131525300215045ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/unistd/src/generator/dune000066400000000000000000000012161515131525300223620ustar00rootroot00000000000000(executable (name gen_stubs) (modules gen_stubs) (libraries posix-unistd.stubs posix-base)) (executable (name gen_stubs_unlocked) (modules gen_stubs_unlocked) (libraries posix-unistd.stubs_unlocked posix-base)) (executable (name gen_constants_c) (modules gen_constants_c) (libraries posix-unistd.constants posix-base)) (rule (targets gen_constants.c) (action (run ./gen_constants_c.exe %{targets}))) (rule (targets gen_constants_c) (deps (:c_code ./gen_constants.c)) (action (run %{ocaml-config:c_compiler} %{read-lines:../../../../base/c_flags} -I %{ocaml-config:standard_library} -o %{targets} %{c_code}))) ocaml-posix-4.0.2/modules/unistd/src/generator/gen_constants_c.ml000066400000000000000000000006141515131525300252060ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_unistd_constants.Def let c_headers = {| #include #include #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 256 #endif #ifndef LOGIN_NAME_MAX #define LOGIN_NAME_MAX 256 #endif // FreeBSD does not have this one #ifndef _PC_2_SYMLINKS #define _PC_2_SYMLINKS 13 #endif |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/unistd/src/generator/gen_stubs.ml000066400000000000000000000010441515131525300240260ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_unistd_stubs.Def let c_headers = {| #include #include #include #include static inline size_t confstr_bytes(int name, unsigned char* buf, size_t len) { return confstr(name, (char*)buf, len); } #ifdef __FreeBSD__ static inline pid_t _setpgrp() { setpgrp(0, 0); return getpgid(0); } #define setpgrp _setpgrp #endif |} let concurrency = Cstubs.sequential let prefix = "posix_unistd" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/unistd/src/generator/gen_stubs_unlocked.ml000066400000000000000000000004441515131525300257150ustar00rootroot00000000000000module Stubs = Posix_base.Generators.Stubs (struct module Stubs = Posix_unistd_stubs_unlocked.Def let c_headers = {| #include #include #include |} let concurrency = Cstubs.unlocked let prefix = "posix_unistd_unlocked" end) let () = Stubs.gen () ocaml-posix-4.0.2/modules/unistd/src/generator/gen_types_c.ml000066400000000000000000000002441515131525300243350ustar00rootroot00000000000000module Types = Posix_base.Generators.Types (struct module Types = Posix_unistd_types.Def let c_headers = {| #include |} end) let () = Types.gen () ocaml-posix-4.0.2/modules/unistd/src/posix_unistd.ml000066400000000000000000000263661515131525300226150ustar00rootroot00000000000000open Ctypes include Posix_unistd_stubs.Def (Posix_unistd_generated_stubs) include Posix_unistd_stubs_unlocked.Def (Posix_unistd_generated_stubs_unlocked) module Constants = Posix_unistd_constants.Def (Posix_unistd_generated_constants) include Constants (* Helper to convert Unix.file_descr to int *) external fd_to_int : Unix.file_descr -> int = "%identity" (* Helper to convert int to Unix.file_descr *) external int_to_fd : int -> Unix.file_descr = "%identity" let default_buf_len = 1024 (* Basic I/O operations with OCaml-friendly API *) let read_wrapper ~name ~fn fd buf ofs len = if ofs < 0 || len < 0 || ofs + len > Bytes.length buf then invalid_arg (name ^ ": invalid offset or length"); let fd = fd_to_int fd in let tmp = CArray.make char len in let result = Posix_errno.raise_on_neg ~call:name (fun () -> fn fd (CArray.start tmp) len) in memcpy_to_bytes (ocaml_bytes_start buf) (CArray.start tmp) result; result let write_wrapper ~name ~fn fd buf ofs len = if ofs < 0 || len < 0 || ofs + len > Bytes.length buf then invalid_arg (name ^ ": invalid offset or length"); let fd = fd_to_int fd in let tmp = CArray.make char len in memcpy_from_bytes (CArray.start tmp) (ocaml_bytes_start buf) (Bytes.length buf); Posix_errno.raise_on_neg ~call:name (fun () -> fn fd (CArray.start tmp) len) let read = read_wrapper ~name:"read" ~fn:read let write = write_wrapper ~name:"write" ~fn:write let pread fd buf ofs len offset = read_wrapper ~name:"pread" ~fn:(fun fd buf len -> pread fd buf len offset) fd buf ofs len let pwrite fd buf ofs len offset = write_wrapper ~name:"pwrite" ~fn:(fun fd buf len -> pwrite fd buf len offset) fd buf ofs len (* File descriptor operations *) let close fd = ignore (Posix_errno.raise_on_neg ~call:"close" (fun () -> close (fd_to_int fd))) let dup fd = int_to_fd (Posix_errno.raise_on_neg ~call:"dup" (fun () -> dup (fd_to_int fd))) let dup2 fd1 fd2 = let fd1 = fd_to_int fd1 in let fd2 = fd_to_int fd2 in int_to_fd (Posix_errno.raise_on_neg ~call:"dup2" (fun () -> dup2 fd1 fd2)) let pipe () = let fds = allocate_n int ~count:2 in ignore (Posix_errno.raise_on_neg ~call:"pipe" (fun () -> pipe fds)); (int_to_fd !@fds, int_to_fd !@(fds +@ 1)) (* Data synchronization *) let fsync fd = let fd = fd_to_int fd in ignore (Posix_errno.raise_on_neg ~call:"fsync" (fun () -> fsync fd)) let fdatasync fd = let fd = fd_to_int fd in ignore (Posix_errno.raise_on_neg ~call:"fdatasync" (fun () -> fdatasync fd)) (* File operations *) let link ~target ~link_name = ignore (Posix_errno.raise_on_neg ~call:"link" (fun () -> link target link_name)) let symlink ~target ~link_name = ignore (Posix_errno.raise_on_neg ~call:"symlink" (fun () -> symlink target link_name)) let readlink ?(max_len = default_buf_len) path = let buf = CArray.make char max_len in let len = Posix_errno.raise_on_neg ~call:"readlink" (fun () -> readlink path (CArray.start buf) default_buf_len) in string_from_ptr (CArray.start buf) ~length:len let unlink path = ignore (Posix_errno.raise_on_neg ~call:"unlink" (fun () -> unlink path)) let rmdir path = ignore (Posix_errno.raise_on_neg ~call:"rmdir" (fun () -> rmdir path)) (* Directory operations *) let chdir path = ignore (Posix_errno.raise_on_neg ~call:"chdir" (fun () -> chdir path)) let fchdir fd = let fd = fd_to_int fd in ignore (Posix_errno.raise_on_neg ~call:"fchdir" (fun () -> fchdir fd)) let getcwd () = let buf = CArray.make char default_buf_len in ignore (Posix_errno.raise_on_null ~call:"getcwd" (fun () -> getcwd (CArray.start buf) default_buf_len)); string_from_ptr (CArray.start buf) ~length:(strlen (CArray.start buf)) (* File positioning *) type seek_command = Seek_set | Seek_cur | Seek_end let lseek fd offset whence = let fd = fd_to_int fd in let whence = match whence with | Seek_set -> seek_set | Seek_cur -> seek_cur | Seek_end -> seek_end in Posix_errno.raise_on_neg ~call:"lseek" (fun () -> lseek fd offset whence) (* File permissions and ownership *) type access_permission = [ `Read | `Write | `Execute | `Exists ] let access path perms = let mode = List.fold_left (fun acc perm -> acc lor match perm with | `Read -> r_ok | `Write -> w_ok | `Execute -> x_ok | `Exists -> f_ok) 0 perms in access path mode = 0 let chown path uid gid = let uid = Posix_types.Uid.of_int uid in let gid = Posix_types.Gid.of_int gid in ignore (Posix_errno.raise_on_neg ~call:"chown" (fun () -> chown path uid gid)) let fchown fd uid gid = let fd = fd_to_int fd in let uid = Posix_types.Uid.of_int uid in let gid = Posix_types.Gid.of_int gid in ignore (Posix_errno.raise_on_neg ~call:"fchown" (fun () -> fchown fd uid gid)) let lchown path uid gid = let uid = Posix_types.Uid.of_int uid in let gid = Posix_types.Gid.of_int gid in ignore (Posix_errno.raise_on_neg ~call:"lchown" (fun () -> lchown path uid gid)) let truncate path length = ignore (Posix_errno.raise_on_neg ~call:"truncate" (fun () -> truncate path length)) let ftruncate fd length = let fd = fd_to_int fd in ignore (Posix_errno.raise_on_neg ~call:"ftruncate" (fun () -> ftruncate fd length)) (* File locking *) type lock_command = [ `Unlock | `Lock | `Test_lock | `Try_lock ] let lockf fd cmd size = let fd = fd_to_int fd in let cmd = match cmd with | `Unlock -> f_ulock | `Lock -> f_lock | `Try_lock -> f_tlock | `Test_lock -> f_test in ignore (Posix_errno.raise_on_neg ~call:"lockf" (fun () -> lockf fd cmd size)) (* Process operations *) let fork () = Posix_errno.raise_on_neg ~call:"fork" fork let getpgid pid = Posix_errno.raise_on_neg ~call:"getpgid" (fun () -> getpgid pid) let setpgid pid pgid = ignore (Posix_errno.raise_on_neg ~call:"setpgid" (fun () -> setpgid pid pgid)) let setpgrp () = ignore (Posix_errno.raise_on_neg ~call:"setpgrp" setpgrp) let setsid () = Posix_errno.raise_on_neg ~call:"setsid" setsid let getsid pid = Posix_errno.raise_on_neg ~call:"getsid" (fun () -> getsid pid) (* User and group IDs *) let getuid () = Posix_types.Uid.to_int (getuid ()) let geteuid () = Posix_types.Uid.to_int (geteuid ()) let getgid () = Posix_types.Gid.to_int (getgid ()) let getegid () = Posix_types.Gid.to_int (getegid ()) let setuid uid = let uid = Posix_types.Uid.of_int uid in ignore (Posix_errno.raise_on_neg ~call:"setuid" (fun () -> setuid uid)) let seteuid uid = let uid = Posix_types.Uid.of_int uid in ignore (Posix_errno.raise_on_neg ~call:"seteuid" (fun () -> seteuid uid)) let setgid gid = let gid = Posix_types.Gid.of_int gid in ignore (Posix_errno.raise_on_neg ~call:"setgid" (fun () -> setgid gid)) let setegid gid = let gid = Posix_types.Gid.of_int gid in ignore (Posix_errno.raise_on_neg ~call:"setegid" (fun () -> setegid gid)) let setreuid ruid euid = let ruid = Posix_types.Uid.of_int ruid in let euid = Posix_types.Uid.of_int euid in ignore (Posix_errno.raise_on_neg ~call:"setreuid" (fun () -> setreuid ruid euid)) let setregid rgid egid = let rgid = Posix_types.Gid.of_int rgid in let egid = Posix_types.Gid.of_int egid in ignore (Posix_errno.raise_on_neg ~call:"setregid" (fun () -> setregid rgid egid)) (* Group membership *) let getgroups () = let ngroups = Posix_errno.raise_on_neg ~call:"getgroups" (fun () -> getgroups 0 (from_voidp Posix_types.gid_t null)) in let groups = allocate_n Posix_types.gid_t ~count:ngroups in let n = Posix_errno.raise_on_neg ~call:"getgroups" (fun () -> getgroups ngroups groups) in let result = Array.init n (fun i -> Posix_types.Gid.to_int !@(groups +@ i)) in Array.to_list result let setgroups groups = let ngroups = List.length groups in let groups_arr = CArray.of_list Posix_types.gid_t (List.map Posix_types.Gid.of_int groups) in ignore (Posix_errno.raise_on_neg ~call:"setgroups" (fun () -> setgroups ngroups (CArray.start groups_arr))) (* System configuration *) let sysconf name = Signed.Long.to_int (sysconf name) let pathconf path name = Signed.Long.to_int (pathconf path name) let fpathconf fd name = let fd_int = fd_to_int fd in Signed.Long.to_int (fpathconf fd_int name) let confstr name = let size = Posix_errno.raise_on_neg ~call:"confstr" (fun () -> confstr_ptr name (from_voidp char null) 0) in let buf = Bytes.create size in let ret = confstr_bytes name (ocaml_bytes_start buf) size in assert (ret = size); Bytes.unsafe_to_string buf (* Signal/timer *) let pause () = ignore (Posix_errno.raise_on_neg ~call:"pause" (fun () -> pause ())) let usleep n = ignore (Posix_errno.raise_on_neg ~call:"usleep" (fun () -> usleep n)) (* Terminal *) let isatty fd = let fd = fd_to_int fd in isatty fd <> 0 let ttyname fd = let fd = fd_to_int fd in Posix_errno.raise_on_none ~call:"ttyname" (fun () -> ttyname fd) let ttyname_r ?(len = host_name_max) fd = let fd = fd_to_int fd in let buf = CArray.make char len in match ttyname_r fd (CArray.start buf) len with | 0n -> string_from_ptr (CArray.start buf) ~length:(strlen (CArray.start buf)) | n -> raise (Unix.Unix_error (Posix_errno.int_to_unix_error n, "ttyname_r", "")) let ctermid () = let buf = CArray.make char host_name_max in let result = Posix_errno.raise_on_null ~call:"ctermid" (fun () -> ctermid (CArray.start buf)) in string_from_ptr result ~length:(strlen (CArray.start buf)) let tcgetpgrp fd = let fd = fd_to_int fd in Posix_errno.raise_on_neg ~call:"tcgetpgrp" (fun () -> tcgetpgrp fd) let tcsetpgrp fd pgrp = let fd = fd_to_int fd in ignore (Posix_errno.raise_on_neg ~call:"tcsetpgrp" (fun () -> tcsetpgrp fd pgrp)) (* System info *) let gethostid () = Signed.Long.to_int64 (gethostid ()) let gethostname () = let buf = CArray.make char host_name_max in ignore (Posix_errno.raise_on_neg ~call:"gethostname" (fun () -> gethostname (CArray.start buf) host_name_max)); string_from_ptr (CArray.start buf) ~length:(strlen (CArray.start buf)) let sethostname name = ignore (Posix_errno.raise_on_neg ~call:"sethostname" (fun () -> sethostname name (String.length name))) (* Login *) let getlogin () = Posix_errno.raise_on_none ~call:"getlogin" (fun () -> getlogin ()) let getlogin_r ?(len = login_name_max) () = let buf = CArray.make char len in match getlogin_r (CArray.start buf) len with | 0n -> string_from_ptr (CArray.start buf) ~length:(strlen (CArray.start buf)) | n -> raise (Unix.Unix_error (Posix_errno.int_to_unix_error n, "getlogin_r", "")) (* Program execution *) let execv path args = let args_arr = CArray.of_list string ((path :: args) @ [""]) in ignore (Posix_errno.raise_on_neg ~call:"execv" (fun () -> execv path (CArray.start args_arr))) let execve path args env = let args_arr = CArray.of_list string ((path :: args) @ [""]) in let env_arr = CArray.of_list string (env @ [""]) in ignore (Posix_errno.raise_on_neg ~call:"execve" (fun () -> execve path (CArray.start args_arr) (CArray.start env_arr))) let execvp file args = let args_arr = CArray.of_list string ((file :: args) @ [""]) in ignore (Posix_errno.raise_on_neg ~call:"execvp" (fun () -> execvp file (CArray.start args_arr))) ocaml-posix-4.0.2/modules/unistd/src/posix_unistd.mli000066400000000000000000000446761515131525300227720ustar00rootroot00000000000000(** POSIX unistd.h bindings. This module provides OCaml bindings to POSIX functions defined in {{:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html} unistd.h}. It includes functions for file I/O, process control, user/group IDs, directory operations, and system configuration. {2 Example} {[ (* Read from a file descriptor *) let buf = Bytes.create 1024 in let n = Posix_unistd.read fd buf 0 1024 in Printf.printf "Read %d bytes\n" n; (* Get system configuration *) let max_open = Posix_unistd.sysconf sc_open_max in Printf.printf "Max open files: %d\n" max_open ]} *) (** {1 Constants} *) (** {2 Name limits} *) val host_name_max : int val login_name_max : int (** {2 System configuration (sysconf) constants} *) (** Commonly available sysconf names *) val sc_arg_max : int val sc_child_max : int val sc_clk_tck : int val sc_open_max : int val sc_pagesize : int val sc_page_size : int val sc_nprocessors_onln : int val sc_nprocessors_conf : int val sc_phys_pages : int val sc_stream_max : int val sc_tzname_max : int val sc_version : int val sc_atexit_max : int val sc_login_name_max : int val sc_tty_name_max : int val sc_host_name_max : int val sc_line_max : int val sc_getgr_r_size_max : int val sc_getpw_r_size_max : int val sc_ngroups_max : int val sc_re_dup_max : int val sc_symloop_max : int (** POSIX options *) val sc_job_control : int val sc_saved_ids : int val sc_fsync : int val sc_mapped_files : int val sc_memlock : int val sc_memlock_range : int val sc_memory_protection : int val sc_priority_scheduling : int val sc_synchronized_io : int val sc_timers : int val sc_asynchronous_io : int val sc_prioritized_io : int val sc_realtime_signals : int val sc_semaphores : int val sc_shared_memory_objects : int val sc_message_passing : int val sc_threads : int val sc_thread_safe_functions : int val sc_thread_attr_stackaddr : int val sc_thread_attr_stacksize : int val sc_thread_priority_scheduling : int val sc_thread_prio_inherit : int val sc_thread_prio_protect : int val sc_thread_process_shared : int (** POSIX.2 constants *) val sc_2_version : int val sc_2_c_bind : int val sc_2_c_dev : int val sc_bc_base_max : int val sc_bc_dim_max : int val sc_bc_scale_max : int val sc_bc_string_max : int val sc_coll_weights_max : int val sc_expr_nest_max : int (** X/Open constants *) val sc_xopen_version : int val sc_xopen_crypt : int val sc_xopen_enh_i18n : int val sc_xopen_shm : int val sc_xopen_unix : int (** {2 Path configuration (pathconf) constants} *) val pc_link_max : int val pc_max_canon : int val pc_max_input : int val pc_name_max : int val pc_path_max : int val pc_pipe_buf : int val pc_no_trunc : int val pc_vdisable : int val pc_chown_restricted : int val pc_async_io : int val pc_prio_io : int val pc_sync_io : int val pc_filesizebits : int val pc_2_symlinks : int val pc_symlink_max : int (** {2 File locking (lockf) commands} *) val f_ulock : int val f_lock : int val f_tlock : int val f_test : int (** {2 Configuration strings (confstr) constants} *) val cs_path : int (** {2 File positioning (lseek) constants} *) val seek_set : int val seek_cur : int val seek_end : int (** {2 File access mode flags} *) (** Read permission *) val r_ok : int (** Write permission *) val w_ok : int (** Execute permission *) val x_ok : int (** File exists *) val f_ok : int (** {2 Standard file descriptors} *) val stdin_fileno : int val stdout_fileno : int val stderr_fileno : int (** {1 Basic I/O Operations} *) (** Read from a file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html} read(2)}. @return Number of bytes read. @raise Unix.Unix_error on failure. *) val read : Unix.file_descr -> bytes -> int -> int -> int (** Write to a file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html} write(2)}. @return Number of bytes written. @raise Unix.Unix_error on failure. *) val write : Unix.file_descr -> bytes -> int -> int -> int (** {1 Positioned I/O} *) (** Read from a file descriptor at a given offset without changing the file offset. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html} pread(2)}. @return Number of bytes read. @raise Unix.Unix_error on failure. *) val pread : Unix.file_descr -> bytes -> int -> int -> int -> int (** Write to a file descriptor at a given offset without changing the file offset. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html} pwrite(2)}. @return Number of bytes written. @raise Unix.Unix_error on failure. *) val pwrite : Unix.file_descr -> bytes -> int -> int -> int -> int (** {1 File Descriptor Operations} *) (** Close a file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html} close(2)}. *) val close : Unix.file_descr -> unit (** Duplicate a file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html} dup(2)}. *) val dup : Unix.file_descr -> Unix.file_descr (** Duplicate a file descriptor to a specified descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html} dup2(2)}. *) val dup2 : Unix.file_descr -> Unix.file_descr -> Unix.file_descr (** Create a pipe. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html} pipe(2)}. @return [(read_end, write_end)]. *) val pipe : unit -> Unix.file_descr * Unix.file_descr (** {1 Data Synchronization} *) (** Synchronize file data and metadata to disk. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html} fsync(2)}. *) val fsync : Unix.file_descr -> unit (** Synchronize file data (but not necessarily metadata) to disk. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html} fdatasync(2)}. *) val fdatasync : Unix.file_descr -> unit (** Schedule writes of all modified buffer cache blocks to disk. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/sync.html} sync(2)}. *) val sync : unit -> unit (** {1 File Operations} *) (** Create a hard link. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html} link(2)}. *) val link : target:string -> link_name:string -> unit (** Create a symbolic link. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/symlink.html} symlink(2)}. *) val symlink : target:string -> link_name:string -> unit (** Read the target of a symbolic link. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html} readlink(2)}. *) val readlink : ?max_len:int -> string -> string (** Remove a file. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html} unlink(2)}. *) val unlink : string -> unit (** Remove an empty directory. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html} rmdir(2)}. *) val rmdir : string -> unit (** {1 Directory Operations} *) (** Change the current working directory. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html} chdir(2)}. *) val chdir : string -> unit (** Change the current working directory to a directory referenced by a file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html} fchdir(2)}. *) val fchdir : Unix.file_descr -> unit (** Get the current working directory. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html} getcwd(3)}. *) val getcwd : unit -> string (** {1 File Positioning} *) (** File positioning commands for {!lseek}. *) type seek_command = | Seek_set (** Set offset to the given value *) | Seek_cur (** Set offset relative to current position *) | Seek_end (** Set offset relative to end of file *) (** Reposition the file offset. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html} lseek(2)}. *) val lseek : Unix.file_descr -> int -> seek_command -> int (** {1 File Permissions and Ownership} *) (** Access permission flags for {!access}. *) type access_permission = [ `Read | `Write | `Execute | `Exists ] (** Check file accessibility. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html} access(2)}. *) val access : string -> access_permission list -> bool (** Change file ownership. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html} chown(2)}. *) val chown : string -> int -> int -> unit (** Change file ownership using a file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html} fchown(2)}. *) val fchown : Unix.file_descr -> int -> int -> unit (** Change ownership of a symbolic link itself. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/lchown.html} lchown(2)}. *) val lchown : string -> int -> int -> unit (** Truncate a file to a specified length. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html} truncate(2)}. *) val truncate : string -> int -> unit (** Truncate a file to a specified length using a file descriptor. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html} ftruncate(2)}. *) val ftruncate : Unix.file_descr -> int -> unit (** {1 File Locking} *) (** File locking commands for {!lockf}. *) type lock_command = [ `Unlock | `Lock | `Test_lock | `Try_lock ] (** Apply, test, or remove a POSIX lock on a section of a file. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/lockf.html} lockf(3)}. *) val lockf : Unix.file_descr -> lock_command -> int -> unit (** {1 Process Operations} *) (** Create a new process. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html} fork(2)}. @return 0 in the child, child's PID in the parent. *) val fork : unit -> int (** Get the process ID of the calling process. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html} getpid(2)}. *) val getpid : unit -> int (** Get the parent process ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html} getppid(2)}. *) val getppid : unit -> int (** Get the process group ID of a process. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgid.html} getpgid(2)}. *) val getpgid : int -> int (** Set the process group ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html} setpgid(2)}. *) val setpgid : int -> int -> unit (** Get the process group ID of the calling process. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html} getpgrp(2)}. *) val getpgrp : unit -> int (** Set the process group ID to the process ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgrp.html} setpgrp(3)}. *) val setpgrp : unit -> unit (** Create a new session. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html} setsid(2)}. @return The session ID. *) val setsid : unit -> int (** Get the session ID of a process. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html} getsid(2)}. *) val getsid : int -> int (** {1 User and Group IDs} *) (** Get the real user ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html} getuid(2)}. *) val getuid : unit -> int (** Get the effective user ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html} geteuid(2)}. *) val geteuid : unit -> int (** Get the real group ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html} getgid(2)}. *) val getgid : unit -> int (** Get the effective group ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html} getegid(2)}. *) val getegid : unit -> int (** Set the user ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html} setuid(2)}. *) val setuid : int -> unit (** Set the effective user ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/seteuid.html} seteuid(2)}. *) val seteuid : int -> unit (** Set the group ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setgid.html} setgid(2)}. *) val setgid : int -> unit (** Set the effective group ID. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setegid.html} setegid(2)}. *) val setegid : int -> unit (** Set real and effective user IDs. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setreuid.html} setreuid(2)}. *) val setreuid : int -> int -> unit (** Set real and effective group IDs. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setregid.html} setregid(2)}. *) val setregid : int -> int -> unit (** {1 Group Membership} *) (** Get the list of supplementary group IDs. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgroups.html} getgroups(2)}. *) val getgroups : unit -> int list (** Set the supplementary group IDs. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/setgroups.html} setgroups(2)}. *) val setgroups : int list -> unit (** {1 System Configuration} *) (** Get system configuration value. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html} sysconf(3)}. Use [sc_*] constants. *) val sysconf : int -> int (** Get path configuration value. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html} pathconf(3)}. Use [pc_*] constants. *) val pathconf : string -> int -> int (** Get path configuration value for an open file. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/fpathconf.html} fpathconf(3)}. *) val fpathconf : Unix.file_descr -> int -> int (** Get configuration string value. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html} confstr(3)}. Use [cs_*] constants. *) val confstr : int -> string (** {1 Process Priority} *) (** Adjust process priority. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/nice.html} nice(2)}. @return The new priority. *) val nice : int -> int (** {1 Sleep Operations} *) (** Sleep for a number of seconds. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.html} sleep(3)}. @return 0 on completion, or seconds remaining if interrupted. *) val sleep : int -> int (** Sleep for a number of microseconds. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/usleep.html} usleep(3)}. *) val usleep : int -> unit (** {1 Signal and Timer} *) (** Wait until a signal is caught. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html} pause(2)}. *) val pause : unit -> unit (** Set an alarm clock. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html} alarm(2)}. @return Seconds remaining from previous alarm, or 0 if none. *) val alarm : int -> int (** {1 Terminal Operations} *) (** Test whether a file descriptor refers to a terminal. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/isatty.html} isatty(3)}. *) val isatty : Unix.file_descr -> bool (** Get the name of a terminal device. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/ttyname.html} ttyname(3)}. *) val ttyname : Unix.file_descr -> string (** Thread-safe version of {!ttyname}. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/ttyname.html} ttyname_r(3)}. *) val ttyname_r : ?len:int -> Unix.file_descr -> string (** Get the pathname of the controlling terminal. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/ctermid.html} ctermid(3)}. *) val ctermid : unit -> string (** Get the foreground process group ID associated with a terminal. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetpgrp.html} tcgetpgrp(3)}. *) val tcgetpgrp : Unix.file_descr -> int (** Set the foreground process group ID associated with a terminal. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html} tcsetpgrp(3)}. *) val tcsetpgrp : Unix.file_descr -> int -> unit (** {1 System Information} *) (** Get the system page size in bytes. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpagesize.html} getpagesize(2)}. *) val getpagesize : unit -> int (** Get the unique identifier of the current host. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostid.html} gethostid(3)}. *) val gethostid : unit -> int64 (** Get the host name. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html} gethostname(2)}. *) val gethostname : unit -> string (** Set the host name. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/sethostname.html} sethostname(2)}. *) val sethostname : string -> unit (** {1 Login Information} *) (** Get the login name of the user. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getlogin.html} getlogin(3)}. *) val getlogin : unit -> string (** Thread-safe version of {!getlogin}. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/getlogin.html} getlogin_r(3)}. *) val getlogin_r : ?len:int -> unit -> string (** {1 Program Execution} *) (** Execute a program with specified arguments. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html} execv(2)}. Only returns on error (by raising an exception). *) val execv : string -> string list -> unit (** Execute a program with specified arguments and environment. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html} execve(2)}. Only returns on error (by raising an exception). *) val execve : string -> string list -> string list -> unit (** Execute a program using PATH to find the executable. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html} execvp(2)}. Only returns on error (by raising an exception). *) val execvp : string -> string list -> unit (** {1 Process Termination} *) (** Terminate the calling process immediately without cleanup. See {{:https://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html} _exit(2)}. Use [Stdlib.exit] for normal termination. *) val _exit : int -> unit ocaml-posix-4.0.2/modules/unistd/src/stubs/000077500000000000000000000000001515131525300206565ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/unistd/src/stubs/dune000066400000000000000000000005501515131525300215340ustar00rootroot00000000000000(env (dev (flags (:standard -warn-error -A)))) (library (name posix_unistd_stubs) (public_name posix-unistd.stubs) (modules posix_unistd_stubs) (libraries posix-types ctypes.stubs)) (library (name posix_unistd_stubs_unlocked) (public_name posix-unistd.stubs_unlocked) (modules posix_unistd_stubs_unlocked) (libraries posix-types ctypes.stubs)) ocaml-posix-4.0.2/modules/unistd/src/stubs/posix_unistd_stubs.ml000066400000000000000000000115021515131525300251570ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F let strlen = foreign "strlen" (ptr char @-> returning int) let memcpy_to_bytes = foreign "memcpy" (ocaml_bytes @-> ptr char @-> int @-> returning void) let memcpy_from_bytes = foreign "memcpy" (ptr char @-> ocaml_bytes @-> int @-> returning void) let ttyname_r = foreign "ttyname_r" (int @-> ptr char @-> int @-> returning nativeint) let getlogin_r = foreign "getlogin_r" (ptr char @-> int @-> returning nativeint) (* File descriptor operations *) let close = foreign "close" (int @-> returning int) let dup = foreign "dup" (int @-> returning int) let dup2 = foreign "dup2" (int @-> int @-> returning int) let pipe = foreign "pipe" (ptr int @-> returning int) (* Data synchronization *) let fsync = foreign "fsync" (int @-> returning int) let fdatasync = foreign "fdatasync" (int @-> returning int) let sync = foreign "sync" (void @-> returning void) (* File operations *) let link = foreign "link" (string @-> string @-> returning int) let symlink = foreign "symlink" (string @-> string @-> returning int) let unlink = foreign "unlink" (string @-> returning int) let rmdir = foreign "rmdir" (string @-> returning int) (* Directory operations *) let chdir = foreign "chdir" (string @-> returning int) let fchdir = foreign "fchdir" (int @-> returning int) let getcwd = foreign "getcwd" (ptr char @-> int @-> returning (ptr char)) (* File permissions and ownership *) let access = foreign "access" (string @-> int @-> returning int) let chown = foreign "chown" (string @-> Posix_types.uid_t @-> Posix_types.gid_t @-> returning int) let fchown = foreign "fchown" (int @-> Posix_types.uid_t @-> Posix_types.gid_t @-> returning int) let lchown = foreign "lchown" (string @-> Posix_types.uid_t @-> Posix_types.gid_t @-> returning int) let truncate = foreign "truncate" (string @-> int @-> returning int) let ftruncate = foreign "ftruncate" (int @-> int @-> returning int) (* File locking *) let lockf = foreign "lockf" (int @-> int @-> int @-> returning int) let getpid = foreign "getpid" (void @-> returning int) let getppid = foreign "getppid" (void @-> returning int) let getpgid = foreign "getpgid" (int @-> returning int) let setpgid = foreign "setpgid" (int @-> int @-> returning int) let getpgrp = foreign "getpgrp" (void @-> returning int) let setpgrp = foreign "setpgrp" (void @-> returning int) let setsid = foreign "setsid" (void @-> returning int) let getsid = foreign "getsid" (int @-> returning int) (* User and group IDs *) let getuid = foreign "getuid" (void @-> returning Posix_types.uid_t) let geteuid = foreign "geteuid" (void @-> returning Posix_types.uid_t) let getgid = foreign "getgid" (void @-> returning Posix_types.gid_t) let getegid = foreign "getegid" (void @-> returning Posix_types.gid_t) let setuid = foreign "setuid" (Posix_types.uid_t @-> returning int) let seteuid = foreign "seteuid" (Posix_types.uid_t @-> returning int) let setgid = foreign "setgid" (Posix_types.gid_t @-> returning int) let setegid = foreign "setegid" (Posix_types.gid_t @-> returning int) let setreuid = foreign "setreuid" (Posix_types.uid_t @-> Posix_types.uid_t @-> returning int) let setregid = foreign "setregid" (Posix_types.gid_t @-> Posix_types.gid_t @-> returning int) (* Group membership *) let getgroups = foreign "getgroups" (int @-> ptr Posix_types.gid_t @-> returning int) let setgroups = foreign "setgroups" (int @-> ptr Posix_types.gid_t @-> returning int) (* System configuration *) let sysconf = foreign "sysconf" (int @-> returning long) let pathconf = foreign "pathconf" (string @-> int @-> returning long) let fpathconf = foreign "fpathconf" (int @-> int @-> returning long) (* Configuration strings - needs special handling for buffer size *) let confstr_ptr = foreign "confstr" (int @-> ptr char @-> int @-> returning int) (* Configuration strings - needs special handling for buffer size *) let confstr_bytes = foreign "confstr_bytes" (int @-> ocaml_bytes @-> int @-> returning int) (* Terminal *) let isatty = foreign "isatty" (int @-> returning int) let ttyname = foreign "ttyname" (int @-> returning string_opt) let ctermid = foreign "ctermid" (ptr char @-> returning (ptr char)) let tcgetpgrp = foreign "tcgetpgrp" (int @-> returning int) let tcsetpgrp = foreign "tcsetpgrp" (int @-> int @-> returning int) (* System info *) let getpagesize = foreign "getpagesize" (void @-> returning int) let gethostid = foreign "gethostid" (void @-> returning long) let gethostname = foreign "gethostname" (ptr char @-> int @-> returning int) let sethostname = foreign "sethostname" (string @-> int @-> returning int) (* Login *) let getlogin = foreign "getlogin" (void @-> returning string_opt) end ocaml-posix-4.0.2/modules/unistd/src/stubs/posix_unistd_stubs_unlocked.ml000066400000000000000000000027401515131525300270470ustar00rootroot00000000000000open Ctypes module Def (F : Cstubs.FOREIGN) = struct open F (* Type alias to fix const char ** vs char *const * mismatch *) let argv_t = typedef (ptr string) "char*const*" (* Basic I/O operations *) let read = foreign "read" (int @-> ptr char @-> int @-> returning int) let write = foreign "write" (int @-> ptr char @-> int @-> returning int) (* Positioned I/O *) let pread = foreign "pread" (int @-> ptr char @-> int @-> int @-> returning int) let pwrite = foreign "pwrite" (int @-> ptr char @-> int @-> int @-> returning int) let readlink = foreign "readlink" (string @-> ptr char @-> int @-> returning int) (* File positioning *) let lseek = foreign "lseek" (int @-> int @-> int @-> returning int) (* Process operations *) let fork = foreign "fork" (void @-> returning int) (* Process priority *) let nice = foreign "nice" (int @-> returning int) (* Sleep operations *) let sleep = foreign "sleep" (int @-> returning int) let usleep = foreign "usleep" (int @-> returning int) (* Signal/timer *) let pause = foreign "pause" (void @-> returning int) let alarm = foreign "alarm" (int @-> returning int) (* Program execution *) let execv = foreign "execv" (string @-> argv_t @-> returning int) let execve = foreign "execve" (string @-> argv_t @-> argv_t @-> returning int) let execvp = foreign "execvp" (string @-> argv_t @-> returning int) (* Process termination *) let _exit = foreign "_exit" (int @-> returning void) end ocaml-posix-4.0.2/modules/unistd/test/000077500000000000000000000000001515131525300177065ustar00rootroot00000000000000ocaml-posix-4.0.2/modules/unistd/test/dune000066400000000000000000000007661515131525300205750ustar00rootroot00000000000000(executable (name test) (modules test_helpers test_constants test_file_descriptors test_files test_directories test_io test_sync test_process test_terminal test_sysinfo test_io_errors test_file_descriptors_errors test_files_errors test_directories_errors test_process_errors test_terminal_errors test_sysinfo_errors test) (libraries compiler-libs.common unix posix-unistd ounit2)) (rule (alias citest) (package posix-unistd) (action (run %{exe:test.exe}))) ocaml-posix-4.0.2/modules/unistd/test/test.ml000066400000000000000000000012751515131525300212240ustar00rootroot00000000000000open OUnit2 let suite = "posix-unistd tests" >::: [ Test_constants.suite; Test_file_descriptors.suite; Test_files.suite; Test_directories.suite; Test_io.suite; Test_sync.suite; Test_process.suite; Test_terminal.suite; Test_sysinfo.suite; (* Error handling tests *) Test_io_errors.suite; Test_file_descriptors_errors.suite; Test_files_errors.suite; Test_directories_errors.suite; Test_process_errors.suite; Test_terminal_errors.suite; Test_sysinfo_errors.suite; ] let () = at_exit Test_helpers.flush_verbose; run_test_tt_main suite ocaml-posix-4.0.2/modules/unistd/test/test_constants.ml000066400000000000000000000016211515131525300233130ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_constants _ = test_success "constants" "constants" "Verify POSIX constants" (fun () -> (* Standard file descriptors *) assert_equal 0 stdin_fileno; assert_equal 1 stdout_fileno; assert_equal 2 stderr_fileno; (* Access modes *) assert (r_ok >= 0); assert (w_ok >= 0); assert (x_ok >= 0); assert (f_ok >= 0); (* Seek constants *) assert (seek_set >= 0); assert (seek_cur >= 0); assert (seek_end >= 0); (* Lockf constants *) assert (f_lock >= 0); assert (f_ulock >= 0); assert (f_test >= 0); assert (f_tlock >= 0); (* sysconf constants - just check they're defined *) assert (sc_pagesize > 0); assert (sc_open_max > 0); assert (sc_arg_max >= 0)) let suite = "Constants tests" >::: ["test_constants" >:: test_constants] ocaml-posix-4.0.2/modules/unistd/test/test_directories.ml000066400000000000000000000020721515131525300236140ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_chdir_getcwd _ = test_success "chdir/getcwd" "chdir/getcwd" "Change and get current directory" (fun () -> let original_dir = Sys.getcwd () in with_temp_dir (fun tmp -> (* Change to temp directory *) chdir tmp; (* Get current directory *) let cwd = getcwd () in (* Normalize paths for comparison *) let tmp_real = Unix.realpath tmp in let cwd_real = Unix.realpath cwd in assert_equal tmp_real cwd_real; (* Restore original directory *) Unix.chdir original_dir)) let test_rmdir _ = test_success "rmdir" "rmdir" "Remove directory" (fun () -> let tmp = Filename.temp_file "posix_unistd_test" ".dir" in Unix.unlink tmp; Unix.mkdir tmp 0o755; (* Remove directory *) rmdir tmp; assert_bool "Directory should not exist" (not (Sys.file_exists tmp))) let suite = "Directory operation tests" >::: ["test_chdir_getcwd" >:: test_chdir_getcwd; "test_rmdir" >:: test_rmdir] ocaml-posix-4.0.2/modules/unistd/test/test_directories_errors.ml000066400000000000000000000057011515131525300252120ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers (* Test error handling for directory operations *) let test_chdir_nonexistent _ = (* Changing to nonexistent directory should raise ENOENT *) assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "chdir", "")) "chdir to nonexistent" (fun () -> chdir "/nonexistent/directory") let test_chdir_not_directory _ = (* Changing to a file (not directory) should raise ENOTDIR *) with_temp_file (fun tmp -> assert_raises_verbose (Unix.Unix_error (Unix.ENOTDIR, "chdir", "")) "chdir to file" (fun () -> chdir tmp)) let test_rmdir_nonexistent _ = (* Removing nonexistent directory should raise ENOENT *) assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "rmdir", "")) "rmdir nonexistent" (fun () -> rmdir "/nonexistent/directory") let test_rmdir_not_directory _ = (* Removing a file (not directory) should raise ENOTDIR *) with_temp_file (fun tmp -> assert_raises_verbose (Unix.Unix_error (Unix.ENOTDIR, "rmdir", "")) "rmdir file" (fun () -> rmdir tmp)) let test_rmdir_nonempty _ = (* Removing non-empty directory should raise ENOTEMPTY or EEXIST *) with_temp_dir (fun tmpdir -> (* Create a file in the directory *) let filepath = Filename.concat tmpdir "testfile" in let fd = Unix.openfile filepath [Unix.O_CREAT; Unix.O_WRONLY] 0o644 in Unix.close fd; try rmdir tmpdir; assert_failure "Unexpected success - should have failed" with Unix.Unix_error ((Unix.ENOTEMPTY | Unix.EEXIST), "rmdir", _) -> Unix.unlink filepath) let test_getcwd_after_delete _ = (* This test checks behavior when current directory is deleted *) (* getcwd should either succeed or raise ENOENT depending on system *) let original_dir = Sys.getcwd () in with_temp_dir (fun tmpdir -> chdir tmpdir; (* Delete the current directory from another path reference *) Unix.rmdir tmpdir; try let _ = getcwd () in (* Some systems allow this *) () with Unix.Unix_error (Unix.ENOENT, "getcwd", "") -> (* Other systems raise ENOENT *) ()); (* Restore original directory *) Unix.chdir original_dir let test_pathconf_nonexistent _ = (* pathconf on nonexistent file returns -1 without raising *) let result = pathconf "/nonexistent/file" pc_name_max in (* pathconf returns -1 for errors but doesn't check errno *) assert_equal (-1) result let suite = "Directory operation error tests" >::: [ "test_chdir_nonexistent" >:: test_chdir_nonexistent; "test_chdir_not_directory" >:: test_chdir_not_directory; "test_rmdir_nonexistent" >:: test_rmdir_nonexistent; "test_rmdir_not_directory" >:: test_rmdir_not_directory; "test_rmdir_nonempty" >:: test_rmdir_nonempty; "test_getcwd_after_delete" >:: test_getcwd_after_delete; "test_pathconf_nonexistent" >:: test_pathconf_nonexistent; ] ocaml-posix-4.0.2/modules/unistd/test/test_file_descriptors.ml000066400000000000000000000042241515131525300246410ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_pipe _ = test_success "pipe" "pipe" "Create and use pipe" (fun () -> let read_fd, write_fd = pipe () in (* Write to pipe *) let msg = Bytes.of_string "Hello, pipe!" in let written = write write_fd msg 0 (Bytes.length msg) in assert_equal (Bytes.length msg) written; (* Read from pipe *) let buf = Bytes.create 20 in let read_count = read read_fd buf 0 20 in assert_equal (Bytes.length msg) read_count; assert_equal "Hello, pipe!" (Bytes.sub_string buf 0 (Bytes.length msg)); (* Close descriptors *) close read_fd; close write_fd) let test_dup _ = test_success "dup" "dup" "Duplicate file descriptor" (fun () -> with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR; Unix.O_CREAT] 0o644 in (* Test dup *) let fd2 = dup fd in (* Write via original fd *) let msg = Bytes.of_string "test" in ignore (write fd msg 0 4); (* Read via duplicated fd *) ignore (lseek fd2 0 Seek_set); let buf = Bytes.create 4 in let n = read fd2 buf 0 4 in assert_equal 4 n; assert_equal "test" (Bytes.to_string buf); close fd2; Unix.close fd)) let test_dup2 _ = test_success "dup2" "dup2" "Duplicate fd to specific number" (fun () -> with_temp_file (fun tmp -> let fd1 = Unix.openfile tmp [Unix.O_RDWR; Unix.O_CREAT] 0o644 in let fd2 = Unix.openfile "/dev/null" [Unix.O_RDONLY] 0 in (* Test dup2 *) let _ = dup2 fd1 fd2 in (* fd2 should now point to tmp *) let msg = Bytes.of_string "dup2" in ignore (write fd2 msg 0 4); ignore (lseek fd2 0 Seek_set); let buf = Bytes.create 4 in let n = read fd2 buf 0 4 in assert_equal 4 n; assert_equal "dup2" (Bytes.to_string buf); Unix.close fd1; Unix.close fd2)) let suite = "File descriptor tests" >::: [ "test_pipe" >:: test_pipe; "test_dup" >:: test_dup; "test_dup2" >:: test_dup2; ] ocaml-posix-4.0.2/modules/unistd/test/test_file_descriptors_errors.ml000066400000000000000000000073071515131525300262420ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers (* Test error handling for file descriptor operations *) let test_close_bad_fd _ = (* Closing an invalid file descriptor should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "close" (fun () -> close bad_fd)) let test_close_twice _ = (* Closing the same fd twice should raise EBADF on second close *) with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in close fd; assert_raises_errno Unix.EBADF "close" (fun () -> close fd)) let test_dup_bad_fd _ = (* dup on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "dup" (fun () -> ignore (dup bad_fd))) let test_dup2_bad_fd _ = (* dup2 with invalid source fd should raise EBADF *) (* Note: After closing bad_fd, opening another file may reuse the same fd number, so we use two separate temp files to avoid fd reuse *) with_temp_file (fun tmp1 -> with_temp_file (fun tmp2 -> let fd1 = Unix.openfile tmp1 [Unix.O_RDWR] 0o644 in let fd2 = Unix.openfile tmp2 [Unix.O_RDWR] 0o644 in Unix.close fd1; assert_raises_errno Unix.EBADF "dup2" (fun () -> ignore (dup2 fd1 fd2)); Unix.close fd2)) let test_fsync_bad_fd _ = (* fsync on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "fsync" (fun () -> fsync bad_fd)) let test_fdatasync_bad_fd _ = (* fdatasync on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "fdatasync" (fun () -> fdatasync bad_fd)) let test_ftruncate_bad_fd _ = (* ftruncate on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "ftruncate" (fun () -> ftruncate bad_fd 0)) let test_fchown_bad_fd _ = (* fchown on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "fchown" (fun () -> fchown bad_fd 0 0)) let test_fchdir_bad_fd _ = (* fchdir on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "fchdir" (fun () -> fchdir bad_fd)) let test_fpathconf_bad_fd _ = (* fpathconf on invalid fd returns -1 for bad fd, doesn't raise *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; let result = fpathconf bad_fd pc_name_max in (* fpathconf returns -1 but doesn't check errno for invalid values *) assert_equal (-1) result) let suite = "File descriptor error tests" >::: [ "test_close_bad_fd" >:: test_close_bad_fd; "test_close_twice" >:: test_close_twice; "test_dup_bad_fd" >:: test_dup_bad_fd; "test_dup2_bad_fd" >:: test_dup2_bad_fd; "test_fsync_bad_fd" >:: test_fsync_bad_fd; "test_fdatasync_bad_fd" >:: test_fdatasync_bad_fd; "test_ftruncate_bad_fd" >:: test_ftruncate_bad_fd; "test_fchown_bad_fd" >:: test_fchown_bad_fd; "test_fchdir_bad_fd" >:: test_fchdir_bad_fd; "test_fpathconf_bad_fd" >:: test_fpathconf_bad_fd; ] ocaml-posix-4.0.2/modules/unistd/test/test_files.ml000066400000000000000000000072751515131525300224140ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_access _ = test_success "access" "access" "Check file access permissions" (fun () -> with_temp_file (fun tmp -> (* File exists *) assert_bool "File should exist" (access tmp [`Exists]); (* Readable *) assert_bool "File should be readable" (access tmp [`Read]); (* Non-existent file *) assert_bool "Non-existent file should return false" (not (access "/nonexistent/file/path" [`Exists])))) let test_link_unlink _ = test_success "link/unlink" "link/unlink" "Create and remove hard link" (fun () -> with_temp_file (fun tmp -> let link_name = tmp ^ ".link" in (* Create hard link *) link ~target:tmp ~link_name; (* Verify link exists *) assert_bool "Link should exist" (Sys.file_exists link_name); (* Remove link *) unlink link_name; assert_bool "Link should not exist" (not (Sys.file_exists link_name)))) let test_symlink_readlink _ = test_success "symlink/readlink" "symlink/readlink" "Create and read symbolic link" (fun () -> with_temp_file (fun tmp -> let link_name = tmp ^ ".symlink" in (* Create symlink *) symlink ~target:tmp ~link_name; (* Read symlink *) let target = readlink link_name in assert_equal tmp target; (* Clean up *) unlink link_name)) let test_truncate _ = test_success "truncate" "truncate" "Truncate file by path" (fun () -> with_temp_file (fun tmp -> (* Write some data *) let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in let msg = Bytes.of_string "Hello, World!" in ignore (write fd msg 0 (Bytes.length msg)); Unix.close fd; (* Truncate to 5 bytes *) truncate tmp 5; (* Verify size *) let size = (Unix.stat tmp).Unix.st_size in assert_equal 5 size)) let test_ftruncate _ = test_success "ftruncate" "ftruncate" "Truncate file by descriptor" (fun () -> with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in (* Write some data *) let msg = Bytes.of_string "Hello, World!" in ignore (write fd msg 0 (Bytes.length msg)); (* Truncate via fd *) ftruncate fd 7; Unix.close fd; (* Verify size *) let size = (Unix.stat tmp).Unix.st_size in assert_equal 7 size)) let test_chown _ = with_temp_file (fun tmp -> let uid = getuid () in let gid = getgid () in (* Change to same owner/group (should succeed) *) try test_success "chown" "chown" "Change file owner/group" (fun () -> chown tmp uid gid) with _ -> skip_test "chown" "chown" "Change file owner/group" "chown requires privileges or not supported") let test_lockf _ = test_success "lockf" "lockf" "File locking operations" (fun () -> with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in (* Lock the file *) lockf fd `Lock 0; (* Unlock the file *) lockf fd `Unlock 0; (* Try lock (non-blocking) *) lockf fd `Try_lock 0; lockf fd `Unlock 0; Unix.close fd)) let suite = "File operation tests" >::: [ "test_access" >:: test_access; "test_link_unlink" >:: test_link_unlink; "test_symlink_readlink" >:: test_symlink_readlink; "test_truncate" >:: test_truncate; "test_ftruncate" >:: test_ftruncate; "test_chown" >:: test_chown; "test_lockf" >:: test_lockf; ] ocaml-posix-4.0.2/modules/unistd/test/test_files_errors.ml000066400000000000000000000120471515131525300240010ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers (* Test error handling for file operations *) let test_link_nonexistent _ = (* Linking to nonexistent file should raise ENOENT *) with_temp_file (fun tmp -> assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "link", "")) "link with nonexistent target" (fun () -> link ~target:"/nonexistent/source" ~link_name:tmp)) let test_link_permission_denied _ = (* Trying to create link in restricted directory should raise EACCES, EPERM, or EROFS *) (* Only test if we don't have root privileges *) if getuid () = 0 then skip_test "link permission denied" "link" "Permission denied (link)" "Running as root" else with_temp_file (fun tmp -> try link ~target:tmp ~link_name:"/root/testlink"; (* Some systems might allow this or /root might not exist *) skip_test "link permission denied" "link" "Permission denied (link)" "Link succeeded or /root not protected" with | Unix.Unix_error ((Unix.EACCES | Unix.EPERM | Unix.EROFS | Unix.ENOENT), "link", _) as exn -> (* Expected - permission denied or /root doesn't exist *) let err_msg = match exn with | Unix.Unix_error (err, call, _) -> Printf.sprintf "%s (%s)" (Unix.error_message err) call | _ -> Printexc.to_string exn in add_test_result "link permission denied" "link" "Permission denied" err_msg "PASS") let test_symlink_nonexistent_dir _ = (* Creating symlink in nonexistent directory should raise ENOENT *) assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "symlink", "")) "symlink in nonexistent dir" (fun () -> symlink ~target:"/tmp/test" ~link_name:"/nonexistent/dir/link") let test_readlink_nonexistent _ = (* Reading nonexistent symlink should raise ENOENT *) assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "readlink", "")) "readlink on nonexistent" (fun () -> readlink "/nonexistent/symlink") let test_readlink_not_symlink _ = (* Reading a regular file with readlink should raise EINVAL *) with_temp_file (fun tmp -> assert_raises_verbose (Unix.Unix_error (Unix.EINVAL, "readlink", "")) "readlink on regular file" (fun () -> readlink tmp)) let test_unlink_nonexistent _ = (* Unlinking nonexistent file should raise ENOENT *) assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "unlink", "")) "unlink nonexistent" (fun () -> unlink "/nonexistent/file") let test_unlink_directory _ = (* Unlinking a directory should raise EPERM or EISDIR *) with_temp_dir (fun tmpdir -> try unlink tmpdir; assert_failure "Unexpected success - should have failed" with Unix.Unix_error ((Unix.EPERM | Unix.EISDIR), "unlink", _) -> ()) let test_truncate_nonexistent _ = (* Truncating nonexistent file should raise ENOENT *) assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "truncate", "")) "truncate nonexistent" (fun () -> truncate "/nonexistent/file" 0) let test_truncate_directory _ = (* Truncating a directory should raise EISDIR *) with_temp_dir (fun tmpdir -> assert_raises_verbose (Unix.Unix_error (Unix.EISDIR, "truncate", "")) "truncate directory" (fun () -> truncate tmpdir 0)) let test_chown_nonexistent _ = (* chown on nonexistent file should raise ENOENT *) let uid = getuid () in let gid = getgid () in assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "chown", "")) "chown nonexistent" (fun () -> chown "/nonexistent/file" uid gid) let test_lchown_nonexistent _ = (* lchown on nonexistent file should raise ENOENT *) let uid = getuid () in let gid = getgid () in assert_raises_verbose (Unix.Unix_error (Unix.ENOENT, "lchown", "")) "lchown nonexistent" (fun () -> lchown "/nonexistent/file" uid gid) let test_lockf_bad_fd _ = (* lockf on closed fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_verbose (Unix.Unix_error (Unix.EBADF, "lockf", "")) "lockf on bad fd" (fun () -> lockf bad_fd `Lock 0)) let suite = "File operation error tests" >::: [ "test_link_nonexistent" >:: test_link_nonexistent; "test_link_permission_denied" >:: test_link_permission_denied; "test_symlink_nonexistent_dir" >:: test_symlink_nonexistent_dir; "test_readlink_nonexistent" >:: test_readlink_nonexistent; "test_readlink_not_symlink" >:: test_readlink_not_symlink; "test_unlink_nonexistent" >:: test_unlink_nonexistent; "test_unlink_directory" >:: test_unlink_directory; "test_truncate_nonexistent" >:: test_truncate_nonexistent; "test_truncate_directory" >:: test_truncate_directory; "test_chown_nonexistent" >:: test_chown_nonexistent; "test_lchown_nonexistent" >:: test_lchown_nonexistent; "test_lockf_bad_fd" >:: test_lockf_bad_fd; ] ocaml-posix-4.0.2/modules/unistd/test/test_helpers.ml000066400000000000000000000153701515131525300227470ustar00rootroot00000000000000(** Shared helper functions for posix-unistd tests *) (* Verbose output flag - opt-out via OCAML_POSIX_NO_VERBOSE_TEST *) let verbose = try ignore (Sys.getenv "OCAML_POSIX_NO_VERBOSE_TEST"); false with Not_found -> true (* Record to store test results *) type test_result = { test_name : string; function_tested : string; expected : string; actual : string; status : string; } (* List to collect test results *) let test_results = ref [] let add_test_result test_name function_tested expected actual status = if verbose then test_results := { test_name; function_tested; expected; actual; status } :: !test_results (* Flush the test results as a table *) let flush_verbose () = if verbose && !test_results <> [] then ( let results = List.rev !test_results in (* Separate passed/failed from skipped *) let passed_failed, skipped = List.partition (fun r -> r.status <> "SKIP") results in (* Print pass/fail table *) if passed_failed <> [] then ( Printf.printf "\n=== Test Results ===\n"; let max_test_name = List.fold_left (fun acc r -> max acc (String.length r.test_name)) 10 passed_failed in let max_function = List.fold_left (fun acc r -> max acc (String.length r.function_tested)) 8 passed_failed in let max_expected = List.fold_left (fun acc r -> max acc (String.length r.expected)) 8 passed_failed in let max_actual = List.fold_left (fun acc r -> max acc (String.length r.actual)) 6 passed_failed in let max_status = 6 in let line_len = max_test_name + max_function + max_expected + max_actual + max_status + 13 in Printf.printf "%s\n" (String.make line_len '-'); Printf.printf "| %-*s | %-*s | %-*s | %-*s | %-*s |\n" max_test_name "Test Name" max_function "Function" max_expected "Expected" max_actual "Actual" max_status "Status"; Printf.printf "%s\n" (String.make line_len '-'); List.iter (fun r -> Printf.printf "| %-*s | %-*s | %-*s | %-*s | %-*s |\n" max_test_name r.test_name max_function r.function_tested max_expected r.expected max_actual r.actual max_status r.status) passed_failed; Printf.printf "%s\n%!" (String.make line_len '-')); (* Print skipped table *) if skipped <> [] then ( Printf.printf "\n=== Skipped Tests ===\n"; let max_test_name = List.fold_left (fun acc r -> max acc (String.length r.test_name)) 10 skipped in let max_function = List.fold_left (fun acc r -> max acc (String.length r.function_tested)) 8 skipped in let max_reason = List.fold_left (fun acc r -> max acc (String.length r.actual)) 6 skipped in let line_len = max_test_name + max_function + max_reason + 7 in Printf.printf "%s\n" (String.make line_len '-'); Printf.printf "| %-*s | %-*s | %-*s |\n" max_test_name "Test Name" max_function "Function" max_reason "Reason"; Printf.printf "%s\n" (String.make line_len '-'); List.iter (fun r -> Printf.printf "| %-*s | %-*s | %-*s |\n" max_test_name r.test_name max_function r.function_tested max_reason r.actual) skipped; Printf.printf "%s\n%!" (String.make line_len '-')); test_results := []) (* Helper to create temporary files *) let with_temp_file f = let tmp = Filename.temp_file "posix_unistd_test" ".tmp" in try let result = f tmp in (try Sys.remove tmp with _ -> ()); result with e -> (try Sys.remove tmp with _ -> ()); raise e (* Helper to create temporary directory *) let with_temp_dir f = let tmp = Filename.temp_file "posix_unistd_test" ".dir" in Unix.unlink tmp; Unix.mkdir tmp 0o755; try let result = f tmp in (try Unix.rmdir tmp with _ -> ()); result with e -> (try Unix.rmdir tmp with _ -> ()); raise e (* Helper to check if an exception matches an errno Errno-unix raises Unix.Unix_error, this helper verifies the errno matches *) let assert_raises_errno errno call f = let expected = Unix.error_message errno in try f (); add_test_result call call expected "No exception" "FAIL"; OUnit2.assert_failure (Printf.sprintf "Expected exception with errno %s for call %s" expected call) with Unix.Unix_error (err, c, _) -> let actual = Printf.sprintf "%s (%s)" (Unix.error_message err) c in if errno = err && call = c then add_test_result call call expected actual "PASS" else ( add_test_result call call expected actual "FAIL"; if errno <> err then OUnit2.assert_equal ~msg: (Printf.sprintf "Wrong errno (expected %s, got %s)" expected (Unix.error_message err)) errno err; if call <> c then OUnit2.assert_equal ~msg:(Printf.sprintf "Wrong call (expected %s, got %s)" call c) call c) (* Helper to skip a test and record it in the table *) let skip_test test_name function_name expected reason = add_test_result test_name function_name expected reason "SKIP"; OUnit2.skip_if true reason (* Helper to record a successful test *) let record_success test_name function_name description = add_test_result test_name function_name description "Success" "PASS" (* Wrapper for success tests *) let test_success test_name function_name description f = try f (); record_success test_name function_name description with exn -> let error_msg = Printexc.to_string exn in add_test_result test_name function_name description error_msg "FAIL"; raise exn (* Verbose wrapper for OUnit2.assert_raises *) let assert_raises_verbose expected_exn test_name f = let expected_str = match expected_exn with | Unix.Unix_error (err, call, _) -> Printf.sprintf "%s (%s)" (Unix.error_message err) call | _ -> Printexc.to_string expected_exn in let function_name = match expected_exn with | Unix.Unix_error (_, call, _) -> call | _ -> test_name in try ignore (f ()); add_test_result test_name function_name expected_str "No exception" "FAIL"; OUnit2.assert_failure (Printf.sprintf "Expected exception %s but none was raised" (Printexc.to_string expected_exn)) with exn -> let actual_str = match exn with | Unix.Unix_error (err, call, _) -> Printf.sprintf "%s (%s)" (Unix.error_message err) call | _ -> Printexc.to_string exn in if exn = expected_exn then add_test_result test_name function_name expected_str actual_str "PASS" else ( add_test_result test_name function_name expected_str actual_str "FAIL"; raise exn) ocaml-posix-4.0.2/modules/unistd/test/test_io.ml000066400000000000000000000046171515131525300217160ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_read_write _ = test_success "read/write" "read/write" "Read and write operations" (fun () -> with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in (* Write *) let msg = Bytes.of_string "Hello, World!" in let written = write fd msg 0 (Bytes.length msg) in assert_equal (Bytes.length msg) written; (* Seek back *) ignore (lseek fd 0 Seek_set); (* Read *) let buf = Bytes.create 20 in let read_count = read fd buf 0 20 in assert_equal (Bytes.length msg) read_count; assert_equal "Hello, World!" (Bytes.sub_string buf 0 (Bytes.length msg)); Unix.close fd)) let test_pread_pwrite _ = test_success "pread/pwrite" "pread/pwrite" "Positional read and write" (fun () -> with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in (* Write at offset 0 *) let msg1 = Bytes.of_string "AAAAA" in ignore (pwrite fd msg1 0 5 0); (* Write at offset 10 *) let msg2 = Bytes.of_string "BBBBB" in ignore (pwrite fd msg2 0 5 10); (* Read at offset 10 *) let buf = Bytes.create 5 in let n = pread fd buf 0 5 10 in assert_equal 5 n; assert_equal "BBBBB" (Bytes.to_string buf); (* File offset should not have changed *) let pos = lseek fd 0 Seek_cur in assert_equal 0 pos; Unix.close fd)) let test_lseek _ = test_success "lseek" "lseek" "File seek operations" (fun () -> with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in (* Write some data *) let msg = Bytes.of_string "0123456789" in ignore (write fd msg 0 10); (* Seek to beginning *) let pos = lseek fd 0 Seek_set in assert_equal 0 pos; (* Seek to end *) let pos = lseek fd 0 Seek_end in assert_equal 10 pos; (* Seek backward from current *) let pos = lseek fd (-5) Seek_cur in assert_equal 5 pos; Unix.close fd)) let suite = "I/O operation tests" >::: [ "test_read_write" >:: test_read_write; "test_pread_pwrite" >:: test_pread_pwrite; "test_lseek" >:: test_lseek; ] ocaml-posix-4.0.2/modules/unistd/test/test_io_errors.ml000066400000000000000000000074361515131525300233140ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers (* Test error handling for I/O operations *) let test_read_bad_fd _ = (* Reading from an invalid file descriptor should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; let buf = Bytes.create 10 in assert_raises_errno Unix.EBADF "read" (fun () -> ignore (read bad_fd buf 0 10))) let test_read_invalid_args _ = (* Reading with invalid offset/length should raise Invalid_argument *) with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in let buf = Bytes.create 10 in (* Negative offset *) assert_raises (Invalid_argument "read: invalid offset or length") (fun () -> read fd buf (-1) 5); (* Negative length *) assert_raises (Invalid_argument "read: invalid offset or length") (fun () -> read fd buf 0 (-1)); (* Offset + length > buffer size *) assert_raises (Invalid_argument "read: invalid offset or length") (fun () -> read fd buf 5 10); Unix.close fd) let test_write_bad_fd _ = (* Writing to an invalid file descriptor should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; let buf = Bytes.of_string "test" in assert_raises_errno Unix.EBADF "write" (fun () -> ignore (write bad_fd buf 0 4))) let test_write_invalid_args _ = (* Writing with invalid offset/length should raise Invalid_argument *) with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in let buf = Bytes.of_string "test" in (* Negative offset *) assert_raises (Invalid_argument "write: invalid offset or length") (fun () -> write fd buf (-1) 2); (* Negative length *) assert_raises (Invalid_argument "write: invalid offset or length") (fun () -> write fd buf 0 (-1)); (* Offset + length > buffer size *) assert_raises (Invalid_argument "write: invalid offset or length") (fun () -> write fd buf 3 5); Unix.close fd) let test_pread_bad_fd _ = (* pread from invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; let buf = Bytes.create 10 in assert_raises_errno Unix.EBADF "pread" (fun () -> ignore (pread bad_fd buf 0 10 0))) let test_pwrite_bad_fd _ = (* pwrite to invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; let buf = Bytes.of_string "test" in assert_raises_errno Unix.EBADF "pwrite" (fun () -> ignore (pwrite bad_fd buf 0 4 0))) let test_lseek_bad_fd _ = (* lseek on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "lseek" (fun () -> ignore (lseek bad_fd 0 Seek_set))) let test_lseek_pipe _ = (* lseek on a pipe should raise ESPIPE *) let read_fd, write_fd = pipe () in (try assert_raises (Unix.Unix_error (Unix.ESPIPE, "lseek", "")) (fun () -> lseek read_fd 0 Seek_set) with _ -> ()); close read_fd; close write_fd let suite = "I/O error tests" >::: [ "test_read_bad_fd" >:: test_read_bad_fd; "test_read_invalid_args" >:: test_read_invalid_args; "test_write_bad_fd" >:: test_write_bad_fd; "test_write_invalid_args" >:: test_write_invalid_args; "test_pread_bad_fd" >:: test_pread_bad_fd; "test_pwrite_bad_fd" >:: test_pwrite_bad_fd; "test_lseek_bad_fd" >:: test_lseek_bad_fd; "test_lseek_pipe" >:: test_lseek_pipe; ] ocaml-posix-4.0.2/modules/unistd/test/test_process.ml000066400000000000000000000071361515131525300227640ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_getpid _ = test_success "getpid" "getpid" "Get process ID" (fun () -> let pid = getpid () in assert_bool "PID should be positive" (pid > 0); (* Verify it matches Unix.getpid *) assert_equal pid (Unix.getpid ())) let test_getppid _ = test_success "getppid" "getppid" "Get parent process ID" (fun () -> let ppid = getppid () in assert_bool "Parent PID should be positive" (ppid > 0)) let test_getpgrp _ = test_success "getpgrp" "getpgrp" "Get process group" (fun () -> let pgrp = getpgrp () in assert_bool "Process group should be positive" (pgrp > 0)) let test_getuid _ = test_success "getuid" "getuid" "Get user ID" (fun () -> let uid = getuid () in assert_bool "UID should be non-negative" (uid >= 0); assert_equal uid (Unix.getuid ())) let test_geteuid _ = test_success "geteuid" "geteuid" "Get effective user ID" (fun () -> let euid = geteuid () in assert_bool "Effective UID should be non-negative" (euid >= 0); assert_equal euid (Unix.geteuid ())) let test_getgid _ = test_success "getgid" "getgid" "Get group ID" (fun () -> let gid = getgid () in assert_bool "GID should be non-negative" (gid >= 0); assert_equal gid (Unix.getgid ())) let test_getegid _ = test_success "getegid" "getegid" "Get effective group ID" (fun () -> let egid = getegid () in assert_bool "Effective GID should be non-negative" (egid >= 0); assert_equal egid (Unix.getegid ())) let test_getgroups _ = test_success "getgroups" "getgroups" "Get supplementary groups" (fun () -> let groups = getgroups () in assert_bool "Should have at least one group" (List.length groups > 0); List.iter (fun gid -> assert_bool "Group ID should be non-negative" (gid >= 0)) groups) let test_sleep _ = test_success "sleep" "sleep" "Sleep for seconds" (fun () -> (* Sleep for 0 seconds should return immediately *) let remaining = sleep 0 in assert_equal 0 remaining) let test_alarm _ = test_success "alarm" "alarm" "Set alarm timer" (fun () -> (* Set alarm to 0 should cancel any previous alarm *) let _ = alarm 0 in (* Set and immediately cancel *) ignore (alarm 10); let remaining = alarm 0 in assert_bool "Should have had time remaining" (remaining > 0)) let test_usleep _ = test_success "usleep" "usleep" "Sleep for microseconds" (fun () -> (* Sleep for 1 microsecond *) usleep 1; (* Just verify it doesn't raise an exception *) assert_bool "usleep should complete" true) let test_getpgid _ = test_success "getpgid" "getpgid" "Get process group ID" (fun () -> let pid = getpid () in let pgid = getpgid pid in assert_bool "Process group ID should be positive" (pgid > 0)) let test_getsid _ = test_success "getsid" "getsid" "Get session ID" (fun () -> let pid = getpid () in let sid = getsid pid in assert_bool "Session ID should be positive" (sid > 0)) let suite = "Process and user/group tests" >::: [ "test_getpid" >:: test_getpid; "test_getppid" >:: test_getppid; "test_getpgrp" >:: test_getpgrp; "test_getuid" >:: test_getuid; "test_geteuid" >:: test_geteuid; "test_getgid" >:: test_getgid; "test_getegid" >:: test_getegid; "test_getgroups" >:: test_getgroups; "test_sleep" >:: test_sleep; "test_alarm" >:: test_alarm; "test_usleep" >:: test_usleep; "test_getpgid" >:: test_getpgid; "test_getsid" >:: test_getsid; ] ocaml-posix-4.0.2/modules/unistd/test/test_process_errors.ml000066400000000000000000000130061515131525300243510ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers (* Test error handling for process operations *) let test_getpgid_nonexistent _ = (* Getting process group of nonexistent process should raise ESRCH *) (* Use a very high PID that's unlikely to exist *) let nonexistent_pid = 999999 in assert_raises_verbose (Unix.Unix_error (Unix.ESRCH, "getpgid", "")) "getpgid nonexistent" (fun () -> ignore (getpgid nonexistent_pid)) let test_getsid_nonexistent _ = (* Getting session ID of nonexistent process should raise ESRCH *) let nonexistent_pid = 999999 in assert_raises_verbose (Unix.Unix_error (Unix.ESRCH, "getsid", "")) "getsid nonexistent" (fun () -> ignore (getsid nonexistent_pid)) let test_setpgid_nonexistent _ = (* Setting process group of nonexistent process should raise ESRCH *) let nonexistent_pid = 999999 in assert_raises_verbose (Unix.Unix_error (Unix.ESRCH, "setpgid", "")) "setpgid nonexistent" (fun () -> setpgid nonexistent_pid 0) let test_sysconf_invalid _ = (* sysconf with invalid name returns -1 without raising *) let invalid_name = -999999 in let result = sysconf invalid_name in (* sysconf returns -1 for invalid/unlimited, doesn't check errno *) assert_equal (-1) result let test_confstr_invalid _ = (* confstr with invalid name returns -1 without raising *) let invalid_name = -999999 in try let result = confstr invalid_name in (* confstr returns empty string for size 0 *) assert_equal "" result with _ -> (* Or it might fail, which is fine *) () let test_nice_eperm _ = (* Trying to increase priority (nice with negative value) as non-root should raise EPERM *) (* Only test if not running as root *) if getuid () = 0 then skip_test "nice with negative" "nice" "Operation not permitted (nice)" "Running as root" else ( try let _ = nice (-10) in skip_test "nice with negative" "nice" "Operation not permitted (nice)" "System allows priority increase" with Unix.Unix_error (Unix.EPERM, "nice", "") -> add_test_result "nice with negative" "nice" "Operation not permitted (nice)" "Operation not permitted (nice)" "PASS") let test_setuid_eperm _ = (* Setting uid as non-root should raise EPERM (unless setting to same uid) *) if getuid () = 0 then skip_test "setuid to root" "setuid" "Operation not permitted (setuid)" "Running as root" else ( assert_raises_verbose (Unix.Unix_error (Unix.EPERM, "setuid", "")) "setuid to root" (fun () -> setuid 0); (* Setting to same uid should succeed *) setuid (getuid ())) let test_setgid_eperm _ = (* Setting gid as non-root should raise EPERM (unless setting to same gid) *) if getuid () = 0 then skip_test "setgid to root" "setgid" "Operation not permitted (setgid)" "Running as root" else ( assert_raises_verbose (Unix.Unix_error (Unix.EPERM, "setgid", "")) "setgid to root" (fun () -> setgid 0); (* Setting to same gid should succeed *) setgid (getgid ())) let test_setgroups_eperm _ = (* setgroups as non-root should raise EPERM *) if getuid () = 0 then skip_test "setgroups as non-root" "setgroups" "Operation not permitted (setgroups)" "Running as root" else assert_raises_verbose (Unix.Unix_error (Unix.EPERM, "setgroups", "")) "setgroups as non-root" (fun () -> setgroups [0]) let test_seteuid_eperm _ = (* Setting euid as non-root should raise EPERM *) if getuid () = 0 then skip_test "seteuid to root" "seteuid" "Operation not permitted (seteuid)" "Running as root" else assert_raises_verbose (Unix.Unix_error (Unix.EPERM, "seteuid", "")) "seteuid to root" (fun () -> seteuid 0) let test_setegid_eperm _ = (* Setting egid as non-root should raise EPERM *) if getuid () = 0 then skip_test "setegid to root" "setegid" "Operation not permitted (setegid)" "Running as root" else assert_raises_verbose (Unix.Unix_error (Unix.EPERM, "setegid", "")) "setegid to root" (fun () -> setegid 0) let test_setreuid_eperm _ = (* Setting reuid as non-root should raise EPERM *) if getuid () = 0 then skip_test "setreuid to root" "setreuid" "Operation not permitted (setreuid)" "Running as root" else assert_raises_verbose (Unix.Unix_error (Unix.EPERM, "setreuid", "")) "setreuid to root" (fun () -> setreuid 0 0) let test_setregid_eperm _ = (* Setting regid as non-root should raise EPERM *) if getuid () = 0 then skip_test "setregid to root" "setregid" "Operation not permitted (setregid)" "Running as root" else assert_raises_verbose (Unix.Unix_error (Unix.EPERM, "setregid", "")) "setregid to root" (fun () -> setregid 0 0) let suite = "Process operation error tests" >::: [ "test_getpgid_nonexistent" >:: test_getpgid_nonexistent; "test_getsid_nonexistent" >:: test_getsid_nonexistent; "test_setpgid_nonexistent" >:: test_setpgid_nonexistent; "test_sysconf_invalid" >:: test_sysconf_invalid; "test_confstr_invalid" >:: test_confstr_invalid; "test_nice_eperm" >:: test_nice_eperm; "test_setuid_eperm" >:: test_setuid_eperm; "test_setgid_eperm" >:: test_setgid_eperm; "test_setgroups_eperm" >:: test_setgroups_eperm; "test_seteuid_eperm" >:: test_seteuid_eperm; "test_setegid_eperm" >:: test_setegid_eperm; "test_setreuid_eperm" >:: test_setreuid_eperm; "test_setregid_eperm" >:: test_setregid_eperm; ] ocaml-posix-4.0.2/modules/unistd/test/test_sync.ml000066400000000000000000000022071515131525300222540ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_fsync _ = test_success "fsync" "fsync" "Sync file to disk" (fun () -> with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in (* Write data *) let msg = Bytes.of_string "sync test" in ignore (write fd msg 0 (Bytes.length msg)); (* Sync *) fsync fd; Unix.close fd)) let test_fdatasync _ = test_success "fdatasync" "fdatasync" "Sync file data to disk" (fun () -> with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in (* Write data *) let msg = Bytes.of_string "datasync test" in ignore (write fd msg 0 (Bytes.length msg)); (* Sync data *) fdatasync fd; Unix.close fd)) let test_sync_all _ = test_success "sync" "sync" "Sync all filesystems" (fun () -> (* Just ensure it doesn't crash *) sync ()) let suite = "Synchronization tests" >::: [ "test_fsync" >:: test_fsync; "test_fdatasync" >:: test_fdatasync; "test_sync_all" >:: test_sync_all; ] ocaml-posix-4.0.2/modules/unistd/test/test_sysinfo.ml000066400000000000000000000055371515131525300230030ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_sysconf _ = test_success "sysconf" "sysconf" "Get system configuration" (fun () -> (* Test pagesize *) let size = sysconf sc_pagesize in assert_bool "Page size should be positive" (size > 0); assert_bool "Page size should be a power of 2" (size land (size - 1) = 0); (* Test open_max - can be -1 (unlimited) or a positive value *) let max = sysconf sc_open_max in assert_bool "Open max should be -1 or positive" (max = -1 || max > 0)) let test_pathconf _ = test_success "pathconf" "pathconf" "Get path configuration" (fun () -> with_temp_file (fun tmp -> let max = pathconf tmp pc_name_max in assert_bool "Name max should be positive" (max > 0))) let test_confstr _ = test_success "confstr" "confstr" "Get configuration string" (fun () -> let path = confstr cs_path in assert_bool "PATH should not be empty" (String.length path > 0)) let test_getpagesize _ = test_success "getpagesize" "getpagesize" "Get system page size" (fun () -> let pagesize = getpagesize () in assert_bool "Page size should be positive" (pagesize > 0); assert_bool "Page size should be power of 2" (pagesize land (pagesize - 1) = 0)) let test_gethostname _ = test_success "gethostname" "gethostname" "Get hostname" (fun () -> let hostname = gethostname () in assert_bool "Hostname should not be empty" (String.length hostname > 0)) let test_gethostid _ = test_success "gethostid" "gethostid" "Get host ID" (fun () -> let hostid = gethostid () in (* Just verify we can call it *) ignore hostid) let skip_login = try ignore (getlogin ()); false with _ -> true let test_getlogin _ = if skip_login then skip_test "getlogin" "getlogin" "Get login name" "getlogin not available in this environment" else test_success "getlogin" "getlogin" "Get login name" (fun () -> let login = getlogin () in assert_bool "Login name should not be empty" (String.length login > 0)) let test_getlogin_r _ = if skip_login then skip_test "getlogin_r" "getlogin_r" "Get login name (reentrant)" "getlogin_r not available in this environment" else test_success "getlogin_r" "getlogin_r" "Get login name (reentrant)" (fun () -> let login = getlogin_r () in assert_bool "Login name should not be empty" (String.length login > 0)) let suite = "System configuration and info tests" >::: [ "test_sysconf" >:: test_sysconf; "test_pathconf" >:: test_pathconf; "test_confstr" >:: test_confstr; "test_getpagesize" >:: test_getpagesize; "test_gethostname" >:: test_gethostname; "test_gethostid" >:: test_gethostid; "test_getlogin" >:: test_getlogin; "test_getlogin_r" >:: test_getlogin_r; ] ocaml-posix-4.0.2/modules/unistd/test/test_sysinfo_errors.ml000066400000000000000000000023321515131525300243650ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers (* Test error handling for system info operations *) let sethostname_eperm_error = if Config.system = "gnu" then Unix.EACCES else Unix.EPERM let test_sethostname_eperm _ = (* sethostname as non-root should raise EPERM *) if getuid () = 0 then skip_test "sethostname as non-root" "sethostname" "Operation not permitted (sethostname)" "Running as root" else assert_raises_verbose (Unix.Unix_error (sethostname_eperm_error, "sethostname", "")) "sethostname as non-root" (fun () -> sethostname "testhostname") let test_getlogin_r_small_buffer _ = (* getlogin_r with too small buffer should raise ERANGE *) try let _ = getlogin_r ~len:1 () in (* May succeed with very short login names *) () with | Unix.Unix_error (Unix.ERANGE, "getlogin_r", "") -> (* Expected for most cases *) () | Unix.Unix_error (Unix.ENOTTY, "getlogin_r", "") -> (* Expected in containerized/non-TTY environments *) () let suite = "System info error tests" >::: [ "test_sethostname_eperm" >:: test_sethostname_eperm; "test_getlogin_r_small_buffer" >:: test_getlogin_r_small_buffer; ] ocaml-posix-4.0.2/modules/unistd/test/test_terminal.ml000066400000000000000000000041461515131525300231170ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers let test_isatty _ = test_success "isatty" "isatty" "Check if fd is a terminal" (fun () -> (* stdin/stdout/stderr might or might not be a tty depending on how tests run *) let _ = isatty Unix.stdin in let _ = isatty Unix.stdout in let _ = isatty Unix.stderr in (* A regular file is definitely not a tty *) with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in assert_bool "Regular file should not be a tty" (not (isatty fd)); Unix.close fd)) let test_ttyname _ = (* Skip if stdin is not a tty *) if not (isatty Unix.stdin) then skip_test "ttyname" "ttyname" "Get terminal name" "stdin is not a tty" else ( try test_success "ttyname" "ttyname" "Get terminal name" (fun () -> let name = ttyname Unix.stdin in assert_bool "tty name should not be empty" (String.length name > 0)) with _ -> skip_test "ttyname" "ttyname" "Get terminal name" "ttyname not available") let test_ttyname_r _ = (* Skip if stdin is not a tty *) if not (isatty Unix.stdin) then skip_test "ttyname_r" "ttyname_r" "Get terminal name (reentrant)" "stdin is not a tty" else ( try test_success "ttyname_r" "ttyname_r" "Get terminal name (reentrant)" (fun () -> let name = ttyname_r Unix.stdin in assert_bool "tty name should not be empty" (String.length name > 0)) with _ -> skip_test "ttyname_r" "ttyname_r" "Get terminal name (reentrant)" "ttyname_r not available") let test_ctermid _ = try test_success "ctermid" "ctermid" "Get controlling terminal ID" (fun () -> let name = ctermid () in assert_bool "ctermid should return a name" (String.length name > 0)) with _ -> skip_test "ctermid" "ctermid" "Get controlling terminal ID" "ctermid not available" let suite = "Terminal operation tests" >::: [ "test_isatty" >:: test_isatty; "test_ttyname" >:: test_ttyname; "test_ttyname_r" >:: test_ttyname_r; "test_ctermid" >:: test_ctermid; ] ocaml-posix-4.0.2/modules/unistd/test/test_terminal_errors.ml000066400000000000000000000056201515131525300245110ustar00rootroot00000000000000open OUnit2 open Posix_unistd open Test_helpers (* Test error handling for terminal operations *) let test_ttyname_not_tty _ = (* ttyname on non-tty fd should raise ENOTTY *) with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in assert_raises_verbose (Unix.Unix_error (Unix.ENOTTY, "ttyname", "")) "ttyname on non-tty" (fun () -> ignore (ttyname fd)); Unix.close fd) let test_ttyname_bad_fd _ = (* ttyname on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_verbose (Unix.Unix_error (Unix.EBADF, "ttyname", "")) "ttyname on bad fd" (fun () -> ignore (ttyname bad_fd))) let test_ttyname_r_not_tty _ = (* ttyname_r on non-tty fd should raise ENOTTY *) with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in assert_raises_verbose (Unix.Unix_error (Unix.ENOTTY, "ttyname_r", "")) "ttyname_r on non-tty" (fun () -> ignore (ttyname_r fd)); Unix.close fd) let test_tcgetpgrp_not_tty _ = (* tcgetpgrp on non-tty fd should raise ENOTTY *) with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in assert_raises_verbose (Unix.Unix_error (Unix.ENOTTY, "tcgetpgrp", "")) "tcgetpgrp on non-tty" (fun () -> ignore (tcgetpgrp fd)); Unix.close fd) let test_tcgetpgrp_bad_fd _ = (* tcgetpgrp on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; assert_raises_errno Unix.EBADF "tcgetpgrp" (fun () -> ignore (tcgetpgrp bad_fd))) let test_tcsetpgrp_not_tty _ = (* tcsetpgrp on non-tty fd should raise ENOTTY *) with_temp_file (fun tmp -> let fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in let pgrp = getpgrp () in assert_raises_verbose (Unix.Unix_error (Unix.ENOTTY, "tcsetpgrp", "")) "tcsetpgrp on non-tty" (fun () -> tcsetpgrp fd pgrp); Unix.close fd) let test_tcsetpgrp_bad_fd _ = (* tcsetpgrp on invalid fd should raise EBADF *) with_temp_file (fun tmp -> let bad_fd = Unix.openfile tmp [Unix.O_RDWR] 0o644 in Unix.close bad_fd; let pgrp = getpgrp () in assert_raises_errno Unix.EBADF "tcsetpgrp" (fun () -> tcsetpgrp bad_fd pgrp)) let suite = "Terminal operation error tests" >::: [ "test_ttyname_not_tty" >:: test_ttyname_not_tty; "test_ttyname_bad_fd" >:: test_ttyname_bad_fd; "test_ttyname_r_not_tty" >:: test_ttyname_r_not_tty; "test_tcgetpgrp_not_tty" >:: test_tcgetpgrp_not_tty; "test_tcgetpgrp_bad_fd" >:: test_tcgetpgrp_bad_fd; "test_tcsetpgrp_not_tty" >:: test_tcsetpgrp_not_tty; "test_tcsetpgrp_bad_fd" >:: test_tcsetpgrp_bad_fd; ] ocaml-posix-4.0.2/opam/000077500000000000000000000000001515131525300147055ustar00rootroot00000000000000ocaml-posix-4.0.2/opam/posix-base.opam000066400000000000000000000014451515131525300176410ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Base module for the posix bindings" description: "posix-base provides base tools for the posix binding modules." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ocaml" {>= "4.08"} "integers" {>= "0.3.0"} "ctypes" {>= "0.24.0"} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] ocaml-posix-4.0.2/opam/posix-bindings.opam000066400000000000000000000015321515131525300205210ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "POSIX bindings" description: "install all available posix bindings" maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "posix-types" "posix-socket" "posix-socket-unix" "posix-time2" "posix-unistd" "posix-uname" "posix-math2" "posix-getopt" "posix-stat" "posix-resource" "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] ocaml-posix-4.0.2/opam/posix-errno.opam000066400000000000000000000014311515131525300200470ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "POSIX errno handling and Unix error conversion" description: "posix-errno provides comprehensive errno handling." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ocaml" {>= "4.08"} "posix-base" {= version} "ctypes" "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] ocaml-posix-4.0.2/opam/posix-getopt.opam000066400000000000000000000017511515131525300202310ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix getopt/getopt_long" description: "posix-getopt provides a simple interface for the POSIX getopt and its extensions, getopt_long and getopt_long_only." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "dune-configurator" "ounit2" {with-test} "lwt" {with-test} "posix-uname" {with-test & = version} "ctypes" "posix-base" {= version} "posix-errno" {= version} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] available: os != "win32" & os != "bsd" ocaml-posix-4.0.2/opam/posix-getopt.opam.template000066400000000000000000000000471515131525300220400ustar00rootroot00000000000000available: os != "win32" & os != "bsd" ocaml-posix-4.0.2/opam/posix-math2.opam000066400000000000000000000013751515131525300177440ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix math" description: "posix-math2 provides a simple interface for POSIX math functions." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ctypes" "posix-base" {= version} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] ocaml-posix-4.0.2/opam/posix-resource.opam000066400000000000000000000016071515131525300205560ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix resource limits and usage" description: "posix-resource provides types and bindings for POSIX sys/resource.h APIs." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ctypes" "posix-base" {= version} "posix-types" {= version} "posix-time2" {= version} "posix-errno" {= version} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] available: os != "win32" ocaml-posix-4.0.2/opam/posix-resource.opam.template000066400000000000000000000000311515131525300223560ustar00rootroot00000000000000available: os != "win32" ocaml-posix-4.0.2/opam/posix-signal.opam000066400000000000000000000015221515131525300202000ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for the types defined in " description: "posix-signal provides an API to the types and bindings defined in " maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "posix-base" {= version} "posix-errno" {= version} "ctypes" "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] available: os != "win32" ocaml-posix-4.0.2/opam/posix-signal.opam.template000066400000000000000000000000311515131525300220040ustar00rootroot00000000000000available: os != "win32" ocaml-posix-4.0.2/opam/posix-socket-unix.opam000066400000000000000000000015371515131525300212020ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix sockets" description: "posix-socket-unix provides unix-specific types and bindings for posix sockets." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ctypes" "posix-base" {= version} "posix-socket" {= version} "posix-errno" {= version} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] available: os != "win32" ocaml-posix-4.0.2/opam/posix-socket-unix.opam.template000066400000000000000000000000311515131525300230000ustar00rootroot00000000000000available: os != "win32" ocaml-posix-4.0.2/opam/posix-socket.opam000066400000000000000000000015211515131525300202120ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix sockets" description: "posix-socket provides the types and bindings of posix sockets APIs available on both unix and windows." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ocaml" {>= "4.12"} "dune-configurator" "posix-base" {= version} "ctypes" "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] ocaml-posix-4.0.2/opam/posix-stat.opam000066400000000000000000000015521515131525300177010ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix stat" description: "posix-stat provides types and bindings for POSIX sys/stat.h APIs." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ctypes" "posix-base" {= version} "posix-types" {= version} "posix-time2" {= version} "posix-errno" {= version} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] available: os != "win32" ocaml-posix-4.0.2/opam/posix-stat.opam.template000066400000000000000000000000311515131525300215020ustar00rootroot00000000000000available: os != "win32" ocaml-posix-4.0.2/opam/posix-time2.opam000066400000000000000000000015271515131525300177500ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix time functions" description: "posix-time2 provides the types and bindings for posix time APIs." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ctypes" "posix-base" {= version} "posix-types" {= version} "posix-errno" {= version} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] available: os != "win32" ocaml-posix-4.0.2/opam/posix-time2.opam.template000066400000000000000000000000311515131525300215470ustar00rootroot00000000000000available: os != "win32" ocaml-posix-4.0.2/opam/posix-types.opam000066400000000000000000000015041515131525300200670ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for the types defined in " description: "posix-types provides an API to the types defined in " maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ocaml" {>= "4.03"} "posix-base" {= version} "ctypes" "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] available: os != "win32" ocaml-posix-4.0.2/opam/posix-types.opam.template000066400000000000000000000000311515131525300216730ustar00rootroot00000000000000available: os != "win32" ocaml-posix-4.0.2/opam/posix-uname.opam000066400000000000000000000014501515131525300200300ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix uname" description: "posix-uname provides a simple interface for POSIX uname." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ctypes" "posix-base" {= version} "posix-errno" {= version} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"] available: os != "win32" ocaml-posix-4.0.2/opam/posix-uname.opam.template000066400000000000000000000000311515131525300216340ustar00rootroot00000000000000available: os != "win32" ocaml-posix-4.0.2/opam/posix-unistd.opam000066400000000000000000000015211515131525300202300ustar00rootroot00000000000000# This file is generated by dune, edit dune-project instead opam-version: "2.0" version: "4.0.2" synopsis: "Bindings for posix unistd.h functions" description: "posix-unistd provides comprehensive OCaml bindings to POSIX unistd.h functions." maintainer: ["romain.beauxis@gmail.com"] authors: ["Romain Beauxis"] license: "MIT" homepage: "https://github.com/savonet/ocaml-posix" bug-reports: "https://github.com/savonet/ocaml-posix/issues" depends: [ "dune" {>= "3.20"} "ctypes" "posix-base" {= version} "posix-types" {= version} "posix-errno" {= version} "odoc" {with-doc} ] build: [ ["dune" "subst"] {dev} [ "dune" "build" "-p" name "-j" jobs "@install" "@runtest" {with-test} "@doc" {with-doc} ] ] dev-repo: "git+https://github.com/savonet/ocaml-posix.git" x-maintenance-intent: ["(latest)"]