...
Section 2.9.1 of the System Interfaces volume of POSIX.1-2008 has a much longer list of functions that are not required to be thread-safe.
Noncompliant Code Example
...
Consider a multithreaded application that encounters an error while calling a system function. The strerror()
function returns a human-readable error string given an error number. The C Standard, Section 7.24.6.2 [ISO/IEC 9899:2011], specifically states that strerror()
is not required to avoid data races. Conventionally, it could rely on a static array that maps error numbers to error strings, and that array might be accessible and modifiable by other threads. (This code is specific to POSIX because C99 and C11 do not guarantee that fopen()
will set errno
if an error occurs.)
Code Block | ||||
---|---|---|---|---|
| ||||
errno = 0; FILE* fd = fopen(filename, "r"); if (fd == NULL) { void f(FILE *fp) { fpos_t pos; errno = 0; if (0 != fgetpos(fp, &pos) { char* errmsg = strerror(errno); printf("Could not get openthe file position because of %s\n", errmsg); } } |
Note that this code first sets errno
to 0 to comply with ERR30-C. Set errno to zero before calling a library function known to set errno, and check errno only after the function returns a value indicating failure.
...
Code Block | ||||
---|---|---|---|---|
| ||||
errno = 0; FILE* fd = fopen(filename, "r"); if (fd == NULL) { void f(FILE *fp) { fpos_t pos; errno = 0; if (0 != fgetpos(fp, &pos) { char errmsg[BUFSIZ]; if (strerror_r(errno, errmsg, BUFSIZ) != 0) { /* handle error */ } printf("Could not get openthe file position because of %s\n", errmsg); } } |
Note that Linux provides two versions of strerror_r()
, known as the XSI-compliant version and the GNU-specific version. This compliant solution assumes the XSI-compliant version. You can get the XSI-compliant version if you compile applications in the way POSIX requires (that is, by defining _POSIX_C_SOURCE
or _XOPEN_SOURCE
appropriately). Check your strerror_r()
manual page to see which version(s) are available on your system.
...
Code Block | ||||
---|---|---|---|---|
| ||||
void f(FILE *fp) f{ = 0; errnofpos_t errpos; = fopen_s(&f, filename, "r"); if (err errno = 0; if (0 != fgetpos(fp, &pos) { char errmsg[BUFSIZ]; if (strerror_s(errmsg, BUFSIZ, err) != 0) { /* handle error */ } printf("Could not openget the file position because of %s\n", errmsg); } } |
Note that because of the optional nature of Annex K, strerror_s()
may not be available in all implementations.
...
[Historical information about POSIX.1 Thread Safety] | |
[ISO/IEC 9899:2011] | Section 7.24.6.2, "The |
...