Title: fortify-headers 2.1
Date: 2023-12-16 20:30

Only 4 days after the [release]({filename}/security/fortify-headers_2.0.md) of
[fortify-headers](https://github.com/jvoisin/fortify-headers),
here is the [2.1](https://github.com/jvoisin/fortify-headers/releases/tag/2.1),
fixing a couple of portability issues and tidying a bit the code.
[Chimera Linux](https://chimera-linux.org/) users are
[as of today](https://github.com/chimera-linux/cports/commit/a26be649d8a13c1012d5e165055d354a6bab1af8)
<del>test driving</del> benefiting from it.

## Changelog

- Remove superfluous includes from the headers
- Put some functions in to their proper files
- Add a missing include in `sys/select.h`
- Do not use static inline for C++ to avoid [ODR](https://en.wikipedia.org/wiki/One_Definition_Rule)-wise violation
- Guard some conditional stdio APIs with the right macros
- Fix a typo that would prevent C++ code from compiling correctly
- Rename macros to be more namespace-friendly

## Implementation details

Including parts from the
[stdlib](https://en.wikipedia.org/wiki/Standard_library) in fortify means that
programs that don't correctly include everything they need might compile, even
though they shouldn't. Fortunately, the only bits used are either:

- `size_t`, which can be obtained by using `typeof(sizeof(char))`,
  since it's by definition the type returned by `sizeof`.
- constants like `PATH_MAX` (that we can define to `4096`), `MB_LEN_MAX`
  (defined as 16), ...
- eldritch constructs like [`MB_CUR_MAX`](https://www.man7.org/linux/man-pages/man3/MB_CUR_MAX.3.html),
  whose usage we hide behind an `#ifdef`.

The other big thing is the one caught by [Devin Jeanpierre](https://github.com/ssbr), the usage of `static
inline` while [absolutely alright in C](https://en.cppreference.com/w/c/language/inline),
is problematic in C++, because of the [One Definition Rule](https://en.wikipedia.org/wiki/One_Definition_Rule):
In C++, if a function is declared inline, it must be declared inline in every translation unit, and also every
definition of an inline function must be exactly the same (while in C they may
be different.) On the other hand, C++ allows non-const function-local
statics and all function-local statics from different definitions of an inline
function are the same in C++, but distinct in C.
More practically, calling `FORTIFY_INLINE` functions from an inline function in C++, and including
the header defining that inline function in more than one [translation
unit](https://en.wikipedia.org/wiki/Translation_unit_%28programming%29) results
in undefined behaviour. The fix is easy, and was
[commited](https://github.com/jvoisin/fortify-headers/commit/c607773a80e6685ab4c922245c33cf2ea5dcfb72)
by [q66](https;//github.com/q66): use `static` instead of `static inline` in C++.

Thanks [Devin Jeanpierre](https://github.com/ssbr) for spending time to look at
C++ compatibility, [q66](https://github.com/q66) for his patches, willingness to ship
fortify-headers in Chimera, and becoming co-maintainer.
