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

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

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

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

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