C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
safe_strerror.h
Go to the documentation of this file.
1
2#pragma once
3// 1. Force feature test macros before any standard headers are pulled in
4#if defined(__linux__) || defined(__gnu_linux__)
5#ifndef _GNU_SOURCE
6#define _GNU_SOURCE 1
7#endif
8#endif
9
10#include <stddef.h>
11#include <string.h>
12
13/**
14 * @brief Thread-safe cross-platform error string retriever.
15 * @param errnum The errno code (e.g., errno).
16 * @param buf User-provided destination character buffer.
17 * @param buflen Size of the provided buffer.
18 * @return char* Pointer to the error string (either 'buf' or an internal static string).
19 */
20static inline char *safe_strerror(int errnum, char *buf, size_t buflen) {
21 if (buf == nullptr || buflen == 0) {
22 return "Invalid buffer provided";
23 }
24
25#if defined(_WIN32) || defined(_WIN64)
26 // Windows implementation using bounds-checked standard function
27 if (strerror_s(buf, buflen, errnum) == 0) {
28 return buf;
29 }
30 return "Unknown Windows error";
31
32#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(_POSIX_C_SOURCE) && !defined(_GNU_SOURCE))
33 // POSIX-compliant version (returns int) used by macOS and POSIX-strict environments
34 if (strerror_r(errnum, buf, buflen) == 0) {
35 return buf;
36 }
37 return "Unknown POSIX error";
38
39#elif defined(__linux__) || defined(__gnu_linux__)
40 // GNU-specific strerror_r (returns a char*, which might NOT be the buffer you passed)
41 return strerror_r(errnum, buf, buflen);
42
43#else
44 // Fallback if no thread-safe alternative is safely exposed
45 // Note: plain strerror is not thread-safe, but acts as a last resort
46 (void)buf;
47 (void)buflen;
48 return strerror(errnum);
49#endif
50}
#define _GNU_SOURCE
Definition amort.c:9