Я пытаюсь создать программу, которая имитирует команду nohup. Программа получает в качестве первого параметра имя команды, которая должна быть выполнена.
Программа, выполняемая моей программой, не должна уведомляться при закрытии терминала, она должна игнорировать SIGHUP.
Если я проверю свою программу с помощью следующей команды:
./mynohup sleep 120 &
И затем я пытаюсь отправить SIGHUP с другого терминала, сон прерывается, когда он должен быть защищен от него.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include "utils.h"
#define NOHUP_OUT_FILE "nohup.out"
static void handle_signal(int signum)
{
if(signum == SIGHUP)
{
printf("This is ignored\n");
}
else
{
printf("Not ignored\n");
}
fflush(stdout);
}
/* configure handlers */
static void set_signals(void)
{
struct sigaction sa;
int rc;
/* TODO - ignore SIGHUP */
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = handle_signal;
rc = sigaction(SIGHUP, &sa, NULL);
DIE(rc == -1, "sigaction");
}
/* execute a new program */
static void exec_func(int argc, char **argv)
{
int rc;
int i;
char **exec_args;
int fd;
set_signals(); /* ignore SIGHUP */
if(isatty(STDOUT_FILENO))
{
fd = open(NOHUP_OUT_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
DIE(fd < 0, "open");
dup2(fd, STDOUT_FILENO);
close(fd);
}
/* exec a new process */
exec_args = malloc(argc * sizeof(*exec_args));
DIE(exec_args == NULL, "malloc");
for (i = 0; i < argc-1; i++)
exec_args[i] = argv[i+1];
exec_args[argc-1] = NULL;
execvp(exec_args[0], exec_args);
DIE(1, "execvp");
}
int main(int argc, char **argv)
{
if (argc <= 1) {
fprintf(stderr, "Usage: %s command_and_arguments\n", argv[0]);
exit(EXIT_FAILURE);
}
exec_func(argc, argv);
return 0;
}
Я попытался пропустить создание нового процесса, и обработчик сигнала работает отлично.
Если обработчик сигнала имеет следующую форму, программа работает
static void set_signals(void)
{
struct sigaction sa;
int rc;
/* ignore SIGHUP */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
rc = sigaction(SIGHUP, &sa, NULL);
DIE(rc == -1, "sigaction");
}
Я не понимаю, почему, когда я создаю первую версию обработчика сигнала, программа не работает, а со второй она работает.
Заранее спасибо!