如何通过向他发送SIGUSR1信号立即唤醒守护程序

时间:2019-04-15 07:48:54

标签: c linux signals

我编写了一个程序守护程序,将一个文件夹中的文件复制到另一个文件夹。我必须实现SIGUSR1,该SIGUSR1通过向他发送SIGUSR1信号立即唤醒守护程序。我不知道我做错了什么,我使用命令kill -SIGUSR1,也许是错误的命令?有人知道该代码有什么问题吗?我在编译该程序后没有任何警告,但是什么也没发生

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>

#define _XOPEN_SOURCE ;

int recursion = 0; //1 if enabled, otherwise 0
int sleepTime = 300;
int fileLimit = 0;
int signaL = 0;
int exitSignal = 0;
int buffer = 1000;

//Returns 0 if arguments are correct otherwise returns 1
int readArguments(int number, char **argv, char *source, char *goal);
int checkFileType(struct stat file);
int copy(char *source, char *target, mode_t mask);
int copy_map(char *source, char *target, struct stat *Source);
void syncCopy(char *source, char *target);
void syncRemove(char *source, char *target);


void my_handler(int sig)
{
    syslog(LOG_INFO, "Daemon received signal SIGUSR1\n");
    signaL = 1;
}

void exitFunction(int sig)
{
    syslog(LOG_INFO, "Daemon received signal SIGUSR2\n");
    exitSignal = 1;
}
int main(int argc, char **argv)
{
    //char tables for paths
    char source[500], goal[500];
    struct stat Source, Goal;
    struct sigaction my_action, old_action;

    //checking and reading arguments
    if (readArguments(argc, argv, source, goal) == 1)
        exit(-1);

    //checking paths

    //checking  if argv[1] and argv[2] are existing paths
    if (lstat(source, &Source) != 0 || lstat(goal, &Goal) != 0) //bad result
    {
        printf("One of the paths or both dont exist\n");
        exit(-1);
    }

    if (checkFileType(Source) != 0)
    {
        printf("Source path is not path to folder");
        exit(-1);
    }

    if (checkFileType(Goal) != 0)
    {
        printf("Goal path is not path to folder");
        exit(-1);
    }

    //forking the parent process
    pid_t pid;
    // Fork off the parent process  and create new
    pid = fork();
    //if failure
    if (pid < 0)
    {
        exit(-1);
    }
    // if it is native process
    else if (pid > 0)
    {
        return 0;
    }
    //if pid==0 then it is childs process

    //now we have to umask in order to write to any files(for exmaple logs)

    umask(0);
    openlog("logFile", LOG_PID, LOG_DAEMON);
    syslog(LOG_INFO, "Deamon has just started running\n");

    pid_t sid = setsid();
    if (sid < 0)
    {
        syslog(LOG_ERR, "Error with session opening\n");
        exit(-1);
    }

    //SIGNAL SIGUSR1
    my_action.sa_handler = my_handler;
    sigfillset(&my_action.sa_mask);
    my_action.sa_flags = 0;
    if (sigaction(SIGUSR1, &my_action, &old_action) < 0)
    {
        syslog(LOG_ERR, "Error with the use of  SIGUSR1 signal\n");
        exit(-1);
    }

    //SIGNAL SIGUSR2 for exiting daemon
    my_action.sa_handler = exitFunction;
    sigfillset(&my_action.sa_mask);
    my_action.sa_flags = 0;
    if (sigaction(SIGUSR2, &my_action, &old_action) < 0)
    {
        syslog(LOG_ERR, "Error with the use of  SIGUSR2 signal\n");
        exit(-1);
    }

    while (!exitSignal)
    {
        sleep(sleepTime);
        switch (signaL)
        {
        case 0:
            syslog(LOG_INFO, "Demon started working after %ds\n", sleepTime);
            break;

        case 1:
        {
            syslog(LOG_INFO, "Demon started working after SIGUSR1 signal\n");
            signaL = 0; //Need to reeset signaL
            break;
        }
        }

        syncCopy(source, goal);
        syncRemove(source, goal);
        syslog(LOG_INFO, "Demon has just  gone to sleep");
    }

    //at the end of program we need to close log using
    syslog(LOG_INFO, "Demon has stopped\n");
    closelog();

    return 0;
}

1 个答案:

答案 0 :(得分:0)

将命令用作kill -10 <pid>的{​​{1}}和SIGUSR1的{​​{1}}。

kill -12 <pid>

还将变量SIGUSR2 kill -l // command to know the signal number. 设置为signaL类型。

为什么 exitSignal

当在某些其他函数中定期检查在信号处理程序中更新的全局变量以采取适当措施时,我们应始终使用volatile属性声明它们,以防止编译器执行导致变量存储在寄存器中的优化。在最坏的情况下,变量的更新值(在处理程序上下文中更新)对于函数轮询变量是不可见的。

为什么 volatile sig_atomic_t

读取和写入全局变量可能涉及多个机器语言指令,并且信号处理程序可能会在这样的指令序列中间中断主程序。 (我们说对变量的访问是非原子的。)因此,C语言标准和SUSv3指定了整数数据类型volatile,对于该数据类型,读写保证是原子的。因此,应声明主程序和信号处理程序之间共享的全局标志变量,如下所示:

  

volatile sig_atomic_t信号;