Read this file AND the global rules before making any code changes - https://tarampampam.github.io/.github/ai/AGENTS.md (mirror - https://raw.githubusercontent.com/tarampampam/.github/refs/heads/master/ai/AGENTS.md).
- This file (
AGENTS.mdin this repository) - Global rules (external URLs)
- Other documentation
If rules conflict, follow the highest priority source.
Requires musl-gcc, make, cmake, python3. Compile sources on any changes to ensure no warnings or errors.
Run all tests after batching changes to ensure no regressions.
make # build all binaries → build/bin/{httpcheck,httpscheck,portcheck,parallel,pidcheck}
make test # build + run all unit tests (C) + all feature tests (Python)
make fmt # format all C source with clang-format
make clean # remove build/ and apps/version.h
APP_VERSION=1.2.3 make # set version string (generates apps/version.h)Run a single unit test binary:
make build/bin/cli_test && ./build/bin/cli_test # CLI module unit tests
make build/bin/http_test && ./build/bin/http_test # HTTP module unit tests
make build/bin/command_test && ./build/bin/command_test # command parsing unit testsRun a single feature test suite:
python3 ./tests/feature/httpcheck.py --bin ./build/bin/httpcheck # HTTP mode
python3 ./tests/feature/httpcheck.py --bin ./build/bin/httpscheck --https # HTTPS mode (needs openssl)
python3 ./tests/feature/httpcheck.py --bin ./build/bin/httpscheck --fallback # fallback mode (HTTPS->HTTP)
python3 ./tests/feature/portcheck.py --bin ./build/bin/portcheck
python3 ./tests/feature/parallel.py --bin ./build/bin/parallel
python3 ./tests/feature/pidcheck.py --bin ./build/bin/pidcheckapps/httpcheck.c compiles to both httpcheck and httpscheck. The difference: httpscheck is compiled with
-DWITH_TLS and linked against mbedTLS 4. All TLS code paths in the file are gated on #ifdef WITH_TLS. Both
binaries share the same CLI flags.
lib/cli/- CLI argument parsing. Flags have immutable metadata (cli_flag_meta_t) and mutable state (cli_flag_state_t). Three value types:FLAG_TYPE_BOOL,FLAG_TYPE_STRING,FLAG_TYPE_STRINGS. Value priority: CLI flag > environment variable > default. Every flag can have a companion--flag-envflag to override the env var name at runtime.lib/http/- HTTP protocol (no I/O). URL parsing is zero-copy:hostandpathfields point into the original string, not allocated copies. Use_lenfields for bounds.http_build_request()constructs the full HTTP/1.1 request string.lib/command/- Parses shell-like quoted command strings intoargvarrays. Used only byparallel.lib/mbedtls4/- Vendored vialib/install-mbedtls4.sh, built with cmake. Only linked intohttpscheck.
When the URL has no scheme (host:port/path without http:// or https://), httpscheck tries HTTPS first,
then falls back to HTTP on any connection/TLS error. The --connect-timeout flag controls both the TCP poll()
timeout and the SO_RCVTIMEO during TLS handshake; after a successful handshake, SO_RCVTIMEO is reset to the
full --timeout.
Do not use fprintf, snprintf, or other <stdio.h> formatting functions in apps. This bloats binary size.
Use write() with string literals or fputs() for error output. See the comment at the top of apps/httpcheck.c.
Follow the existing pattern in apps/httpcheck.c:
- Define
#define FLAG_*_LONG "flag-name"and error string constants - Define
static const cli_flag_meta_t FLAG_METAandFLAG_ENV_METAstructs cli_app_add_flag(app, &FLAG_META)and..._ENV_METAinmain()- Add both to the NULL-check and
flag_pairs[](for env-override wiring) - Parse and validate the value using a
parse_*()function following the style ofparse_timeout()
The project uses manual integer/float parsers (no strtof/atof) for size and consistency. See parse_timeout()
and parse_connect_timeout() in apps/httpcheck.c for the pattern.
tests/feature/httpcheck.py tests run in three modes selected by flags:
- Default (no flag): HTTP server, tests without
https_only=Trueorfallback_only=True --https: HTTPS server, tests withhttps_only=True--fallback: HTTP server +httpscheckbinary, tests withfallback_only=True
Each TestCase replaces {PORT} and {PROTOCOL} placeholders in give_args and give_env values at runtime.