rlimit-0.8.3/.cargo_vcs_info.json0000644000000001360000000000100123440ustar { "git": { "sha1": "bb3d058f87172e0f1f9ae36e440644f210b47c59" }, "path_in_vcs": "" }rlimit-0.8.3/.github/dependabot.yml000064400000000000000000000007700072674642500153600ustar 00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "cargo" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" rlimit-0.8.3/.github/workflows/ci.yml000064400000000000000000000201760072674642500157050ustar 00000000000000on: push: branches: - master pull_request: branches: - master schedule: # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#onschedule - cron: '0 0 * * 0' # at midnight of each sunday name: CI jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - uses: actions-rs/cargo@v1 with: command: check fmt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - run: rustup component add rustfmt - uses: actions-rs/cargo@v1 with: command: fmt args: --all -- --check clippy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - run: rustup component add clippy - uses: actions-rs/cargo@v1 with: command: clippy args: -- -D warnings ubuntu: runs-on: ubuntu-latest strategy: fail-fast: false matrix: target: # copied from `rustup target list` # - aarch64-apple-darwin # (build error) # - aarch64-apple-ios # (build error) # - aarch64-apple-ios-sim # (build error) # - aarch64-fuchsia # (fuchsia does not have [sg]etrlimit) - aarch64-linux-android # - aarch64-pc-windows-msvc # (missing docker image) - aarch64-unknown-linux-gnu - aarch64-unknown-linux-musl # - aarch64-unknown-none # (no std) # - aarch64-unknown-none-softfloat # (no std) - arm-linux-androideabi - arm-unknown-linux-gnueabi # (libc mismatch) - arm-unknown-linux-gnueabihf # (libc mismatch) - arm-unknown-linux-musleabi - arm-unknown-linux-musleabihf # - armebv7r-none-eabi # (no std) # - armebv7r-none-eabihf # (no std) - armv5te-unknown-linux-gnueabi # (libc mismatch) - armv5te-unknown-linux-musleabi - armv7-linux-androideabi # - armv7-unknown-linux-gnueabi # (missing docker image) - armv7-unknown-linux-gnueabihf # (libc mismatch) # - armv7-unknown-linux-musleabi # (missing docker image) - armv7-unknown-linux-musleabihf # - armv7a-none-eabi # (no std) # - armv7r-none-eabi # (no std) # - armv7r-none-eabihf # (no std) # - asmjs-unknown-emscripten # (build error) # - i586-pc-windows-msvc # (missing docker image) - i586-unknown-linux-gnu # (libc mismatch) - i586-unknown-linux-musl - i686-linux-android # - i686-pc-windows-gnu # (missing docker image) # - i686-pc-windows-msvc # (missing docker image) # - i686-unknown-freebsd # (missing docker image) - i686-unknown-linux-gnu # (libc mismatch) - i686-unknown-linux-musl - mips-unknown-linux-gnu # (libc mismatch) - mips-unknown-linux-musl - mips64-unknown-linux-gnuabi64 # - mips64-unknown-linux-muslabi64 # (missing docker image) - mips64el-unknown-linux-gnuabi64 # - mips64el-unknown-linux-muslabi64 # (missing docker image) - mipsel-unknown-linux-gnu # (libc mismatch) - mipsel-unknown-linux-musl # - nvptx64-nvidia-cuda # (no std) - powerpc-unknown-linux-gnu # (libc mismatch) # - powerpc64-unknown-linux-gnu # (missing docker image) - powerpc64le-unknown-linux-gnu # - riscv32i-unknown-none-elf # (no std) # - riscv32imac-unknown-none-elf # (no std) # - riscv32imc-unknown-none-elf # (no std) - riscv64gc-unknown-linux-gnu # - riscv64gc-unknown-none-elf # (no std) # - riscv64imac-unknown-none-elf # (no std) - s390x-unknown-linux-gnu # - sparc64-unknown-linux-gnu # (missing docker image) # - sparcv9-sun-solaris # (build error) # - thumbv6m-none-eabi # (no std) # - thumbv7em-none-eabi # (no std) # - thumbv7em-none-eabihf # (no std) # - thumbv7m-none-eabi # (no std) # - thumbv7neon-linux-androideabi # (missing docker image) # - thumbv7neon-unknown-linux-gnueabihf # (missing docker image) # - thumbv8m.base-none-eabi # (no std) # - thumbv8m.main-none-eabi # (no std) # - thumbv8m.main-none-eabihf # (no std) # - wasm32-unknown-emscripten # (build error) # - wasm32-unknown-unknown # (tester error) # - wasm32-wasi # (tester error) # - x86_64-apple-darwin # (build error) # - x86_64-apple-ios # (build error) # - x86_64-fortanix-unknown-sgx # (tester error) # - x86_64-fuchsia # (fuchsia does not have [sg]etrlimit) - x86_64-linux-android # - x86_64-pc-solaris # (missing docker image) # - x86_64-pc-windows-gnu # (other) # - x86_64-pc-windows-msvc # (missing docker image) # - x86_64-sun-solaris # (build error) # - x86_64-unknown-freebsd # (missing docker image) # - x86_64-unknown-illumos # (build error) - x86_64-unknown-linux-gnu # - x86_64-unknown-linux-gnux32 # (missing docker image) - x86_64-unknown-linux-musl # - x86_64-unknown-netbsd # (tester error) # - x86_64-unknown-redox # (nightly) steps: - uses: actions/checkout@v2 - run: | # workaround ls -al ~/.cargo/bin set +e rm ~/.cargo/bin/rustfmt rm ~/.cargo/bin/cargo-fmt - uses: actions-rs/toolchain@v1 with: toolchain: stable target: ${{ matrix.target }} components: rustfmt override: true - uses: actions-rs/cargo@v1 with: use-cross: true command: test args: --all-features --target=${{ matrix.target }} -- --test-threads=1 macos: runs-on: macos-latest strategy: fail-fast: false matrix: target: - x86_64-apple-darwin steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable target: ${{ matrix.target }} override: true - uses: actions-rs/cargo@v1 with: command: test args: --all-features --target=${{ matrix.target }} -- --test-threads=1 windows: runs-on: windows-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable - uses: actions-rs/cargo@v1 with: command: test args: --all-features -- --test-threads=1 diff-codegen: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable - uses: actions-rs/cargo@v1 with: command: install args: ripgrep - name: diff run: | cp src/bindings.rs bindings.rs ./scripts/codegen.sh diff src/bindings.rs bindings.rs rlimit-0.8.3/.gitignore000064400000000000000000000000740072674642500131550ustar 00000000000000/target **/*.rs.bk /Cargo.lock /.vscode /libc __pycache__ rlimit-0.8.3/CHANGELOG.md000064400000000000000000000044620072674642500130030ustar 00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] [Unreleased]: https://github.com/Nugine/rlimit/v0.8.3...HEAD ## [0.8.3] - 2022-04-06 [0.8.3]: https://github.com/Nugine/rlimit/compare/v0.8.2...v0.8.3 [PR #43](https://github.com/Nugine/rlimit/pull/43): Downgrade MSRV ## [0.8.2] - 2022-04-06 [0.8.2]: https://github.com/Nugine/rlimit/compare/v0.8.1...v0.8.2 rlimit v0.8.2 uses libc definitions again instead of incorrect custom bindings. rlimit v0.8.0 and v0.8.1 are yanked now. ## [0.8.1] - 2022-04-01 [0.8.1]: https://github.com/Nugine/rlimit/compare/v0.8.0...v0.8.1 [PR #36](https://github.com/Nugine/rlimit/pull/36): Fix the bindings for aarch64-apple-darwin. ## [0.8.0] - 2022-03-31 [0.8.0]: https://github.com/Nugine/rlimit/compare/v0.7.0...v0.8.0 rlimit v0.8.0 uses custom ffi bindings instead of libc for rlimit symbols and constants. The custom bindings are kept in sync with system headers automatically. All resource constants are available on all unix platforms. Passing an unsupported resource to `[set|get|p]rlimit` will result in a custom IO error. ### Added + `Resource::is_supported` ### Changed + `Resource::as_raw` is a private method now. ### Removed + `Resource::available_names` + `Resource::available_resources` + `RawResource` ## [0.7.0] - 2022-02-13 [0.7.0]: https://github.com/Nugine/rlimit/compare/v0.6.2...v0.7.0 ### Added + Windows support + [rlimit::getmaxstdio](https://docs.rs/rlimit/0.7.0/rlimit/fn.getmaxstdio.html) + [rlimit::setmaxstdio](https://docs.rs/rlimit/0.7.0/rlimit/fn.stdmaxstdio.html) ### Changed + [rlimit::utils::increase_nofile_limit] in v0.6.2 has been moved to [rlimit::increase_nofile_limit]. [rlimit::utils::increase_nofile_limit]: https://docs.rs/rlimit/0.6.2/rlimit/utils/fn.increase_nofile_limit.html [rlimit::increase_nofile_limit]: https://docs.rs/rlimit/0.7.0/rlimit/fn.increase_nofile_limit.html ### Removed + [rlimit::utils::get_kern_max_files_per_proc] has been removed from public interfaces. [rlimit::utils::get_kern_max_files_per_proc]: https://docs.rs/rlimit/0.6.2/x86_64-apple-darwin/rlimit/utils/fn.get_kern_max_files_per_proc.html rlimit-0.8.3/Cargo.lock0000644000000005600000000000100103200ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "libc" version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" [[package]] name = "rlimit" version = "0.8.3" dependencies = [ "libc", ] rlimit-0.8.3/Cargo.toml0000644000000016270000000000100103500ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "rlimit" version = "0.8.3" authors = ["Nugine "] description = "Resource limits" documentation = "https://docs.rs/rlimit" readme = "README.md" keywords = ["rlimit", "unix", "syscall"] categories = ["os::unix-apis"] license = "MIT" repository = "https://github.com/Nugine/rlimit/" [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies.libc] version = "0.2" rlimit-0.8.3/Cargo.toml.orig000064400000000000000000000006760072674642500140640ustar 00000000000000[package] name = "rlimit" version = "0.8.3" authors = ["Nugine "] edition = "2018" description = "Resource limits" repository = "https://github.com/Nugine/rlimit/" license = "MIT" readme = "README.md" keywords = ["rlimit", "unix", "syscall"] categories = ["os::unix-apis"] documentation = "https://docs.rs/rlimit" [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] libc = "0.2" rlimit-0.8.3/LICENSE000064400000000000000000000020470072674642500121740ustar 00000000000000MIT License Copyright (c) 2019 Nugine 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. rlimit-0.8.3/README.md000064400000000000000000000006010072674642500124400ustar 00000000000000# rlimit [![Latest Version]][crates.io] [![Documentation]][docs.rs] ![License] Resource limits. [crates.io]: https://crates.io/crates/rlimit [Latest Version]: https://img.shields.io/crates/v/rlimit.svg [Documentation]: https://docs.rs/rlimit/badge.svg [docs.rs]: https://docs.rs/rlimit [License]: https://img.shields.io/crates/l/rlimit.svg Documentation: rlimit-0.8.3/examples/nofile.rs000064400000000000000000000020670072674642500146310ustar 00000000000000#[cfg(unix)] mod unix_limits { use std::cmp; use std::io; use rlimit::Resource; const DEFAULT_NOFILE_LIMIT: u64 = 16384; // or another number /// Try to increase NOFILE limit and return the current soft limit. pub fn increase_nofile_limit() -> io::Result { let (soft, hard) = Resource::NOFILE.get()?; println!("Before increasing: soft = {}, hard = {}", soft, hard); let target = cmp::min(DEFAULT_NOFILE_LIMIT, hard); println!("Try to increase: target = {}", target); Resource::NOFILE.set(target, hard)?; let (soft, hard) = Resource::NOFILE.get()?; println!("After increasing: soft = {}, hard = {}", soft, hard); Ok(soft) } } fn main() { #[cfg(unix)] { match unix_limits::increase_nofile_limit() { Ok(soft) => println!("NOFILE limit: soft = {}", soft), Err(err) => println!("Failed to increase NOFILE limit: {}", err), } } #[cfg(not(unix))] { println!("Do nothing on non-Unix systems"); } } rlimit-0.8.3/justfile000064400000000000000000000006170072674642500127400ustar 00000000000000# https://github.com/casey/just fmt: cargo fmt --all check: fmt cargo check cargo clippy -- -D warnings test: check cargo test --all-features -- --test-threads=1 --nocapture cargo run --example nofile doc: RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --no-deps --open --all-features codegen: #!/bin/bash -e cd {{justfile_directory()}} ./scripts/codegen.sh rlimit-0.8.3/scripts/codegen.py000064400000000000000000000133210072674642500146310ustar 00000000000000from typing import Optional, Dict, List import json import os import re from pprint import pprint LIBC_REPO_PATH = os.getenv("LIBC_REPO_PATH", "libc") PREDICATES = { "fuchsia/mod.rs": {"os": ["fuchsia"]}, "unix/bsd/apple/mod.rs": {"os": ["macos", "ios"]}, "unix/bsd/freebsdlike/dragonfly/mod.rs": {"os": ["dragonfly"]}, "unix/bsd/freebsdlike/freebsd/mod.rs": {"os": ["freebsd"]}, "unix/bsd/freebsdlike/mod.rs": {"os": ["freebsd", "dragonfly"]}, "unix/bsd/netbsdlike/mod.rs": {"os": ["openbsd", "netbsd"]}, "unix/bsd/netbsdlike/netbsd/mod.rs": {"os": ["netbsd"]}, "unix/haiku/mod.rs": {"os": ["haiku"]}, "unix/linux_like/android/mod.rs": {"os": ["android"]}, "unix/linux_like/emscripten/mod.rs": {"os": ["emscripten"]}, "unix/linux_like/linux/arch/generic/mod.rs": {"os": ["linux"]}, "unix/linux_like/linux/arch/mips/mod.rs": {"os": ["linux"], "arch": ["mips", "mips64"]}, "unix/linux_like/linux/arch/powerpc/mod.rs": {"os": ["linux"], "arch": ["powerpc", "powerpc64"]}, "unix/linux_like/linux/arch/sparc/mod.rs": {"os": ["linux"], "arch": ["sparc", "sparc64"]}, "unix/solarish/mod.rs": {"os": ["solaris", "illumos"]}, "unix/linux_like/linux/gnu/mod.rs": {"os": ["linux"], "env": ["gnu"]}, "unix/linux_like/linux/musl/mod.rs": {"os": ["linux"], "env": ["musl"]}, "unix/linux_like/linux/uclibc/mod.rs": {"os": ["linux"], "env": ["uclibc"]}, "unix/linux_like/android/b32/mod.rs": {"os": ["android"], "pointer_width": ["32"]}, "unix/linux_like/android/b64/mod.rs": {"os": ["android"], "pointer_width": ["64"]}, "unix/linux_like/linux/mod.rs": {"os": ["linux"]}, "unix/mod.rs": {"family": ["unix"]}, "vxworks/mod.rs": {"os": ["vxworks"]}, "unix/bsd/mod.rs": {"os": ["macos", "ios", "watchos", "freebsd", "dragonfly", "openbsd", "netbsd"]}, "unix/hermit/mod.rs": {"os": ["hermit"]}, "unix/newlib/mod.rs": {"env": ["newlib"]}, "unix/redox/mod.rs": {"os": ["redox"]}, } def extract_paths(rg_lines: List[str]) -> List[str]: paths = set() for line in rg_lines: item = json.loads(line) if item["type"] == "match": file_path = item["data"]["path"]["text"] rel_file_path = re.match(".+src/(.+)", file_path).group(1) # type: ignore paths.add(rel_file_path) return sorted(paths) def search(prefix: str, ident: str) -> List[Dict[str, List[str]]]: pipe = os.popen(f"rg --json 'pub {prefix} {ident}' {LIBC_REPO_PATH}") lines = [l for l in pipe.read().split("\n") if l != ""] cfgs = [PREDICATES[path] for path in extract_paths(lines)] return cfgs def emit_predicate(kind: str, cond: List[str]) -> str: if len(cond) == 1: return f'{kind} = "{cond[0]}"' else: return "any(" + ", ".join(f'{kind} = "{c}"' for c in cond) + ")" def emit_cfg(cfgs: List[Dict[str, List[str]]], indent: int) -> str: predicates = [] for cfg in cfgs: ps = [] for kind in ["os", "arch", "env", "pointer_width", "family"]: if kind in cfg: ps.append(emit_predicate(f"target_{kind}", cfg[kind])) if len(ps) == 1: predicates.append(ps[0]) else: predicates.append("all(" + ", ".join(ps) + ")") ans = "any(\n" for p in predicates: ans += " " * (indent + 1) + p + ",\n" ans += " " * indent + ")" return ans if __name__ == "__main__": resources = [ "RLIMIT_AS", "RLIMIT_CORE", "RLIMIT_CPU", "RLIMIT_DATA", "RLIMIT_FSIZE", "RLIMIT_KQUEUES", "RLIMIT_LOCKS", "RLIMIT_MEMLOCK", "RLIMIT_MSGQUEUE", "RLIMIT_NICE", "RLIMIT_NOFILE", "RLIMIT_NOVMON", "RLIMIT_NPROC", "RLIMIT_NPTS", "RLIMIT_NTHR", "RLIMIT_POSIXLOCKS", "RLIMIT_RSS", "RLIMIT_RTPRIO", "RLIMIT_RTTIME", "RLIMIT_SBSIZE", "RLIMIT_SIGPENDING", "RLIMIT_STACK", "RLIMIT_SWAP", "RLIMIT_UMTXP", "RLIMIT_VMEM", ] print( "#![allow(" "clippy::assertions_on_constants, " "clippy::absurd_extreme_comparisons, " "clippy::cast_possible_truncation, " "unused_comparisons)]\n" ) resource_cfgs = [] for resource in resources: cfg = emit_cfg(search("const", resource), indent=0) resource_cfgs.append((resource, cfg)) print(f"#[cfg({cfg})]") print(f"pub const {resource}: u8 = libc::{resource} as u8;") print() print(f"#[cfg(not({cfg}))]") print(f"pub const {resource}: u8 = u8::MAX;") print() print("// " + "-" * 77) print() print("#[allow(clippy::too_many_lines)]") print("#[test]") print("fn resource_bound() {") for resource, cfg in resource_cfgs: print(f" #[cfg({cfg})]") print(f" assert!((0..128).contains(&libc::{resource}));") print() print("}") print() for ident in ["rlimit", "getrlimit", "setrlimit"]: if ident == "rlimit": cfg64 = emit_cfg(search("struct", ident + "64"), indent=0) cfg = emit_cfg(search("struct", ident), indent=0) else: cfg64 = emit_cfg(search("fn", ident + "64"), indent=0) cfg = emit_cfg(search("fn", ident), indent=0) print(f"#[cfg({cfg64})]") print(f"pub use libc::{ident}64 as {ident};") print() print(f"#[cfg(all(not({cfg64}), {cfg}))]") print(f"pub use libc::{ident};") print() ident = "RLIM_INFINITY" cfg = emit_cfg(search("const", ident), indent=0) print(f"#[cfg({cfg})]") print(f"pub const {ident}: u64 = libc::{ident} as u64;") print() print(f"#[cfg(not({cfg}))]") print(f"pub const {ident}: u64 = u64::MAX;") print() rlimit-0.8.3/scripts/codegen.sh000075500000000000000000000004600072674642500146160ustar 00000000000000#!/bin/bash echo "updating libc" if [ ! -d "libc" ]; then git clone https://github.com/rust-lang/libc.git -b master --depth=1 else pushd libc git pull popd fi mkdir -p target python3 ./scripts/codegen.py > target/out.rs rustfmt target/out.rs cp target/out.rs src/bindings.rs echo "done" rlimit-0.8.3/src/bindings.rs000075500000000000000000001156630072674642500141350ustar 00000000000000#![allow( clippy::assertions_on_constants, clippy::absurd_extreme_comparisons, clippy::cast_possible_truncation, unused_comparisons )] #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), target_os = "netbsd", target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIMIT_AS: u8 = libc::RLIMIT_AS as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), target_os = "netbsd", target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIMIT_AS: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIMIT_CORE: u8 = libc::RLIMIT_CORE as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIMIT_CORE: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIMIT_CPU: u8 = libc::RLIMIT_CPU as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIMIT_CPU: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIMIT_DATA: u8 = libc::RLIMIT_DATA as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIMIT_DATA: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIMIT_FSIZE: u8 = libc::RLIMIT_FSIZE as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIMIT_FSIZE: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any(target_os = "freebsd",))] pub const RLIMIT_KQUEUES: u8 = libc::RLIMIT_KQUEUES as u8; #[cfg(not(any(target_os = "freebsd",)))] pub const RLIMIT_KQUEUES: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_LOCKS: u8 = libc::RLIMIT_LOCKS as u8; #[cfg(not(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_LOCKS: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_MEMLOCK: u8 = libc::RLIMIT_MEMLOCK as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_MEMLOCK: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_MSGQUEUE: u8 = libc::RLIMIT_MSGQUEUE as u8; #[cfg(not(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_MSGQUEUE: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_NICE: u8 = libc::RLIMIT_NICE as u8; #[cfg(not(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_NICE: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIMIT_NOFILE: u8 = libc::RLIMIT_NOFILE as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIMIT_NOFILE: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any(target_os = "haiku",))] pub const RLIMIT_NOVMON: u8 = libc::RLIMIT_NOVMON as u8; #[cfg(not(any(target_os = "haiku",)))] pub const RLIMIT_NOVMON: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_NPROC: u8 = libc::RLIMIT_NPROC as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_NPROC: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any(target_os = "freebsd",))] pub const RLIMIT_NPTS: u8 = libc::RLIMIT_NPTS as u8; #[cfg(not(any(target_os = "freebsd",)))] pub const RLIMIT_NPTS: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any(target_os = "netbsd",))] pub const RLIMIT_NTHR: u8 = libc::RLIMIT_NTHR as u8; #[cfg(not(any(target_os = "netbsd",)))] pub const RLIMIT_NTHR: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any(target_os = "dragonfly",))] pub const RLIMIT_POSIXLOCKS: u8 = libc::RLIMIT_POSIXLOCKS as u8; #[cfg(not(any(target_os = "dragonfly",)))] pub const RLIMIT_POSIXLOCKS: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_RSS: u8 = libc::RLIMIT_RSS as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_RSS: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_RTPRIO: u8 = libc::RLIMIT_RTPRIO as u8; #[cfg(not(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_RTPRIO: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_RTTIME: u8 = libc::RLIMIT_RTTIME as u8; #[cfg(not(any( target_os = "fuchsia", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_RTTIME: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( any(target_os = "freebsd", target_os = "dragonfly"), target_os = "netbsd", ))] pub const RLIMIT_SBSIZE: u8 = libc::RLIMIT_SBSIZE as u8; #[cfg(not(any( any(target_os = "freebsd", target_os = "dragonfly"), target_os = "netbsd", )))] pub const RLIMIT_SBSIZE: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] pub const RLIMIT_SIGPENDING: u8 = libc::RLIMIT_SIGPENDING as u8; #[cfg(not(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), )))] pub const RLIMIT_SIGPENDING: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIMIT_STACK: u8 = libc::RLIMIT_STACK as u8; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIMIT_STACK: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any(target_os = "freebsd",))] pub const RLIMIT_SWAP: u8 = libc::RLIMIT_SWAP as u8; #[cfg(not(any(target_os = "freebsd",)))] pub const RLIMIT_SWAP: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any(target_os = "freebsd",))] pub const RLIMIT_UMTXP: u8 = libc::RLIMIT_UMTXP as u8; #[cfg(not(any(target_os = "freebsd",)))] pub const RLIMIT_UMTXP: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[cfg(any( any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIMIT_VMEM: u8 = libc::RLIMIT_VMEM as u8; #[cfg(not(any( any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIMIT_VMEM: u8 = u8::MAX; // ----------------------------------------------------------------------------- #[allow(clippy::too_many_lines)] #[test] fn resource_bound() { #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), target_os = "netbsd", target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] assert!((0..128).contains(&libc::RLIMIT_AS)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] assert!((0..128).contains(&libc::RLIMIT_CORE)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] assert!((0..128).contains(&libc::RLIMIT_CPU)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] assert!((0..128).contains(&libc::RLIMIT_DATA)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] assert!((0..128).contains(&libc::RLIMIT_FSIZE)); #[cfg(any(target_os = "freebsd",))] assert!((0..128).contains(&libc::RLIMIT_KQUEUES)); #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_LOCKS)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_MEMLOCK)); #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_MSGQUEUE)); #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_NICE)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] assert!((0..128).contains(&libc::RLIMIT_NOFILE)); #[cfg(any(target_os = "haiku",))] assert!((0..128).contains(&libc::RLIMIT_NOVMON)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_NPROC)); #[cfg(any(target_os = "freebsd",))] assert!((0..128).contains(&libc::RLIMIT_NPTS)); #[cfg(any(target_os = "netbsd",))] assert!((0..128).contains(&libc::RLIMIT_NTHR)); #[cfg(any(target_os = "dragonfly",))] assert!((0..128).contains(&libc::RLIMIT_POSIXLOCKS)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_RSS)); #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_RTPRIO)); #[cfg(any( target_os = "fuchsia", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_RTTIME)); #[cfg(any( any(target_os = "freebsd", target_os = "dragonfly"), target_os = "netbsd", ))] assert!((0..128).contains(&libc::RLIMIT_SBSIZE)); #[cfg(any( target_os = "fuchsia", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), ))] assert!((0..128).contains(&libc::RLIMIT_SIGPENDING)); #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] assert!((0..128).contains(&libc::RLIMIT_STACK)); #[cfg(any(target_os = "freebsd",))] assert!((0..128).contains(&libc::RLIMIT_SWAP)); #[cfg(any(target_os = "freebsd",))] assert!((0..128).contains(&libc::RLIMIT_UMTXP)); #[cfg(any( any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "solaris", target_os = "illumos"), ))] assert!((0..128).contains(&libc::RLIMIT_VMEM)); } #[cfg(any( target_os = "fuchsia", all(target_os = "android", target_pointer_width = "32"), all(target_os = "android", target_pointer_width = "64"), target_os = "emscripten", target_os = "linux", ))] pub use libc::rlimit64 as rlimit; #[cfg(all( not(any( target_os = "fuchsia", all(target_os = "android", target_pointer_width = "32"), all(target_os = "android", target_pointer_width = "64"), target_os = "emscripten", target_os = "linux", )), any( target_os = "fuchsia", all(target_os = "android", target_pointer_width = "32"), all(target_os = "android", target_pointer_width = "64"), target_os = "emscripten", target_os = "linux", target_family = "unix", target_os = "vxworks", ) ))] pub use libc::rlimit; #[cfg(any( target_os = "android", target_os = "emscripten", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), all(target_os = "linux", target_env = "uclibc"), ))] pub use libc::getrlimit64 as getrlimit; #[cfg(all( not(any( target_os = "android", target_os = "emscripten", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), all(target_os = "linux", target_env = "uclibc"), )), any( any( target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd" ), target_os = "haiku", target_os = "hermit", target_os = "android", target_os = "emscripten", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), all(target_os = "linux", target_env = "uclibc"), target_env = "newlib", target_os = "redox", any(target_os = "solaris", target_os = "illumos"), ) ))] pub use libc::getrlimit; #[cfg(any( target_os = "android", target_os = "emscripten", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), all(target_os = "linux", target_env = "uclibc"), ))] pub use libc::setrlimit64 as setrlimit; #[cfg(all( not(any( target_os = "android", target_os = "emscripten", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), all(target_os = "linux", target_env = "uclibc"), )), any( any( target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd" ), target_os = "haiku", target_os = "hermit", target_os = "android", target_os = "emscripten", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), all(target_os = "linux", target_env = "uclibc"), target_env = "newlib", target_os = "redox", any(target_os = "solaris", target_os = "illumos"), ) ))] pub use libc::setrlimit; #[cfg(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), ))] pub const RLIM_INFINITY: u64 = libc::RLIM_INFINITY as u64; #[cfg(not(any( target_os = "fuchsia", any(target_os = "macos", target_os = "ios"), any(target_os = "freebsd", target_os = "dragonfly"), any(target_os = "openbsd", target_os = "netbsd"), target_os = "haiku", target_os = "android", target_os = "emscripten", target_os = "linux", all(target_os = "linux", any(target_arch = "mips", target_arch = "mips64")), all( target_os = "linux", any(target_arch = "powerpc", target_arch = "powerpc64") ), all( target_os = "linux", any(target_arch = "sparc", target_arch = "sparc64") ), any(target_os = "solaris", target_os = "illumos"), )))] pub const RLIM_INFINITY: u64 = u64::MAX; rlimit-0.8.3/src/lib.rs000064400000000000000000000056130072674642500130740ustar 00000000000000//! rlimit - Resource limits. //! //! # Examples //! //! ## Set resource limit //! ```no_run //! # #[cfg(unix)] //! # { //! use rlimit::{setrlimit, Resource}; //! //! const DEFAULT_SOFT_LIMIT: u64 = 4 * 1024 * 1024; //! const DEFAULT_HARD_LIMIT: u64 = 8 * 1024 * 1024; //! assert!(Resource::FSIZE.set(DEFAULT_SOFT_LIMIT, DEFAULT_HARD_LIMIT).is_ok()); //! //! let soft = 16384; //! let hard = soft * 2; //! assert!(setrlimit(Resource::NOFILE, soft, hard).is_ok()); //! # } //! ``` //! //! ## Get resource limit //! ```no_run //! # #[cfg(unix)] //! # { //! use rlimit::{getrlimit, Resource}; //! //! assert!(Resource::NOFILE.get().is_ok()); //! assert_eq!(getrlimit(Resource::CPU).unwrap(), (rlimit::INFINITY, rlimit::INFINITY)); //! # } //! ``` //! //! ## Increase NOFILE limit //! See the example [nofile](https://github.com/Nugine/rlimit/tree/v0.8.3/examples/nofile.rs). //! //! You can also use the tool function showed below: //! //! ```no_run //! rlimit::increase_nofile_limit(10240).unwrap(); //! rlimit::increase_nofile_limit(u64::MAX).unwrap(); //! ``` //! //! ## Windows //! //! Windows does not have Unix-like resource limits. //! It only supports changing the number of simultaneously open files currently permitted at the stdio level. //! //! See the official documentation of //! [`_getmaxstdio`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getmaxstdio?view=msvc-170) //! and //! [`_setmaxstdio`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setmaxstdio?view=msvc-170). //! //! ```no_run //! # #[cfg(windows)] //! # { //! println!("{}", rlimit::getmaxstdio()); // 512 //! rlimit::setmaxstdio(2048).unwrap(); //! println!("{}", rlimit::getmaxstdio()); // 2048 //! # } //! ``` //! //! # Troubleshoot //! //! ## Failed to increase NOFILE to hard limit on macOS //! On macOS, getrlimit by default reports that the hard limit is //! unlimited, but there is usually a stricter hard limit discoverable //! via sysctl (`kern.maxfilesperproc`). Failing to discover this secret stricter hard limit will //! cause the call to setrlimit to fail. //! //! [`rlimit::increase_nofile_limit`][`crate::increase_nofile_limit`] //! respects `kern.maxfilesperproc`. //! #![cfg_attr(docsrs, feature(doc_cfg))] #![deny( missing_docs, missing_debug_implementations, clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo )] #[allow(unused_macros)] macro_rules! group { ($($item:item)*) => { $($item)* } } #[cfg(any(doc, windows))] group! { mod windows; #[doc(inline)] pub use self::windows::*; } #[cfg(any(doc, unix))] group! { mod bindings; mod unix; mod resource; #[doc(inline)] pub use self::unix::*; #[doc(inline)] pub use self::resource::Resource; } #[cfg(any(doc, target_os = "linux"))] group! { mod proc_limits; #[doc(inline)] pub use self::proc_limits::*; } mod tools; #[doc(inline)] pub use self::tools::*; rlimit-0.8.3/src/proc_limits.rs000064400000000000000000000176120072674642500146540ustar 00000000000000#![deny(unsafe_code)] use crate::unix::pid_t; use std::fs; use std::io::{self, BufRead}; use std::num::ParseIntError; use std::path::Path; /// A process's resource limits. It is parsed from the **proc** filesystem. /// /// See . /// #[cfg_attr(docsrs, doc(cfg(target_os = "linux")))] #[derive(Debug, Clone, Default)] #[non_exhaustive] pub struct ProcLimits { /// Max cpu time. See also [Resource::CPU](struct.Resource.html#associatedconstant.CPU). pub max_cpu_time: Option, /// Max file size. See also [Resource::FSIZE](struct.Resource.html#associatedconstant.FSIZE). pub max_file_size: Option, /// Max data size. See also [Resource::DATA](struct.Resource.html#associatedconstant.DATA). pub max_data_size: Option, /// Max stack size. See also [Resource::STACK](struct.Resource.html#associatedconstant.STACK). pub max_stack_size: Option, /// Max core file size. See also [Resource::CORE](struct.Resource.html#associatedconstant.CORE). pub max_core_file_size: Option, /// Max resident set. See also [Resource::RSS](struct.Resource.html#associatedconstant.RSS). pub max_resident_set: Option, /// Max processes. See also [Resource::NPROC](struct.Resource.html#associatedconstant.NPROC). pub max_processes: Option, /// Max open files. See also [Resource::NOFILE](struct.Resource.html#associatedconstant.NOFILE). pub max_open_files: Option, /// Max locked memory. See also [Resource::MEMLOCK](struct.Resource.html#associatedconstant.MEMLOCK). pub max_locked_memory: Option, /// Max address space. See also [Resource::AS](struct.Resource.html#associatedconstant.AS). pub max_address_space: Option, /// Max file locks. See also [Resource::LOCKS](struct.Resource.html#associatedconstant.LOCKS). pub max_file_locks: Option, /// Max pending signals. See also [Resource::SIGPENDING](struct.Resource.html#associatedconstant.SIGPENDING). pub max_pending_signals: Option, /// Max msgqueue size. See also [Resource::MSGQUEUE](struct.Resource.html#associatedconstant.MSGQUEUE). pub max_msgqueue_size: Option, /// Max nice priority. See also [Resource::NICE](struct.Resource.html#associatedconstant.NICE). pub max_nice_priority: Option, /// Max realtime priority. See also [Resource::RTPRIO](struct.Resource.html#associatedconstant.RTPRIO). pub max_realtime_priority: Option, /// Max realtime timeout. See also [Resource::RTTIME](struct.Resource.html#associatedconstant.RTTIME). pub max_realtime_timeout: Option, } /// A process's resource limit field. #[cfg_attr(docsrs, doc(cfg(target_os = "linux")))] #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct ProcLimit { /// Soft limit. `None` indicates `unlimited`. pub soft_limit: Option, /// Hard limit. `None` indicates `unlimited`. pub hard_limit: Option, } impl ProcLimits { /// Reads the current process's resource limits from `/proc/self/limits`. /// /// # Errors /// Returns an error if any IO operation failed. /// /// Returns an error if the file format is invalid. /// pub fn read_self() -> io::Result { Self::read_proc_fs("/proc/self/limits") } /// Reads a process's resource limits from `/proc/[pid]/limits`. /// /// # Errors /// Returns an error if `pid` is negative. /// /// Returns an error if any IO operation failed. /// /// Returns an error if the file format is invalid. /// pub fn read_process(pid: pid_t) -> io::Result { if pid < 0 { return Err(io::Error::new( io::ErrorKind::InvalidInput, "ProcLimits: pid must be non-negative", )); } Self::read_proc_fs(format!("/proc/{}/limits", pid)) } fn read_proc_fs(limits_path: impl AsRef) -> io::Result { fn parse_head(head: &str) -> Option<(usize, usize, usize)> { let s_idx = head.find('S')?; let h_idx = head[s_idx..].find('H')?; let u_idx = head[s_idx + h_idx..].find('U')?; Some((s_idx, h_idx, u_idx)) } fn parse_limit_number(s: &str) -> Result, ParseIntError> { match s { "unlimited" => Ok(None), _ => match s.parse::() { Ok(n) => Ok(Some(n)), Err(e) => Err(e), }, } } fn error_missing_table_head() -> io::Error { io::Error::new(io::ErrorKind::Other, "ProcLimits: missing table head") } fn error_invalid_table_head() -> io::Error { io::Error::new(io::ErrorKind::Other, "ProcLimits: invalid table head") } fn error_invalid_limit_number(e: ParseIntError) -> io::Error { let ans = io::Error::new( io::ErrorKind::Other, format!("ProcLimits: invalid limit number: {}", e), ); drop(e); ans } fn error_duplicate_limit_field() -> io::Error { io::Error::new(io::ErrorKind::Other, "ProcLimits: duplicate limit field") } fn error_unknown_limit_field(s: &str) -> io::Error { io::Error::new( io::ErrorKind::Other, format!("ProcLimits: unknown limit field: {:?}", s), ) } let reader = io::BufReader::new(fs::File::open(limits_path)?); let mut lines = reader.lines(); let head = lines.next().ok_or_else(error_missing_table_head)??; let (name_len, soft_len, hard_len) = parse_head(&head).ok_or_else(error_invalid_table_head)?; let mut ans = Self::default(); let sorted_table: [(&str, &mut Option); 16] = [ ("max address space", &mut ans.max_address_space), ("max core file size", &mut ans.max_core_file_size), ("max cpu time", &mut ans.max_cpu_time), ("max data size", &mut ans.max_data_size), ("max file locks", &mut ans.max_file_locks), ("max file size", &mut ans.max_file_size), ("max locked memory", &mut ans.max_locked_memory), ("max msgqueue size", &mut ans.max_msgqueue_size), ("max nice priority", &mut ans.max_nice_priority), ("max open files", &mut ans.max_open_files), ("max pending signals", &mut ans.max_pending_signals), ("max processes", &mut ans.max_processes), ("max realtime priority", &mut ans.max_realtime_priority), ("max realtime timeout", &mut ans.max_realtime_timeout), ("max resident set", &mut ans.max_resident_set), ("max stack size", &mut ans.max_stack_size), ]; for line in lines { let line = line?; let (name, line) = line.split_at(name_len); let (soft, line) = line.split_at(soft_len); let (hard, _) = line.split_at(hard_len); let name = name.trim().to_lowercase(); let soft_limit = parse_limit_number(soft.trim()).map_err(error_invalid_limit_number)?; let hard_limit = parse_limit_number(hard.trim()).map_err(error_invalid_limit_number)?; let limit = ProcLimit { soft_limit, hard_limit, }; match sorted_table.binary_search_by_key(&name.as_str(), |&(s, _)| s) { Ok(idx) => { let field = &mut *sorted_table[idx].1; if field.is_some() { return Err(error_duplicate_limit_field()); } *field = Some(limit); } Err(_) => return Err(error_unknown_limit_field(&name)), } } Ok(ans) } } rlimit-0.8.3/src/resource.rs000064400000000000000000000225620072674642500141570ustar 00000000000000#![deny(unsafe_code)] use crate::bindings as C; use std::error::Error; use std::fmt; use std::io; use std::str::FromStr; /// A kind of resource. /// /// All resource constants are available on all unix platforms. /// Passing an unsupported resource to `[set|get|p]rlimit` will /// result in a custom IO error. /// /// **Be careful**: The documentation of [`Resource`][Resource] constants are based on a few systems. /// It may be inconsistent with other platforms. /// /// # References /// Linux: /// /// FreeBSD: /// /// NetBSD: /// /// [Resource]: struct.Resource.html /// #[allow(clippy::doc_markdown)] #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Resource { tag: u8, value: u8, } impl fmt::Debug for Resource { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let idx = Self::VALUE_TABLE.iter().position(|v| v == self).unwrap(); write!(f, "Resource::{}", Self::IDENT_TABLE[idx]) } } impl FromStr for Resource { type Err = ParseResourceError; fn from_str(s: &str) -> Result { let pos = Self::NAME_TABLE.iter().position(|&name| s == name); match pos { Some(idx) => Ok(Self::VALUE_TABLE[idx]), None => Err(ParseResourceError { _priv: () }), } } } /// An error returned when parsing a `Resource` using [`from_str`] fails #[derive(Debug, Clone, PartialEq, Eq)] pub struct ParseResourceError { /// private place holder _priv: (), } impl fmt::Display for ParseResourceError { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "failed to parse Resource") } } impl Error for ParseResourceError {} macro_rules! declare_resource { {$($(#[$attr:meta])* $id:ident = $tag:expr => $c_enum:ident,)+} => { impl Resource{ $( $(#[$attr])* pub const $id: Self = Self{ tag: $tag, value: C::$c_enum as u8 }; )+ } #[allow(unused_doc_comments)] impl Resource{ const NAME_TABLE: &'static [&'static str] = &[ $( $(#[$attr])* { stringify!($c_enum) }, )+ ]; const VALUE_TABLE: &'static [Self] = &[ $( $(#[$attr])* { Self::$id }, )+ ]; const IDENT_TABLE: &'static [&'static str] = &[ $( $(#[$attr])* { stringify!($id) }, )+ ]; } #[cfg(test)] mod tests{ use super::*; #[allow(unused_comparisons)] #[allow(unused_doc_comments)] #[test] fn name_value(){ $( $(#[$attr])* { assert_eq!(Resource::$id.as_name(), stringify!($c_enum)); assert_eq!(Resource::from_str(stringify!($c_enum)).unwrap(), Resource::$id); } )+ } #[allow(unused_doc_comments)] #[test] fn unique_tag(){ use std::collections::HashSet; let tags = [ $( $(#[$attr])* { $tag }, )+ ]; let s: HashSet = tags.iter().copied().collect(); assert_eq!(s.len(), Resource::NAME_TABLE.len()); } #[allow(unused_doc_comments)] #[test] fn raw_eq(){ $( $(#[$attr])* { assert_eq!(Resource::$id.as_raw(), C::$c_enum); } )+ } #[allow(unused_doc_comments)] #[test] fn from_str(){ $( $(#[$attr])* { assert_eq!(Resource::from_str(stringify!($c_enum)), Ok(Resource::$id)); } )+ assert!(Resource::from_str("asdqwe").is_err()); } } }; } impl Resource { /// Set resource limits. /// # Errors /// See [`setrlimit`](fn.setrlimit.html) #[inline] pub fn set(self, soft: u64, hard: u64) -> io::Result<()> { super::setrlimit(self, soft, hard) } /// Get resource limits. /// # Errors /// See [`getrlimit`](fn.getrlimit.html) #[inline] pub fn get(self) -> io::Result<(u64, u64)> { super::getrlimit(self) } /// Returns the name of the resource. /// /// # Example /// ``` /// # #[cfg(unix)] /// # { /// # use rlimit::Resource; /// assert_eq!(Resource::NOFILE.as_name(), "RLIMIT_NOFILE"); /// # } /// ``` #[must_use] #[allow(clippy::missing_panics_doc)] // this method should never panic pub fn as_name(self) -> &'static str { let idx = Self::VALUE_TABLE.iter().position(|&v| v == self).unwrap(); Self::NAME_TABLE[idx] } /// Returns true if the current platform supports this resource. #[must_use] pub const fn is_supported(self) -> bool { self.value != u8::MAX } /// `u8::MAX` indicates unsupported resource. #[inline] #[must_use] pub(crate) const fn as_raw(self) -> u8 { self.value } } declare_resource! { /// The maximum size (in bytes) /// of the process's virtual memory (address space). AS = 1 => RLIMIT_AS, /// The maximum size (in bytes) /// of a core file that the process may dump. CORE = 2 => RLIMIT_CORE, /// A limit (in seconds) /// on the amount of CPU time that the process can consume. CPU = 3 => RLIMIT_CPU, /// The maximum size (in bytes) /// of the process's data segment /// (initialized data, uninitialized data, and heap). DATA = 4 => RLIMIT_DATA, /// The maximum size (in bytes) /// of files that the process may create. FSIZE = 5 => RLIMIT_FSIZE, /// The maximum number of kqueues this user id is allowed to create. KQUEUES = 6 => RLIMIT_KQUEUES, /// (early Linux 2.4 only) /// /// A limit on the combined number /// of `flock(2)` locks and `fcntl(2)` leases /// that this process may establish. LOCKS = 7 => RLIMIT_LOCKS, /// The maximum number (in bytes) /// of memory that may be locked into RAM. MEMLOCK = 8 => RLIMIT_MEMLOCK, /// A limit on the number /// of bytes that can be allocated for POSIX message queues /// for the real user ID of the calling process. MSGQUEUE = 9 => RLIMIT_MSGQUEUE, /// This specifies a ceiling /// to which the process's nice value can be raised /// using `setpriority(2)` or `nice(2)`. NICE = 10 => RLIMIT_NICE, /// This specifies a value /// one greater than the maximum file descriptor number /// that can be opened by this process. NOFILE = 11 => RLIMIT_NOFILE, /// The number of open vnode monitors. NOVMON = 12 => RLIMIT_NOVMON, /// A limit on the number of extant process (or, more precisely on Linux, threads) /// for the real user ID of the calling process. NPROC = 13 => RLIMIT_NPROC, /// The maximum number of pseudo-terminals this user id is allowed to create. NPTS = 14 => RLIMIT_NPTS, /// The maximum number of simultaneous threads (Lightweight /// Processes) for this user id. Kernel threads and the /// first thread of each process are not counted against this /// limit. NTHR = 15 => RLIMIT_NTHR, /// The maximum number of POSIX-type advisory-mode locks available to this user. POSIXLOCKS = 16 => RLIMIT_POSIXLOCKS, /// A limit (in bytes) /// on the process's resident set /// (the number of virtual pages resident in RAM). RSS = 17 => RLIMIT_RSS, /// This specifies a ceiling on the real-time priority /// that may be set for this process /// using `sched_setscheduler(2)` and `sched_setparam(2)`. RTPRIO = 18 => RLIMIT_RTPRIO, /// A limit (in microseconds) on the amount of CPU time /// that a process scheduled under a real-time scheduling policy /// may consume without making a blocking system call. RTTIME = 19 => RLIMIT_RTTIME, /// The maximum size (in bytes) of socket buffer usage for /// this user. This limits the amount of network memory, and /// hence the amount of mbufs, that this user may hold at any /// time. SBSIZE = 20 => RLIMIT_SBSIZE, /// A limit on the number /// of signals that may be queued /// for the real user ID of the calling process. SIGPENDING = 21 => RLIMIT_SIGPENDING, /// The maximum size (in bytes) /// of the process stack. STACK = 22 => RLIMIT_STACK, /// The maximum size (in bytes) of the swap space that may be /// reserved or used by all of this user id's processes. SWAP = 23 => RLIMIT_SWAP, /// The number of shared locks a given user may create simultaneously. UMTXP = 24 => RLIMIT_UMTXP, /// An alias for RLIMIT_AS. The maximum size of a process's mapped address space in bytes. VMEM = 25 => RLIMIT_VMEM, } rlimit-0.8.3/src/tools.rs000064400000000000000000000037460072674642500134730ustar 00000000000000use std::io; /// Returns the value of `kern.maxfilesperproc` by sysctl. /// # Errors /// Returns an error if any syscall failed. #[cfg(any( any(target_os = "macos", target_os = "ios"), target_os = "dragonfly", target_os = "freebsd", ))] fn get_kern_max_files_per_proc() -> io::Result { use std::mem; use std::ptr; let mut mib = [libc::CTL_KERN, libc::KERN_MAXFILESPERPROC]; let mut max_files_per_proc: libc::c_int = 0; let mut oldlen = mem::size_of::(); let ret = unsafe { libc::sysctl( mib.as_mut_ptr(), 2, &mut max_files_per_proc as *mut libc::c_int as *mut libc::c_void, &mut oldlen, ptr::null_mut(), 0, ) }; if ret < 0 { return Err(io::Error::last_os_error()); } debug_assert!(max_files_per_proc >= 0); Ok(max_files_per_proc as u64) } /// Try to increase NOFILE limit and return the current soft limit. /// /// `lim` is the expected limit which can be up to [`u64::MAX`]. /// /// This function does nothing and returns `Ok(lim)` /// if `RLIMIT_NOFILE` does not exist on current platform. /// /// # Errors /// Returns an error if any syscall failed. pub fn increase_nofile_limit(lim: u64) -> io::Result { #[cfg(unix)] { use crate::Resource; if !Resource::NOFILE.is_supported() { return Ok(lim); } let (soft, hard) = Resource::NOFILE.get()?; if soft >= hard { return Ok(hard); } if soft >= lim { return Ok(soft); } let mut lim = lim; lim = lim.min(hard); #[cfg(any( any(target_os = "macos", target_os = "ios"), target_os = "dragonfly", target_os = "freebsd", ))] { lim = lim.min(get_kern_max_files_per_proc()?) } Resource::NOFILE.set(lim, hard)?; Ok(lim) } #[cfg(windows)] { Ok(lim) } } rlimit-0.8.3/src/unix.rs000064400000000000000000000062710072674642500133120ustar 00000000000000use crate::bindings as C; use crate::resource::Resource; use std::{io, mem}; /// A value indicating no limit. pub const INFINITY: u64 = C::RLIM_INFINITY as u64; fn check_supported(resource: Resource) -> io::Result<()> { let raw_resource = resource.as_raw(); if raw_resource == u8::MAX { return Err(io::Error::new(io::ErrorKind::Other, "unsupported resource")); } Ok(()) } /// Set resource limits. /// # Errors /// \[Linux\] See #[inline] pub fn setrlimit(resource: Resource, soft: u64, hard: u64) -> io::Result<()> { check_supported(resource)?; let rlim = C::rlimit { rlim_cur: soft.min(INFINITY) as _, rlim_max: hard.min(INFINITY) as _, }; #[allow(clippy::cast_lossless)] let ret = unsafe { C::setrlimit(resource.as_raw() as _, &rlim) }; if ret == 0 { Ok(()) } else { Err(io::Error::last_os_error()) } } /// Get resource limits. /// # Errors /// \[Linux\] See #[inline] pub fn getrlimit(resource: Resource) -> io::Result<(u64, u64)> { check_supported(resource)?; let mut rlim = unsafe { mem::zeroed() }; #[allow(clippy::cast_lossless)] let ret = unsafe { C::getrlimit(resource.as_raw() as _, &mut rlim) }; if ret == 0 { let soft = (rlim.rlim_cur as u64).min(INFINITY); let hard = (rlim.rlim_max as u64).min(INFINITY); Ok((soft, hard)) } else { Err(io::Error::last_os_error()) } } /// The type of a process ID #[allow(non_camel_case_types)] #[cfg(any(doc, target_os = "linux"))] #[cfg_attr(docsrs, doc(cfg(target_os = "linux")))] pub type pid_t = i32; #[cfg(target_os = "linux")] extern "C" { fn prlimit64( pid: pid_t, resource: u32, new_limit: *const C::rlimit, old_limit: *mut C::rlimit, ) -> i32; } /// Set and get the resource limits of an arbitrary process. /// # Errors /// See #[inline] #[cfg(any(doc, target_os = "linux"))] #[cfg_attr(docsrs, doc(cfg(target_os = "linux")))] pub fn prlimit( pid: pid_t, resource: Resource, new_limit: Option<(u64, u64)>, old_limit: Option<(&mut u64, &mut u64)>, ) -> io::Result<()> { check_supported(resource)?; let new_rlim: Option = new_limit.map(|(soft, hard)| C::rlimit { rlim_cur: soft.min(INFINITY) as _, rlim_max: hard.min(INFINITY) as _, }); let new_rlimit_ptr: *const C::rlimit = match new_rlim { Some(ref rlim) => rlim, None => std::ptr::null(), }; let mut old_rlim: C::rlimit = unsafe { mem::zeroed() }; let old_rlimit_ptr: *mut C::rlimit = if old_limit.is_some() { &mut old_rlim } else { std::ptr::null_mut() }; #[allow(clippy::cast_lossless)] let ret = unsafe { prlimit64(pid, resource.as_raw() as _, new_rlimit_ptr, old_rlimit_ptr) }; if ret == 0 { if let Some((soft, hard)) = old_limit { *soft = (old_rlim.rlim_cur as u64).min(INFINITY); *hard = (old_rlim.rlim_max as u64).min(INFINITY); } Ok(()) } else { Err(io::Error::last_os_error()) } } rlimit-0.8.3/src/windows.rs000064400000000000000000000025360072674642500140210ustar 00000000000000use std::io; use std::os::raw::c_int; extern "C" { fn _setmaxstdio(new_max: c_int) -> c_int; fn _getmaxstdio() -> c_int; } /// Sets a maximum for the number of simultaneously open files at the stream I/O level. /// /// See /// /// # Errors /// See the official documentation #[cfg_attr(docsrs, doc(cfg(windows)))] pub fn setmaxstdio(new_max: u32) -> io::Result { // A negative `new_max` will cause EINVAL. // A negative `ret` should never appear. // It is safe even if the return value is wrong. #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] unsafe { let ret = _setmaxstdio(new_max as c_int); if ret < 0 { return Err(io::Error::last_os_error()); } Ok(ret as u32) } } /// Returns the number of simultaneously open files permitted at the stream I/O level. /// /// See #[cfg_attr(docsrs, doc(cfg(windows)))] #[must_use] pub fn getmaxstdio() -> u32 { // A negative `ret` should never appear. // It is safe even if the return value is wrong. #[allow(clippy::cast_sign_loss)] unsafe { let ret = _getmaxstdio(); debug_assert!(ret >= 0); ret as u32 } } rlimit-0.8.3/tests/it/linux.rs000064400000000000000000000052760072674642500144610ustar 00000000000000use std::io::ErrorKind; use std::ops::Not; use rlimit::{prlimit, Resource}; use super::{expect_err, expect_ok}; #[test] fn linux_prlimit() { const SOFT: u64 = 4 * 1024 * 1024; const HARD: u64 = 8 * 1024 * 1024; let res = Resource::CORE; expect_ok(prlimit(0, res, Some((SOFT, HARD)), None)); let mut soft = 0; let mut hard = 0; expect_ok(prlimit(0, res, None, Some((&mut soft, &mut hard)))); assert_eq!((soft, hard), (SOFT, HARD)); expect_err( prlimit(0, res, Some((HARD, SOFT)), None), ErrorKind::InvalidInput, ); expect_err( prlimit(0, res, Some((HARD, HARD + 1)), None), ErrorKind::PermissionDenied, ); } #[test] fn linux_proc_limits() { use rlimit::ProcLimits; let self_limits = ProcLimits::read_self().unwrap(); assert!(self_limits.max_cpu_time.is_some()); assert!(self_limits.max_file_size.is_some()); assert!(self_limits.max_data_size.is_some()); assert!(self_limits.max_stack_size.is_some()); assert!(self_limits.max_core_file_size.is_some()); assert!(self_limits.max_resident_set.is_some()); assert!(self_limits.max_processes.is_some()); assert!(self_limits.max_open_files.is_some()); assert!(self_limits.max_locked_memory.is_some()); assert!(self_limits.max_address_space.is_some()); assert!(self_limits.max_file_locks.is_some()); assert!(self_limits.max_pending_signals.is_some()); assert!(self_limits.max_msgqueue_size.is_some()); assert!(self_limits.max_nice_priority.is_some()); assert!(self_limits.max_realtime_priority.is_some()); assert!(self_limits.max_realtime_timeout.is_some()); let self_pid = unsafe { libc::getpid() }; let process_limits = ProcLimits::read_process(self_pid).unwrap(); macro_rules! assert_limit_eq{ {$lhs:expr, $rhs:expr, [$($field:tt,)+]} => { $( assert_eq!($lhs.$field, $rhs.$field, stringify!($field)); )+ } } assert_limit_eq!( self_limits, process_limits, [ max_cpu_time, max_file_size, max_data_size, max_stack_size, max_core_file_size, max_resident_set, max_processes, max_open_files, max_locked_memory, max_address_space, max_file_locks, max_pending_signals, max_msgqueue_size, max_nice_priority, max_realtime_priority, max_realtime_timeout, ] ); } #[test] fn unsupported() { assert!(Resource::UMTXP.is_supported().not()); let err = Resource::UMTXP.get().unwrap_err(); assert!(err.kind() == std::io::ErrorKind::Other); } rlimit-0.8.3/tests/it/main.rs000064400000000000000000000007450072674642500142420ustar 00000000000000#[cfg(target_os = "linux")] mod linux; #[cfg(unix)] mod unix; #[cfg(windows)] mod windows; #[allow(unused)] use std::io; #[allow(unused)] #[track_caller] fn expect_ok(result: io::Result<()>) { assert!(result.is_ok()); } #[allow(unused)] #[track_caller] fn expect_err(result: io::Result<()>, kind: io::ErrorKind) { assert_eq!(result.unwrap_err().kind(), kind); } #[test] fn tools_nofile() { let lim = rlimit::increase_nofile_limit(u64::MAX).unwrap(); dbg!(lim); } rlimit-0.8.3/tests/it/unix.rs000064400000000000000000000014750072674642500143020ustar 00000000000000use std::io::ErrorKind; use rlimit::{getrlimit, setrlimit, Resource}; use super::{expect_err, expect_ok}; #[test] fn resource_set_get() { const SOFT: u64 = 4 * 1024 * 1024; const HARD: u64 = 8 * 1024 * 1024; expect_ok(Resource::FSIZE.set(SOFT - 1, HARD)); expect_ok(setrlimit(Resource::FSIZE, SOFT, HARD)); assert_eq!(Resource::FSIZE.get().unwrap(), (SOFT, HARD)); // FIXME: why does this line succeed on freebsd? #[cfg(not(target_os = "freebsd"))] { expect_err(Resource::FSIZE.set(HARD, SOFT), ErrorKind::InvalidInput); } expect_err( Resource::FSIZE.set(HARD, HARD + 1), ErrorKind::PermissionDenied, ); } #[test] fn resource_infinity() { assert_eq!( getrlimit(Resource::CPU).unwrap(), (rlimit::INFINITY, rlimit::INFINITY) ); } rlimit-0.8.3/tests/it/windows.rs000064400000000000000000000002550072674642500150040ustar 00000000000000#[test] fn maxstdio() { assert_eq!(rlimit::getmaxstdio(), 512); assert_eq!(rlimit::setmaxstdio(2048).unwrap(), 2048); assert_eq!(rlimit::getmaxstdio(), 2048); }