程序无法处理SIGINT

时间:2019-02-28 10:26:00

标签: c process shared-libraries signals

我有使用记录仪的程序。记录器是一个共享库,具有一个用于输出的进程(它使用Linux MQ将消息从主进程发送到日志进程)。
在我的应用中,我尝试监听SIGINTSIGPIPE信号以关闭服务器:

/* Releases all captured resources and shuts down server */
void shutdown_server(int status) {
    LOG_I("Shutting down server...");
    close(srv_sock);
    settings_destroy(&settings);
    LOG_I("Success!");
    shutdown_log();
    exit(status);
}

/* Handles signals */
void handle_signal_action(int sig_number)
{
    if (sig_number == SIGINT) {
        LOG_D("SIGINT was catched!\n");
        shutdown_server(EXIT_SUCCESS);
    } else if (sig_number == SIGPIPE) {
        LOG_D("SIGPIPE was catched!\n");
        shutdown_server(EXIT_SUCCESS);
    }
}

/** Subscribes to events when thread was terminated or no reader of the pipe **/
int setup_signals(void (*handler)(int))
{
    struct sigaction sa;
    sa.sa_handler = handler;
    if (sigaction(SIGINT, &sa, 0) != 0) {
        LOG_E("Can't subscribe to SIGINT");
        return -1;
    }
    if (sigaction(SIGPIPE, &sa, 0) != 0) {
        LOG_E("Can't subscribe to SIGPIPE");
        return -1;
    }
    return 0;
}

/* Entry point */
int main(int argc, char **argv) {
    if (setup_signals(handle_signal_action)) {
        LOG_F("Can't setup signals");
        return -1;
    }

    if (init_log()) {
        printf("Can't initialize logger.\n");
        return -1;
    }

    if (settings_init(&settings, argc, argv)) {
        LOG_F("Can't load configuration");
        exit(EXIT_FAILURE);
    }
    settings_log(&settings);

    if (socket_init(&srv_sock, settings.address, settings.port)) {
        LOG_F("Can't initialize socket");
        exit(EXIT_FAILURE);
    }

    while (1) {
        LOG_W("Hello, world!");
    }
}

问题是,当我在终端中按 Ctrl + C 时,我的应用程序停止打印日志消息,但是两个进程仍然可以工作。

问题出在哪里?

建议。如果您需要更多详细信息,只需在评论中写上,我会添加。

添加
log.c

#include <log.h>

#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <unistd.h>

#define STOP_SIG "!>kill"

/* Message */
typedef struct mq_msg {
    log_level_t level;
    char msg[MAX_MSG_SIZE + 1];
} mq_msg_t;

/* Process ID */
pid_t pid;
/* Current log level */
log_level_t cur_log_lvl;
/* Message queue descriptor */
mqd_t mq;
/* Message queue attributes */
struct mq_attr attr;
/* Current message */
mq_msg_t cur_msg;

/* Initialize message queue listner for the child process */
void init_listener() {
    while (1) {
        ssize_t len = mq_receive(mq, (char *)&cur_msg, sizeof(cur_msg), NULL);
        if (len > 0) {
            // Check stop signal
            if (strcmp(STOP_SIG, cur_msg.msg) == 0) { exit(EXIT_SUCCESS); }

            time_t timestamp;
            struct tm *timeinfo;

            time(&timestamp);
            timeinfo = localtime(&timestamp);
            FILE *f = cur_msg.level < LL_WARNING ? stderr : stdout;

            fprintf(f, "[%u][%02d:%02d:%02d] ", (uint32_t)timestamp,
                                                timeinfo->tm_hour,
                                                timeinfo->tm_min,
                                                timeinfo->tm_sec);
            fprintf(f, "%s\n", cur_msg.msg);
            fflush(f);
            usleep(0.725 * 1e6); // TODO: Read about these magic numbers
        }
    }
}

/* Initializes logger */
bool init_log() {
    cur_log_lvl = LL_DEBUG;
    // Initialize a message queue
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = sizeof(cur_msg);
    attr.mq_curmsgs = 0;
    mq = mq_open(MQ_NAME, O_CREAT | O_RDONLY, 0644, &attr);
    if (mq == (mqd_t)-1) {
        printf("Can't create a message queue\n");
        return -1;
    }
    // Create a logger process
    pid = fork();
    if (pid == -1) {
        printf("Can't create the logger process\n");
        return -1;
    }

    if (pid == 0) {
        init_listener(); // Listen the message queue
    } else {
        mq = mq_open(MQ_NAME, O_WRONLY); // Connect to the message queue
        if (mq == (mqd_t)-1) {
            printf("Can't connect to the message queue\n");
            return -1;
        }
    }

    return 0;
}

void shutdown_log() {
    if (mq == (mqd_t)-1) { mq_close(mq); }
    if (pid > 0) { 
        memset(cur_msg.msg, 0, sizeof(cur_msg.msg));
        strcpy(cur_msg.msg, STOP_SIG);
        mq_send(mq, (const char *)&cur_msg, sizeof(cur_msg), 0);
    }
}

/* Destructor */
void __attribute__((destructor)) finish_log() {
    shutdown_log();
}

/* Sets log level */
void set_log_level(log_level_t lvl) {
    cur_log_lvl = lvl;
}

/* Returns log level */
log_level_t get_log_level() {
    return cur_log_lvl;
}

/* Sends log message to the message queue */
void trace(const char *format, ...) {
    if (pid != 0) {
        cur_msg.level = LL_DEBUG;
        va_list args;
        va_start(args, format);
        vsnprintf(cur_msg.msg, MAX_MSG_SIZE, format, args);
        va_end(args);
        mq_send(mq, (const char *)&cur_msg, sizeof(cur_msg), 0);
    }
}

0 个答案:

没有答案