Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
49dd6ad
DragonflyBSD: Fix the type of `mcontext_t.mc_fpregs`
tgross35 Dec 2, 2025
0c66946
libc: add PartialEq, Eq, and Hash trait implementations for Padding.
mbyx Nov 6, 2025
8947755
libc: wrap padding fields with Padding newtype.
mbyx Nov 6, 2025
b219385
linux: Move Linux-specific pthread bits to the `new` module
tgross35 Nov 20, 2025
246f2e9
ci: Disable tests on FreeBSD 13
tgross35 Nov 20, 2025
401bdaa
android: Move android-specific pthread bits to the `new` module
tgross35 Nov 20, 2025
d32bd21
emscripten: Move emscripten-specific pthread bits to the `new` module
tgross35 Nov 20, 2025
93d1d92
linux-like: Move pthread API in to the `new` module
tgross35 Nov 20, 2025
f1b7594
l4re: Update available pthread API
tgross35 Nov 20, 2025
e9e7824
apple: Nest all new Apple sources in an `apple/` module
tgross35 Nov 19, 2025
f524656
apple: Add missing pthread API to the semver lists
tgross35 Nov 20, 2025
f540572
apple: Move pthread API to the `new` module
tgross35 Nov 19, 2025
0b69468
fmt: Use the same rustfmt.toml everywhere
tgross35 Nov 20, 2025
3e47c82
fmt: Replace style.sh with style.py
tgross35 Nov 20, 2025
b5a279a
macros: Take a visibility for `c_enum` variants
tgross35 Nov 20, 2025
c8eb9f1
ci: Update `style.py` to work with visibility on enums
tgross35 Nov 20, 2025
39e973a
Fix test for cygwin
500-internal-server-error Nov 12, 2025
5ca17df
cygwin: Add missing utmp/x.h, grp.h, and stdio.h interfaces
500-internal-server-error Nov 24, 2025
210a971
Make eventfd argument names match OS docs/headers
krobelus Nov 16, 2025
686703c
Define eventfd on NetBSD
krobelus Nov 16, 2025
88d2190
linux, android: Add definition for IUCLC
3v1n0 Nov 21, 2025
79c4284
build(deps): bump actions/checkout from 5 to 6
dependabot[bot] Nov 24, 2025
589ecc1
add syscalls 451-469 for m68k linux
Takashiidobe Nov 29, 2025
8e43534
NetBSD: Only skip `sockaddr_dl` on NetBSD9
tgross35 Dec 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ task:
# https://github.com/rust-lang/rust/issues/132185
RUST_BACKTRACE: "0"
matrix:
- name: nightly freebsd-13 i686
# Test i686 FreeBSD in 32-bit emulation on a 64-bit host.
env:
TARGET: i686-unknown-freebsd
freebsd_instance:
image_family: freebsd-13-4
- name: nightly freebsd-13 x86_64
freebsd_instance:
image_family: freebsd-13-4
# FIXME(#4740): FreeBSD 13 tests are extremely flaky and fail most of the time
# - name: nightly freebsd-13 i686
# # Test i686 FreeBSD in 32-bit emulation on a 64-bit host.
# env:
# TARGET: i686-unknown-freebsd
# freebsd_instance:
# image_family: freebsd-13-4
# - name: nightly freebsd-13 x86_64
# freebsd_instance:
# image_family: freebsd-13-4
- name: nightly freebsd-14 x86_64
freebsd_instance:
image: freebsd-14-3-release-amd64-ufs
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ jobs:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup Rust toolchain
run: ./ci/install-rust.sh && rustup component add rustfmt
- name: Check style
run: ./ci/style.sh
run: ./ci/style.py

clippy:
name: Clippy on ${{ matrix.os }}
Expand All @@ -39,7 +39,7 @@ jobs:
runs-on: ${{ matrix.os }}
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: rustup update stable --no-self-update
- uses: Swatinem/rust-cache@v2
# Here we use the latest stable Rust toolchain already installed by GitHub
Expand Down Expand Up @@ -68,7 +68,7 @@ jobs:
env:
TOOLCHAIN: ${{ matrix.toolchain }}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup Rust toolchain
run: ./ci/install-rust.sh

