Project

General

Profile

HowToRunLightyWithRunit ยป sigintwrap.c

signal wrapper for graceful restart - zikzik, 2007-01-15 23:48

 
1
/*
2

    
3
SIGINT wrapper for lighttpd graceful restart feature under runit.
4
by Zik 
5

    
6
("inspired by" execwrap by Sune Foldager) */
7

    
8

    
9

    
10
/* Errors */
11

    
12
#define RC_TARGET               13
13
#define RC_SIGNAL_HANDLER       15
14
#define RC_EXEC                 23
15
#define RC_BAD_OPTION           24
16

    
17

    
18
/* INC */
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <string.h>
22
#include <sys/stat.h>
23
#include <unistd.h>
24
#include <signal.h>
25

    
26

    
27
/* Child PID */
28
int pid;
29

    
30

    
31
/* sighandler */
32
void sigHandler(int signal)
33
{
34
    /* Not forked yet */
35
    if (!pid)
36
	return;
37

    
38
    switch( signal )
39
    {
40
	case SIGHUP:
41
	case SIGUSR1:
42
	case SIGUSR2:
43
	    /* Forward to child */
44
	    kill( pid, signal );
45
	    break;
46
	    
47
	case SIGINT:
48
	    /* Forward signal and we exit */
49
	    kill( pid, SIGINT );
50
	    _exit( 0 );
51

    
52
	case SIGTERM:
53
	    /* Transform to graceful stop */
54
	    kill( pid, SIGINT );
55
	    break;
56
  
57
	case SIGQUIT:
58
	    /* Mapped to SIGTERM */
59
	    kill( pid, SIGTERM );
60
	    break;
61
	    
62
	/* No SIGKILL. We could map some other signal to sigkill, but it seems pointless. */
63
    }
64
}
65

    
66

    
67

    
68
void checkSignal( void *res )
69
{
70
    if ( res == SIG_ERR )
71
    {
72
	fprintf( stderr, "Error setting up signal handler" );
73
	exit( RC_SIGNAL_HANDLER );
74
    }
75
}
76

    
77

    
78
int main(int argc, char* argv[], char* envp[])
79
{
80

    
81
  /* Command line args */
82
  if(argc < 2)
83
  {
84
    fprintf( stderr, "Usage:\t%s target [options]\n", argv[0] );
85
    return( -1 );
86
  }
87

    
88
  char* target = argv[1];
89
  
90
  /* Install the signal handler */
91
  checkSignal( signal(SIGHUP,	sigHandler));
92
  checkSignal( signal(SIGINT,	sigHandler));
93
  checkSignal( signal(SIGQUIT,	sigHandler));
94
  checkSignal( signal(SIGTERM,	sigHandler));
95
  checkSignal( signal(SIGUSR1,	sigHandler));
96
  checkSignal( signal(SIGUSR2,	sigHandler));
97
  checkSignal( signal(SIGPIPE,	SIG_IGN));
98
  checkSignal( signal(SIGALRM,	SIG_IGN));
99

    
100
  /* Fork */
101
  if (!(pid = fork()))
102
  {
103
    /* execute */
104
    execve(target, & argv[1], envp);
105
    fprintf( stderr, "Error executing target: %s", target );
106
    return RC_EXEC;
107
  }
108

    
109
  /* Wait for the child to exit then return. (Or we exit from signal handler.) */
110
  int status;
111
  wait(&status);
112
  return status;
113

    
114
}
115

    
    (1-1/1)