Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/stdlib/set_constraint_handler_s.c
Show All 26 Lines | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "namespace.h" | #include "namespace.h" | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <machine/atomic.h> | #include <machine/atomic.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <pthread.h> | #include <pthread.h> | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include <stdio.h> | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include "un-namespace.h" | #include "un-namespace.h" | ||||
#include "libc_private.h" | #include "libc_private.h" | ||||
/* | /* | ||||
* Rationale recommends allocating new memory each time. | * Rationale recommends allocating new memory each time. | ||||
*/ | */ | ||||
static constraint_handler_t *_ch = NULL; | static constraint_handler_t *_ch = NULL; | ||||
Show All 33 Lines | __throw_constraint_handler_s(const char * restrict msg, errno_t error) | ||||
ch = _ch != NULL ? *_ch : NULL; | ch = _ch != NULL ? *_ch : NULL; | ||||
if (__isthreaded) | if (__isthreaded) | ||||
_pthread_mutex_unlock(&ch_lock); | _pthread_mutex_unlock(&ch_lock); | ||||
if (ch != NULL) | if (ch != NULL) | ||||
ch(msg, NULL, error); | ch(msg, NULL, error); | ||||
} | } | ||||
void | void | ||||
abort_handler_s(const char * restrict msg __unused, | abort_handler_s(const char * restrict msg, void * restrict ptr __unused, | ||||
void * restrict ptr __unused, errno_t error __unused) | errno_t error __unused) | ||||
{ | { | ||||
(void) fprintf(stderr, "abort_handler_s : %s\n", msg); | |||||
kib: Should abort_handler_s() be async-signal safe ? There is no direct answer to the question in… | |||||
Not Done Inline ActionsYes, this is what I mean. I would write this the '18' s line as { static const char msg[] = "abort_hand.... : "; ... (void) _write(STDERR_FILENO, msg, sizeof(msg) - 1); ... kib: Yes, this is what I mean.
I would write this the '18' s line as
```
{
static const char… | |||||
abort(); | abort(); | ||||
} | } | ||||
void | void | ||||
ignore_handler_s(const char * restrict msg __unused, | ignore_handler_s(const char * restrict msg __unused, | ||||
void * restrict ptr __unused, errno_t error __unused) | void * restrict ptr __unused, errno_t error __unused) | ||||
{ | { | ||||
} | } |
Should abort_handler_s() be async-signal safe ? There is no direct answer to the question in the standard, but intent is clearly to allow for almost mechanical replacement of the 'unsafe' (they are not, but I have no better term) functions by a 'safe' function (again, they are not).
memset(3) is async-signal safe, so we perhaps want the memset_s() to be useful in a signal context or be safe against cancellation.
abort() has contradictory requirements already, on the one hand C11 and POSIX claim that it must be async-signal safe, on the other hand POSIX says 'may include an attempt to effect fclose( ) on all open streams' and then admits that it is somewhat silly.
Our implementation of abort does try to call FILEs flush. More, __throw_constrain_handler_s() locks a mutex. Still, I am not sure that this is a good reason to add more async-signal unsafe code.
TL;DR version: I would very much prefer this fprintf call to be replaced with two write(2) calls.