Expand Down Expand Up @@ -130,7 +130,7 @@ jobs:
env:
TARGET: ${{ matrix.target }}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup Rust toolchain
run: ./ci/install-rust.sh
- uses: Swatinem/rust-cache@v2
Expand Down Expand Up @@ -227,7 +227,7 @@ jobs:
env:
TARGET: ${{ matrix.target }}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup Rust toolchain
run: ./ci/install-rust.sh
- uses: Swatinem/rust-cache@v2
Expand Down Expand Up @@ -270,7 +270,7 @@ jobs:
- target: x86_64-unknown-netbsd
timeout-minutes: 25
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: test on Solaris
uses: vmactions/[email protected]
if: contains(matrix.target, 'solaris')
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish_0.2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Rust (rustup)
Expand Down
1 change: 0 additions & 1 deletion src/rustfmt.toml → .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Note that there is a separate top-level configuration for everything else
edition = "2021"
error_on_line_overflow = true
group_imports = "StdExternalCrate"
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ We have two automated tests running on
- `cd libc-test && cargo test`
- Use the `skip_*()` functions in `build.rs` if you really need a workaround.
2. Style checker
- [`./ci/style.sh`](https://github.com/rust-lang/libc/blob/main/ci/style.sh)
- [`./ci/style.py`](https://github.com/rust-lang/libc/blob/main/ci/style.py)

## Breaking change policy

Expand Down
10 changes: 8 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use std::process::{Command, Output};
use std::{env, str};
use std::process::{
Command,
Output,
};
use std::{
env,
str,
};

// List of cfgs this build script is allowed to set. The list is needed to support check-cfg, as we
// need to know all the possible cfgs that this script will set. If you need to set another cfg
Expand Down
10 changes: 8 additions & 2 deletions ci/ios/deploy_and_run_on_ios_simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@
// (https://github.com/snipsco/dinghy): cargo dinghy install, then cargo dinghy
// test.

use std::fs::{self, File};
use std::fs::{
self,
File,
};
use std::io::Write;
use std::path::Path;
use std::process::Command;
use std::{env, process};
use std::{
env,
process,
};

macro_rules! t {
($e:expr) => {
Expand Down
5 changes: 4 additions & 1 deletion ci/runtest-android.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use std::env;
use std::path::{Path, PathBuf};
use std::path::{
Path,
PathBuf,
};
use std::process::Command;

fn main() {
Expand Down
182 changes: 182 additions & 0 deletions ci/style.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#!/usr/bin/env python3

import os
import re
import subprocess as sp
import sys

from difflib import unified_diff
from glob import iglob
from pathlib import Path


FMT_DIRS = ["src", "ci"]
IGNORE_FILES = [
# Too much special syntax that we don't want to format
"src/macros.rs"
]


def main():
# if `CI` is set, do a check rather than overwriting
check_only = os.getenv("CI") is not None
run(["rustfmt", "-V"])

fmt_files = []
for dir in FMT_DIRS:
fmt_files.extend(iglob(f"{dir}/**/*.rs", recursive=True))

for file in fmt_files:
if file in IGNORE_FILES:
continue
fmt_one(Path(file), check_only)

# Run once from workspace root to get everything that wasn't handled as an
# individual file.
if check_only:
run(["cargo", "fmt", "--check"])
else:
run(["cargo", "fmt"])

for file in iglob("libc-test/semver/*.txt"):
check_semver_file(Path(file))

# Style tests
run(
[
"cargo",
"test",
"--manifest-path=libc-test/Cargo.toml",
"--test=style",
"--",
"--nocapture",
]
)

try:
run(["shellcheck", "--version"])
except sp.CalledProcessError:
eprint("ERROR: shellcheck not found")
exit(1)

for file in iglob("**/*.sh", recursive=True):
run(["shellcheck", file])


def fmt_one(fpath: Path, check_only: bool):
eprint(f"Formatting {fpath}")
text = fpath.read_text()

# Rustfmt doesn't format the bodies of `{ ... }` macros, which is most of `libc`. To
# make things usable, we do some hacks to replace macros with some kind of
# alternative syntax that gets formatted about how we want, then reset the changes
# after formatting.

# Turn all braced macro `foo! { /* ... */ }` invocations into
# `fn foo_fmt_tmp() { /* ... */ }`, since our macro bodies are usually valid in
# a function context.
text = re.sub(r"(?!macro_rules)\b(\w+)!\s*\{", r"fn \1_fmt_tmp() {", text)

# Replace `if #[cfg(...)]` within `cfg_if` with `if cfg_tmp!([...])` which
# `rustfmt` will format. We put brackets within the parens so it is easy to
# match (trying to match parentheses would catch the first closing `)` which
# wouldn't be correct for something like `all(any(...), ...)`).
text = re.sub(r"if #\[cfg\((.*?)\)\]", r"if cfg_tmp!([\1])", text, flags=re.DOTALL)

# The `c_enum!` macro allows anonymous enums without names, which isn't valid
# syntax. Replace it with a dummy name.
text = re.sub(r"enum #anon\b", r"enum _fmt_anon", text)

# If enum variants are annotated with `pub`, rustfmt erases the visibility. To get
# around this we first match on all enums to extract their bodies, then look for `pub`
# visibility indicators. If found, these get stashed in a comment on the preceding
# line.
def enum_sub(m: re.Match) -> str:
enum_body = m.group(0)
rep = re.sub(
r"^(.*)\b(pub\s*?(\(.*?\))?)\s*",
r"\1/* FMT-VIS \2 END-FMT-VIS */\n\1",
enum_body,
flags=re.MULTILINE,
)
return rep

text = re.sub(r"\benum.*\{\n?(?:\s*[^}]*\n)+\s*\}", enum_sub, text)

# Invoke rustfmt passing via stdin/stdout so we don't need to write the file. Exits
# on failure.
cmd = ["rustfmt", "--config-path=.rustfmt.toml"]
if check_only:
res = check_output(cmd + ["--check"], input=text)

# Unfortunately rustfmt on stdin always completes with 0 exit code even if
# there are errors, so we need to pick between writing the file to disk or
# relying on empty stdout to indicate success.
# <https://github.com/rust-lang/rustfmt/issues/5376>.
if len(res) == 0:
return
eprint(f"ERROR: File {fpath} is not properly formatted")
print(res)
exit(1)
else:
text = check_output(cmd, input=text)

# Restore all changes in the formatted text
text = re.sub(r"fn (\w+)_fmt_tmp\(\)", r"\1!", text)
text = re.sub(r"cfg_tmp!\(\[(.*?)\]\)", r"#[cfg(\1)]", text, flags=re.DOTALL)
text = re.sub(r"enum _fmt_anon", r"enum #anon", text)
text = re.sub(r"/\* FMT-VIS (.*) END-FMT-VIS \*/\n\s*", r"\1 ", text)

# And write the formatted file back
fpath.write_text(text)


def check_semver_file(fpath: Path):
if "TODO" in str(fpath):
eprint(f"Skipping semver file {fpath}")
return

eprint(f"Checking semver file {fpath}")

text = fpath.read_text()
lines = text.splitlines()
sort = sorted(lines)
if lines != sort:
eprint(f"ERROR: Unsorted semver file {fpath}")
eprint("\n".join(unified_diff(lines, sort, lineterm="")))
exit(1)

duplicates = []
seen = set()
for line in lines:
if line in seen:
duplicates.append(line)
seen.add(line)

if len(duplicates) > 0:
eprint(f"ERROR: Duplicates in semver file {fpath}")
eprint(duplicates)
exit(1)


def check_output(args: list[str], **kw) -> str:
xtrace(args)
return sp.check_output(args, encoding="utf8", text=True, **kw)


def run(args: list[str], **kw) -> sp.CompletedProcess:
xtrace(args)
return sp.run(args, check=True, text=True, **kw)


def xtrace(args: list[str]):
astr = " ".join(args)
eprint(f"+ {astr}")


def eprint(*args, **kw):
print(*args, file=sys.stderr, **kw)


if __name__ == "__main__":
main()
Loading