init_signal_handler.c 3.6 KB
Newer Older
W
wenjun 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright (c) 2020 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "init_signal_handler.h"
17

W
wenjun 已提交
18 19 20
#include <signal.h>
#include <stdio.h>
#include <sys/wait.h>
M
mamingshuai 已提交
21 22 23 24
#ifdef __LINUX__
#include <errno.h>
#include <sys/types.h>
#endif /* __LINUX__ */
25

Z
zhong_ning 已提交
26
#include "init_log.h"
W
wenjun 已提交
27 28
#include "init_service_manager.h"

Z
zhong_ning 已提交
29 30 31 32
#ifndef OHOS_LITE
#include "init_param.h"
#include "uv.h"
#endif
M
mamingshuai 已提交
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

#ifdef __LINUX__
static pid_t  g_waitPid = -1;
static sem_t* g_waitSem = NULL;

void SignalRegWaitSem(pid_t waitPid, sem_t* waitSem)
{
    g_waitPid = waitPid;
    g_waitSem = waitSem;
}

static void CheckWaitPid(pid_t sigPID)
{
    if (g_waitPid == sigPID && g_waitSem != NULL) {
        if (sem_post(g_waitSem) != 0) {
Z
zhong_ning 已提交
48
            INIT_LOGE("CheckWaitPid, sem_post failed, errno %d.\n", errno);
M
mamingshuai 已提交
49 50 51 52 53 54 55
        }
        g_waitPid = -1;
        g_waitSem = NULL;
    }
}
#endif /* __LINUX__ */

W
wenjun 已提交
56 57 58 59 60 61 62 63 64 65 66
static void SigHandler(int sig)
{
    switch (sig) {
        case SIGCHLD: {
            pid_t sigPID;
            int procStat = 0;
            while (1) {
                sigPID = waitpid(-1, &procStat, WNOHANG);
                if (sigPID <= 0) {
                    break;
                }
Z
zhong_ning 已提交
67
                INIT_LOGI("SigHandler, SIGCHLD received, sigPID = %d.\n", sigPID);
M
mamingshuai 已提交
68 69 70
#ifdef __LINUX__
                CheckWaitPid(sigPID);
#endif /* __LINUX__ */
W
wenjun 已提交
71 72 73 74 75
                ReapServiceByPID((int)sigPID);
            }
            break;
        }
        case SIGTERM: {
Z
zhong_ning 已提交
76
            INIT_LOGI("SigHandler, SIGTERM received.\n");
W
wenjun 已提交
77 78 79
            StopAllServices();
            break;
        }
Z
zhong_ning 已提交
80 81 82 83 84 85
        case SIGINT:
#ifndef OHOS_LITE
            StopParamService();
#endif
            exit(0);
            break;
W
wenjun 已提交
86
        default:
Z
zhong_ning 已提交
87
            INIT_LOGI("SigHandler, unsupported signal %d.\n", sig);
W
wenjun 已提交
88 89 90 91
            break;
    }
}

Z
zhong_ning 已提交
92
#ifdef OHOS_LITE
W
wenjun 已提交
93 94 95 96 97 98 99 100 101 102
void SignalInitModule()
{
    struct sigaction act;
    act.sa_handler = SigHandler;
    act.sa_flags   = SA_RESTART;
    (void)sigfillset(&act.sa_mask);

    sigaction(SIGCHLD, &act, NULL);
    sigaction(SIGTERM, &act, NULL);
}
Z
zhong_ning 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
#else // L2 or above, use signal event in libuv
uv_signal_t g_sigchldHandler;
uv_signal_t g_sigtermHandler;
uv_signal_t g_sigintHandler;

static void UVSignalHandler(uv_signal_t* handle, int signum)
{
    SigHandler(signum);
}

void SignalInitModule()
{
    int ret = uv_signal_init(uv_default_loop(), &g_sigchldHandler);
    ret |= uv_signal_init(uv_default_loop(), &g_sigtermHandler);
    ret |= uv_signal_init(uv_default_loop(), &g_sigintHandler);
    if (ret != 0) {
        INIT_LOGW("initialize signal handler failed\n");
        return;
    }
M
mamingshuai 已提交
122

Z
zhong_ning 已提交
123 124 125 126 127 128 129 130 131 132 133
    if (uv_signal_start(&g_sigchldHandler, UVSignalHandler, SIGCHLD) != 0) {
        INIT_LOGW("start SIGCHLD handler failed\n");
    }
    if (uv_signal_start(&g_sigtermHandler, UVSignalHandler, SIGTERM) != 0) {
        INIT_LOGW("start SIGTERM handler failed\n");
    }
    if (uv_signal_start(&g_sigintHandler, UVSignalHandler, SIGINT) != 0) {
        INIT_LOGW("start SIGTERM handler failed\n");
    }
}
#endif