1*086b156cSSascha Wildner /*-
2*086b156cSSascha Wildner * Copyright (c) 2017 Juniper Networks. All rights reserved.
3*086b156cSSascha Wildner *
4*086b156cSSascha Wildner * Redistribution and use in source and binary forms, with or without
5*086b156cSSascha Wildner * modification, are permitted provided that the following conditions
6*086b156cSSascha Wildner * are met:
7*086b156cSSascha Wildner * 1. Redistributions of source code must retain the above copyright
8*086b156cSSascha Wildner * notice, this list of conditions and the following disclaimer.
9*086b156cSSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright
10*086b156cSSascha Wildner * notice, this list of conditions and the following disclaimer in the
11*086b156cSSascha Wildner * documentation and/or other materials provided with the distribution.
12*086b156cSSascha Wildner *
13*086b156cSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
14*086b156cSSascha Wildner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15*086b156cSSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16*086b156cSSascha Wildner * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
17*086b156cSSascha Wildner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18*086b156cSSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19*086b156cSSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20*086b156cSSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21*086b156cSSascha Wildner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22*086b156cSSascha Wildner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23*086b156cSSascha Wildner * SUCH DAMAGE.
24*086b156cSSascha Wildner *
25*086b156cSSascha Wildner * $FreeBSD: head/lib/libc/stdlib/set_constraint_handler_s.c 322427 2017-08-12 15:18:17Z kib $
26*086b156cSSascha Wildner */
27*086b156cSSascha Wildner
28*086b156cSSascha Wildner #include "namespace.h"
29*086b156cSSascha Wildner #include <sys/types.h>
30*086b156cSSascha Wildner #include <machine/atomic.h>
31*086b156cSSascha Wildner #include <errno.h>
32*086b156cSSascha Wildner #include <pthread.h>
33*086b156cSSascha Wildner #include <stddef.h>
34*086b156cSSascha Wildner #include <stdlib.h>
35*086b156cSSascha Wildner #include <string.h>
36*086b156cSSascha Wildner #include <unistd.h>
37*086b156cSSascha Wildner #include "un-namespace.h"
38*086b156cSSascha Wildner #include "libc_private.h"
39*086b156cSSascha Wildner
40*086b156cSSascha Wildner /*
41*086b156cSSascha Wildner * Rationale recommends allocating new memory each time.
42*086b156cSSascha Wildner */
43*086b156cSSascha Wildner static constraint_handler_t *_ch = NULL;
44*086b156cSSascha Wildner static pthread_mutex_t ch_lock = PTHREAD_MUTEX_INITIALIZER;
45*086b156cSSascha Wildner
46*086b156cSSascha Wildner constraint_handler_t
set_constraint_handler_s(constraint_handler_t handler)47*086b156cSSascha Wildner set_constraint_handler_s(constraint_handler_t handler)
48*086b156cSSascha Wildner {
49*086b156cSSascha Wildner constraint_handler_t *new, *old, ret;
50*086b156cSSascha Wildner
51*086b156cSSascha Wildner new = malloc(sizeof(constraint_handler_t));
52*086b156cSSascha Wildner if (new == NULL)
53*086b156cSSascha Wildner return (NULL);
54*086b156cSSascha Wildner *new = handler;
55*086b156cSSascha Wildner if (__isthreaded)
56*086b156cSSascha Wildner _pthread_mutex_lock(&ch_lock);
57*086b156cSSascha Wildner old = _ch;
58*086b156cSSascha Wildner _ch = new;
59*086b156cSSascha Wildner if (__isthreaded)
60*086b156cSSascha Wildner _pthread_mutex_unlock(&ch_lock);
61*086b156cSSascha Wildner if (old == NULL) {
62*086b156cSSascha Wildner ret = NULL;
63*086b156cSSascha Wildner } else {
64*086b156cSSascha Wildner ret = *old;
65*086b156cSSascha Wildner free(old);
66*086b156cSSascha Wildner }
67*086b156cSSascha Wildner return (ret);
68*086b156cSSascha Wildner }
69*086b156cSSascha Wildner
70*086b156cSSascha Wildner void
__throw_constraint_handler_s(const char * restrict msg,errno_t error)71*086b156cSSascha Wildner __throw_constraint_handler_s(const char * restrict msg, errno_t error)
72*086b156cSSascha Wildner {
73*086b156cSSascha Wildner constraint_handler_t ch;
74*086b156cSSascha Wildner
75*086b156cSSascha Wildner if (__isthreaded)
76*086b156cSSascha Wildner _pthread_mutex_lock(&ch_lock);
77*086b156cSSascha Wildner ch = _ch != NULL ? *_ch : NULL;
78*086b156cSSascha Wildner if (__isthreaded)
79*086b156cSSascha Wildner _pthread_mutex_unlock(&ch_lock);
80*086b156cSSascha Wildner if (ch != NULL)
81*086b156cSSascha Wildner ch(msg, NULL, error);
82*086b156cSSascha Wildner }
83*086b156cSSascha Wildner
84*086b156cSSascha Wildner void
abort_handler_s(const char * restrict msg,void * restrict ptr __unused,errno_t error __unused)85*086b156cSSascha Wildner abort_handler_s(const char * restrict msg, void * restrict ptr __unused,
86*086b156cSSascha Wildner errno_t error __unused)
87*086b156cSSascha Wildner {
88*086b156cSSascha Wildner static const char ahs[] = "abort_handler_s : ";
89*086b156cSSascha Wildner
90*086b156cSSascha Wildner (void) _write(STDERR_FILENO, ahs, sizeof(ahs) - 1);
91*086b156cSSascha Wildner (void) _write(STDERR_FILENO, msg, strlen(msg));
92*086b156cSSascha Wildner (void) _write(STDERR_FILENO, "\n", 1);
93*086b156cSSascha Wildner abort();
94*086b156cSSascha Wildner }
95*086b156cSSascha Wildner
96*086b156cSSascha Wildner void
ignore_handler_s(const char * restrict msg __unused,void * restrict ptr __unused,errno_t error __unused)97*086b156cSSascha Wildner ignore_handler_s(const char * restrict msg __unused,
98*086b156cSSascha Wildner void * restrict ptr __unused, errno_t error __unused)
99*086b156cSSascha Wildner {
100*086b156cSSascha Wildner }
101