xref: /kernel/liteos_m/kal/posix/src/signal.c (revision 3d8536b4)
13d8536b4Sopenharmony_ci/*
23d8536b4Sopenharmony_ci * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
33d8536b4Sopenharmony_ci *
43d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
53d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met:
63d8536b4Sopenharmony_ci *
73d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
83d8536b4Sopenharmony_ci *    conditions and the following disclaimer.
93d8536b4Sopenharmony_ci *
103d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
113d8536b4Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
123d8536b4Sopenharmony_ci *    provided with the distribution.
133d8536b4Sopenharmony_ci *
143d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
153d8536b4Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
163d8536b4Sopenharmony_ci *    permission.
173d8536b4Sopenharmony_ci *
183d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
193d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
203d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
213d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
223d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
233d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
243d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
253d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
263d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
273d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
283d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
293d8536b4Sopenharmony_ci */
303d8536b4Sopenharmony_ci
313d8536b4Sopenharmony_ci#include <signal.h>
323d8536b4Sopenharmony_ci#include <errno.h>
333d8536b4Sopenharmony_ci#include <pthread.h>
343d8536b4Sopenharmony_ci#include "los_config.h"
353d8536b4Sopenharmony_ci#include "los_signal.h"
363d8536b4Sopenharmony_ci#include "los_task.h"
373d8536b4Sopenharmony_ci#include "los_tick.h"
383d8536b4Sopenharmony_ci
393d8536b4Sopenharmony_ci#if (LOSCFG_KERNEL_SIGNAL == 1)
403d8536b4Sopenharmony_ci
413d8536b4Sopenharmony_cistatic inline unsigned int TimeSpec2Tick(const struct timespec *tp)
423d8536b4Sopenharmony_ci{
433d8536b4Sopenharmony_ci    unsigned long long tick, ns;
443d8536b4Sopenharmony_ci
453d8536b4Sopenharmony_ci    ns = (unsigned long long)tp->tv_sec * OS_SYS_NS_PER_SECOND + tp->tv_nsec;
463d8536b4Sopenharmony_ci    /* round up for ticks */
473d8536b4Sopenharmony_ci    tick = (ns * LOSCFG_BASE_CORE_TICK_PER_SECOND + (OS_SYS_NS_PER_SECOND - 1)) / OS_SYS_NS_PER_SECOND;
483d8536b4Sopenharmony_ci    if (tick > LOS_WAIT_FOREVER) {
493d8536b4Sopenharmony_ci        tick = LOS_WAIT_FOREVER;
503d8536b4Sopenharmony_ci    }
513d8536b4Sopenharmony_ci    return (unsigned int)tick;
523d8536b4Sopenharmony_ci}
533d8536b4Sopenharmony_ci
543d8536b4Sopenharmony_ciint raise(int sig)
553d8536b4Sopenharmony_ci{
563d8536b4Sopenharmony_ci    unsigned int ret = LOS_SignalSend(LOS_CurTaskIDGet(), sig);
573d8536b4Sopenharmony_ci    if (ret != LOS_OK) {
583d8536b4Sopenharmony_ci        return -1;
593d8536b4Sopenharmony_ci    }
603d8536b4Sopenharmony_ci
613d8536b4Sopenharmony_ci    return 0;
623d8536b4Sopenharmony_ci}
633d8536b4Sopenharmony_ci
643d8536b4Sopenharmony_civoid (*signal(int sig, void (*func)(int)))(int)
653d8536b4Sopenharmony_ci{
663d8536b4Sopenharmony_ci    SIG_HANDLER h = NULL;
673d8536b4Sopenharmony_ci
683d8536b4Sopenharmony_ci    if (!OS_SIGNAL_VALID(sig)) {
693d8536b4Sopenharmony_ci        errno = EINVAL;
703d8536b4Sopenharmony_ci        return SIG_ERR;
713d8536b4Sopenharmony_ci    }
723d8536b4Sopenharmony_ci
733d8536b4Sopenharmony_ci    h = LOS_SignalSet(sig, func);
743d8536b4Sopenharmony_ci    if (h == SIG_ERR) {
753d8536b4Sopenharmony_ci        errno = EINVAL;
763d8536b4Sopenharmony_ci    }
773d8536b4Sopenharmony_ci    return h;
783d8536b4Sopenharmony_ci}
793d8536b4Sopenharmony_ci
803d8536b4Sopenharmony_ciint sigprocmask(int how, const sigset_t *set, sigset_t *oset)
813d8536b4Sopenharmony_ci{
823d8536b4Sopenharmony_ci    unsigned int ret = LOS_SignalMask(how, set, oset);
833d8536b4Sopenharmony_ci    if (ret != LOS_OK) {
843d8536b4Sopenharmony_ci        errno = EINVAL;
853d8536b4Sopenharmony_ci        return -1;
863d8536b4Sopenharmony_ci    }
873d8536b4Sopenharmony_ci    return 0;
883d8536b4Sopenharmony_ci}
893d8536b4Sopenharmony_ci
903d8536b4Sopenharmony_ciint sigaction(int sig, const struct sigaction *act, struct sigaction *oldact)
913d8536b4Sopenharmony_ci{
923d8536b4Sopenharmony_ci    SIG_HANDLER old = NULL;
933d8536b4Sopenharmony_ci
943d8536b4Sopenharmony_ci    if (!OS_SIGNAL_VALID(sig)) {
953d8536b4Sopenharmony_ci        errno = EINVAL;
963d8536b4Sopenharmony_ci        return -1;
973d8536b4Sopenharmony_ci    }
983d8536b4Sopenharmony_ci
993d8536b4Sopenharmony_ci    if (act != NULL) {
1003d8536b4Sopenharmony_ci        old = LOS_SignalSet(sig, act->sa_handler);
1013d8536b4Sopenharmony_ci    } else {
1023d8536b4Sopenharmony_ci        old = LOS_SignalSet(sig, NULL);
1033d8536b4Sopenharmony_ci        (void)LOS_SignalSet(sig, old);
1043d8536b4Sopenharmony_ci    }
1053d8536b4Sopenharmony_ci
1063d8536b4Sopenharmony_ci    if (oldact != NULL) {
1073d8536b4Sopenharmony_ci        oldact->sa_handler = old;
1083d8536b4Sopenharmony_ci    }
1093d8536b4Sopenharmony_ci
1103d8536b4Sopenharmony_ci    return 0;
1113d8536b4Sopenharmony_ci}
1123d8536b4Sopenharmony_ci
1133d8536b4Sopenharmony_ciint sigwait(const sigset_t *set, int *sig)
1143d8536b4Sopenharmony_ci{
1153d8536b4Sopenharmony_ci    siginfo_t info = {0};
1163d8536b4Sopenharmony_ci
1173d8536b4Sopenharmony_ci    int ret = LOS_SignalWait(set, &info, 0);
1183d8536b4Sopenharmony_ci    if (ret < 0) {
1193d8536b4Sopenharmony_ci        errno = EINVAL;
1203d8536b4Sopenharmony_ci        return -1;
1213d8536b4Sopenharmony_ci    }
1223d8536b4Sopenharmony_ci
1233d8536b4Sopenharmony_ci    *sig = info.si_signo;
1243d8536b4Sopenharmony_ci    return 0;
1253d8536b4Sopenharmony_ci}
1263d8536b4Sopenharmony_ci
1273d8536b4Sopenharmony_ciint sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
1283d8536b4Sopenharmony_ci{
1293d8536b4Sopenharmony_ci    int tick = LOS_WAIT_FOREVER;
1303d8536b4Sopenharmony_ci    int ret;
1313d8536b4Sopenharmony_ci
1323d8536b4Sopenharmony_ci    if (timeout != NULL) {
1333d8536b4Sopenharmony_ci        tick = TimeSpec2Tick(timeout);
1343d8536b4Sopenharmony_ci    }
1353d8536b4Sopenharmony_ci
1363d8536b4Sopenharmony_ci    ret = LOS_SignalWait(set, info, tick);
1373d8536b4Sopenharmony_ci    if (ret == LOS_OK) {
1383d8536b4Sopenharmony_ci        return 0;
1393d8536b4Sopenharmony_ci    } else {
1403d8536b4Sopenharmony_ci        if (ret == LOS_ERRNO_SIGNAL_PEND_INTERR) {
1413d8536b4Sopenharmony_ci            errno = EINTR;
1423d8536b4Sopenharmony_ci        } else if (ret == LOS_ERRNO_SIGNAL_TIMEOUT) {
1433d8536b4Sopenharmony_ci            errno = EAGAIN;
1443d8536b4Sopenharmony_ci        } else {
1453d8536b4Sopenharmony_ci            errno = EINVAL;
1463d8536b4Sopenharmony_ci        }
1473d8536b4Sopenharmony_ci        return -1;
1483d8536b4Sopenharmony_ci    }
1493d8536b4Sopenharmony_ci}
1503d8536b4Sopenharmony_ci
1513d8536b4Sopenharmony_ciint sigwaitinfo(const sigset_t *set, siginfo_t *info)
1523d8536b4Sopenharmony_ci{
1533d8536b4Sopenharmony_ci    return sigtimedwait(set, info, NULL);
1543d8536b4Sopenharmony_ci}
1553d8536b4Sopenharmony_ci
1563d8536b4Sopenharmony_ciint pthread_kill(pthread_t pid, int sig)
1573d8536b4Sopenharmony_ci{
1583d8536b4Sopenharmony_ci    unsigned int ret = LOS_SignalSend((unsigned int)pid, sig);
1593d8536b4Sopenharmony_ci    if (ret != LOS_OK) {
1603d8536b4Sopenharmony_ci        errno = EINVAL;
1613d8536b4Sopenharmony_ci        return -1;
1623d8536b4Sopenharmony_ci    }
1633d8536b4Sopenharmony_ci
1643d8536b4Sopenharmony_ci    return 0;
1653d8536b4Sopenharmony_ci}
1663d8536b4Sopenharmony_ci
1673d8536b4Sopenharmony_ciint kill(pid_t pid, int sig)
1683d8536b4Sopenharmony_ci{
1693d8536b4Sopenharmony_ci    unsigned int ret = LOS_SignalSend((unsigned int)pid, sig);
1703d8536b4Sopenharmony_ci    if (ret != LOS_OK) {
1713d8536b4Sopenharmony_ci        errno = EINVAL;
1723d8536b4Sopenharmony_ci        return -1;
1733d8536b4Sopenharmony_ci    }
1743d8536b4Sopenharmony_ci
1753d8536b4Sopenharmony_ci    return 0;
1763d8536b4Sopenharmony_ci}
1773d8536b4Sopenharmony_ci#endif
178