100efb5e1SYuri Pankov /*
200efb5e1SYuri Pankov * Copyright (c) 2017 Juniper Networks. All rights reserved.
300efb5e1SYuri Pankov *
400efb5e1SYuri Pankov * Redistribution and use in source and binary forms, with or without
500efb5e1SYuri Pankov * modification, are permitted provided that the following conditions
600efb5e1SYuri Pankov * are met:
700efb5e1SYuri Pankov * 1. Redistributions of source code must retain the above copyright
800efb5e1SYuri Pankov * notice, this list of conditions and the following disclaimer.
900efb5e1SYuri Pankov * 2. Redistributions in binary form must reproduce the above copyright
1000efb5e1SYuri Pankov * notice, this list of conditions and the following disclaimer in the
1100efb5e1SYuri Pankov * documentation and/or other materials provided with the distribution.
1200efb5e1SYuri Pankov *
1300efb5e1SYuri Pankov * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1400efb5e1SYuri Pankov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1500efb5e1SYuri Pankov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1600efb5e1SYuri Pankov * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1700efb5e1SYuri Pankov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1800efb5e1SYuri Pankov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1900efb5e1SYuri Pankov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2000efb5e1SYuri Pankov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2100efb5e1SYuri Pankov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2200efb5e1SYuri Pankov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2300efb5e1SYuri Pankov * SUCH DAMAGE.
2400efb5e1SYuri Pankov */
2500efb5e1SYuri Pankov
2600efb5e1SYuri Pankov /*
2700efb5e1SYuri Pankov * Copyright 2018 Nexenta Systems, Inc.
2800efb5e1SYuri Pankov */
2900efb5e1SYuri Pankov
30acab0a4fSYuri Pankov #define __STDC_WANT_LIB_EXT1__ 1
31acab0a4fSYuri Pankov
3200efb5e1SYuri Pankov #include "lint.h"
3300efb5e1SYuri Pankov
3400efb5e1SYuri Pankov #include <sys/types.h>
3500efb5e1SYuri Pankov #include <errno.h>
3600efb5e1SYuri Pankov #include <stddef.h>
3700efb5e1SYuri Pankov #include <stdlib.h>
3800efb5e1SYuri Pankov #include <string.h>
3900efb5e1SYuri Pankov #include <synch.h>
4000efb5e1SYuri Pankov #include <thread.h>
4100efb5e1SYuri Pankov #include <unistd.h>
4200efb5e1SYuri Pankov
4300efb5e1SYuri Pankov #include "libc.h"
4400efb5e1SYuri Pankov
4500efb5e1SYuri Pankov /*
4600efb5e1SYuri Pankov * Rationale recommends allocating new memory each time.
4700efb5e1SYuri Pankov */
4800efb5e1SYuri Pankov static constraint_handler_t *_ch = NULL;
4900efb5e1SYuri Pankov static mutex_t ch_lock = ERRORCHECKMUTEX;
5000efb5e1SYuri Pankov
5100efb5e1SYuri Pankov constraint_handler_t
set_constraint_handler_s(constraint_handler_t handler)5200efb5e1SYuri Pankov set_constraint_handler_s(constraint_handler_t handler)
5300efb5e1SYuri Pankov {
5400efb5e1SYuri Pankov constraint_handler_t *new, *old, ret;
5500efb5e1SYuri Pankov
5600efb5e1SYuri Pankov new = malloc(sizeof (constraint_handler_t));
5700efb5e1SYuri Pankov if (new == NULL)
5800efb5e1SYuri Pankov return (NULL);
5900efb5e1SYuri Pankov *new = handler;
6000efb5e1SYuri Pankov mutex_enter(&ch_lock);
6100efb5e1SYuri Pankov old = _ch;
6200efb5e1SYuri Pankov _ch = new;
6300efb5e1SYuri Pankov mutex_exit(&ch_lock);
6400efb5e1SYuri Pankov if (old == NULL) {
6500efb5e1SYuri Pankov ret = NULL;
6600efb5e1SYuri Pankov } else {
6700efb5e1SYuri Pankov ret = *old;
6800efb5e1SYuri Pankov free(old);
6900efb5e1SYuri Pankov }
7000efb5e1SYuri Pankov return (ret);
7100efb5e1SYuri Pankov }
7200efb5e1SYuri Pankov
7300efb5e1SYuri Pankov void
abort_handler_s(const char * _RESTRICT_KYWD msg,void * _RESTRICT_KYWD ptr __unused,errno_t error __unused)7400efb5e1SYuri Pankov abort_handler_s(const char *_RESTRICT_KYWD msg,
75*4a38094cSToomas Soome void *_RESTRICT_KYWD ptr __unused, errno_t error __unused)
7600efb5e1SYuri Pankov {
7700efb5e1SYuri Pankov common_panic("abort_handler_s: ", msg);
7800efb5e1SYuri Pankov }
7900efb5e1SYuri Pankov
8000efb5e1SYuri Pankov void
ignore_handler_s(const char * _RESTRICT_KYWD msg __unused,void * _RESTRICT_KYWD ptr __unused,errno_t error __unused)81*4a38094cSToomas Soome ignore_handler_s(const char *_RESTRICT_KYWD msg __unused,
82*4a38094cSToomas Soome void *_RESTRICT_KYWD ptr __unused, errno_t error __unused)
8300efb5e1SYuri Pankov {
8400efb5e1SYuri Pankov }
8500efb5e1SYuri Pankov
8600efb5e1SYuri Pankov void
__throw_constraint_handler_s(const char * _RESTRICT_KYWD msg,errno_t error)8700efb5e1SYuri Pankov __throw_constraint_handler_s(const char *_RESTRICT_KYWD msg, errno_t error)
8800efb5e1SYuri Pankov {
8900efb5e1SYuri Pankov constraint_handler_t ch;
9000efb5e1SYuri Pankov
9100efb5e1SYuri Pankov mutex_enter(&ch_lock);
9200efb5e1SYuri Pankov ch = (_ch != NULL) ? *_ch : NULL;
9300efb5e1SYuri Pankov mutex_exit(&ch_lock);
9400efb5e1SYuri Pankov if (ch != NULL) {
9500efb5e1SYuri Pankov ch(msg, NULL, error);
9600efb5e1SYuri Pankov } else {
9700efb5e1SYuri Pankov /*
9800efb5e1SYuri Pankov * If current handler is NULL (there were no calls to
9900efb5e1SYuri Pankov * set_constraint_handler_s(), or it was called with NULL
10000efb5e1SYuri Pankov * pointer handler argument), call default constraint handler
10100efb5e1SYuri Pankov * per K.3.6.1.1 points 4 and 5.
10200efb5e1SYuri Pankov *
10300efb5e1SYuri Pankov * This implementation defines abort_handler_s() as default.
10400efb5e1SYuri Pankov */
10500efb5e1SYuri Pankov abort_handler_s(msg, NULL, error);
10600efb5e1SYuri Pankov }
10700efb5e1SYuri Pankov }
108