init_signal_handler.c 2.8 KB
Newer Older
W
wenjun 已提交
1
/*
Z
zhong_ning 已提交
2
 * Copyright (c) 2021 Huawei Device Co., Ltd.
W
wenjun 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16
 * 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 <signal.h>
#include <sys/wait.h>
17

18
#include "init_adapter.h"
Z
zhong_ning 已提交
19
#include "init_log.h"
X
xionglei6 已提交
20
#include "init_param.h"
W
wenjun 已提交
21
#include "init_service_manager.h"
X
xionglei6 已提交
22
#include "loop_event.h"
M
mamingshuai 已提交
23

X
xionglei6 已提交
24
SignalHandle g_sigHandle = NULL;
M
mamingshuai 已提交
25

X
xionglei6 已提交
26
static void ProcessSignal(const struct signalfd_siginfo *siginfo)
W
wenjun 已提交
27
{
X
xionglei6 已提交
28
    switch (siginfo->ssi_signo) {
W
wenjun 已提交
29 30 31 32 33 34 35 36
        case SIGCHLD: {
            pid_t sigPID;
            int procStat = 0;
            while (1) {
                sigPID = waitpid(-1, &procStat, WNOHANG);
                if (sigPID <= 0) {
                    break;
                }
Z
zhong_ning 已提交
37 38 39 40 41
                // check child process exit status
                if (WIFSIGNALED(procStat)) {
                    INIT_LOGE("Child process %d exit with signal: %d", sigPID, WTERMSIG(procStat));
                }
                if (WIFEXITED(procStat)) {
42
                    INIT_LOGE("Child process %d exit with code : %d", sigPID, WEXITSTATUS(procStat));
Z
zhong_ning 已提交
43
                }
M
maplestory 已提交
44 45 46 47
                Service* service = GetServiceByPid(sigPID);
                INIT_LOGI("SigHandler, SIGCHLD received, Service:%s pid:%d uid:%d status:%d.",
                    service == NULL ? "Unknown" : service->name,
                    sigPID, siginfo->ssi_uid, procStat);
M
mamingshuai 已提交
48
                CheckWaitPid(sigPID);
M
maplestory 已提交
49
                ServiceReap(service);
W
wenjun 已提交
50 51 52 53
            }
            break;
        }
        case SIGTERM: {
Z
zhong_ning 已提交
54
            INIT_LOGI("SigHandler, SIGTERM received.");
X
xionglei6 已提交
55 56 57
            SystemWriteParam("startup.device.ctl", "stop");
            // exec reboot use toybox reboot cmd
            ExecReboot("reboot");
W
wenjun 已提交
58 59 60
            break;
        }
        default:
X
xionglei6 已提交
61
            INIT_LOGI("SigHandler, unsupported signal %d.", siginfo->ssi_signo);
W
wenjun 已提交
62 63 64 65
            break;
    }
}

66
void SignalInit(void)
Z
zhong_ning 已提交
67
{
X
xionglei6 已提交
68
    if (LE_CreateSignalTask(LE_GetDefaultLoop(), &g_sigHandle, ProcessSignal) != 0) {
Z
zhong_ning 已提交
69
        INIT_LOGW("initialize signal handler failed");
Z
zhong_ning 已提交
70 71
        return;
    }
X
xionglei6 已提交
72
    if (LE_AddSignal(LE_GetDefaultLoop(), g_sigHandle, SIGCHLD) != 0) {
Z
zhong_ning 已提交
73
        INIT_LOGW("start SIGCHLD handler failed");
Z
zhong_ning 已提交
74
    }
X
xionglei6 已提交
75
    if (LE_AddSignal(LE_GetDefaultLoop(), g_sigHandle, SIGTERM) != 0) {
Z
zhong_ning 已提交
76
        INIT_LOGW("start SIGTERM handler failed");
Z
zhong_ning 已提交
77
    }
78
}