xref: /freebsd/lib/libc/stdlib/set_constraint_handler_s.c (revision 559a218c9b257775fb249b67945fe4a05b7a6b9f)
19851b340SKonstantin Belousov /*-
29851b340SKonstantin Belousov  * Copyright (c) 2017 Juniper Networks.  All rights reserved.
39851b340SKonstantin Belousov  *
49851b340SKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
59851b340SKonstantin Belousov  * modification, are permitted provided that the following conditions
69851b340SKonstantin Belousov  * are met:
79851b340SKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
89851b340SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
99851b340SKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
109851b340SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
119851b340SKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
129851b340SKonstantin Belousov  *
139851b340SKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
149851b340SKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
159851b340SKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
169851b340SKonstantin Belousov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
179851b340SKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
189851b340SKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
199851b340SKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
209851b340SKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
219851b340SKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
229851b340SKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
239851b340SKonstantin Belousov  * SUCH DAMAGE.
249851b340SKonstantin Belousov  */
259851b340SKonstantin Belousov 
269851b340SKonstantin Belousov #include "namespace.h"
279851b340SKonstantin Belousov #include <sys/types.h>
289851b340SKonstantin Belousov #include <machine/atomic.h>
299851b340SKonstantin Belousov #include <errno.h>
309851b340SKonstantin Belousov #include <pthread.h>
319851b340SKonstantin Belousov #include <stddef.h>
329851b340SKonstantin Belousov #include <stdlib.h>
33*25b73e63SKonstantin Belousov #include <string.h>
34*25b73e63SKonstantin Belousov #include <unistd.h>
359851b340SKonstantin Belousov #include "un-namespace.h"
369851b340SKonstantin Belousov #include "libc_private.h"
379851b340SKonstantin Belousov 
389851b340SKonstantin Belousov /*
399851b340SKonstantin Belousov  * Rationale recommends allocating new memory each time.
409851b340SKonstantin Belousov  */
419851b340SKonstantin Belousov static constraint_handler_t *_ch = NULL;
429851b340SKonstantin Belousov static pthread_mutex_t ch_lock = PTHREAD_MUTEX_INITIALIZER;
439851b340SKonstantin Belousov 
449851b340SKonstantin Belousov constraint_handler_t
set_constraint_handler_s(constraint_handler_t handler)459851b340SKonstantin Belousov set_constraint_handler_s(constraint_handler_t handler)
469851b340SKonstantin Belousov {
479851b340SKonstantin Belousov 	constraint_handler_t *new, *old, ret;
489851b340SKonstantin Belousov 
499851b340SKonstantin Belousov 	new = malloc(sizeof(constraint_handler_t));
509851b340SKonstantin Belousov 	if (new == NULL)
519851b340SKonstantin Belousov 		return (NULL);
529851b340SKonstantin Belousov 	*new = handler;
539851b340SKonstantin Belousov 	if (__isthreaded)
549851b340SKonstantin Belousov 		_pthread_mutex_lock(&ch_lock);
559851b340SKonstantin Belousov 	old = _ch;
569851b340SKonstantin Belousov 	_ch = new;
579851b340SKonstantin Belousov 	if (__isthreaded)
589851b340SKonstantin Belousov 		_pthread_mutex_unlock(&ch_lock);
599851b340SKonstantin Belousov 	if (old == NULL) {
609851b340SKonstantin Belousov 		ret = NULL;
619851b340SKonstantin Belousov 	} else {
629851b340SKonstantin Belousov 		ret = *old;
639851b340SKonstantin Belousov 		free(old);
649851b340SKonstantin Belousov 	}
659851b340SKonstantin Belousov 	return (ret);
669851b340SKonstantin Belousov }
679851b340SKonstantin Belousov 
689851b340SKonstantin Belousov void
__throw_constraint_handler_s(const char * restrict msg,errno_t error)699851b340SKonstantin Belousov __throw_constraint_handler_s(const char * restrict msg, errno_t error)
709851b340SKonstantin Belousov {
719851b340SKonstantin Belousov 	constraint_handler_t ch;
729851b340SKonstantin Belousov 
739851b340SKonstantin Belousov 	if (__isthreaded)
749851b340SKonstantin Belousov 		_pthread_mutex_lock(&ch_lock);
759851b340SKonstantin Belousov 	ch = _ch != NULL ? *_ch : NULL;
769851b340SKonstantin Belousov 	if (__isthreaded)
779851b340SKonstantin Belousov 		_pthread_mutex_unlock(&ch_lock);
789851b340SKonstantin Belousov 	if (ch != NULL)
799851b340SKonstantin Belousov 		ch(msg, NULL, error);
809851b340SKonstantin Belousov }
819851b340SKonstantin Belousov 
829851b340SKonstantin Belousov void
abort_handler_s(const char * restrict msg,void * restrict ptr __unused,errno_t error __unused)83*25b73e63SKonstantin Belousov abort_handler_s(const char * restrict msg, void * restrict ptr __unused,
84*25b73e63SKonstantin Belousov     errno_t error __unused)
859851b340SKonstantin Belousov {
86*25b73e63SKonstantin Belousov 	static const char ahs[] = "abort_handler_s : ";
879851b340SKonstantin Belousov 
88*25b73e63SKonstantin Belousov 	(void) _write(STDERR_FILENO, ahs, sizeof(ahs) - 1);
89*25b73e63SKonstantin Belousov 	(void) _write(STDERR_FILENO, msg, strlen(msg));
90*25b73e63SKonstantin Belousov 	(void) _write(STDERR_FILENO, "\n", 1);
919851b340SKonstantin Belousov 	abort();
929851b340SKonstantin Belousov }
939851b340SKonstantin Belousov 
949851b340SKonstantin Belousov void
ignore_handler_s(const char * restrict msg __unused,void * restrict ptr __unused,errno_t error __unused)959851b340SKonstantin Belousov ignore_handler_s(const char * restrict msg __unused,
969851b340SKonstantin Belousov     void * restrict ptr __unused, errno_t error __unused)
979851b340SKonstantin Belousov {
989851b340SKonstantin Belousov }
99