9
9
#include " ipc/ipc.h"
10
10
#include " ipc/debug.h"
11
11
12
+ #define len (array ) (int )(sizeof (array) / sizeof (array[0 ]))
13
+
12
14
typedef struct
13
15
{
14
16
const char * const name;
15
- int respawn; // -1 = infinite , 0 = never, 1 = once, 2 = twice, etc.
17
+ int respawn; // respawn on error: -1 = infinite , 0 = never, 1 = once, 2 = twice, etc.
16
18
17
19
// internal
18
20
pid_t pid;
@@ -26,17 +28,20 @@ child children[] =
26
28
// ==================== FILL IN PROCESSES ====================
27
29
{
28
30
.name = " /usr/bin/cpp_ipc_brief_demo_prod" ,
29
- .respawn = 1 ,
31
+ .respawn = - 1 ,
30
32
},
31
33
{
32
34
.name = " /usr/bin/cpp_ipc_brief_demo_cons" ,
33
35
.args = { " --my_option" , " --my_other_option" , },
34
36
},
35
37
// ===========================================================
36
38
};
39
+ #define n_children len (children)
37
40
38
- #define n_children (int )(sizeof (children) / sizeof (children[0 ]))
39
- #define lengthof (var ) (sizeof (var) / sizeof (var[0 ]))
41
+ // ==================== STATUSES THAT BYPASS RESPAWN =========
42
+ // Children that are configured to respawn will not be respawned if they return with these statuses:
43
+ int respawn_bypass_statuses[] = { 0 , SIGINT };
44
+ // ===========================================================
40
45
41
46
int fork_child (child *c)
42
47
{
@@ -50,11 +55,11 @@ int fork_child(child *c)
50
55
51
56
setpgid (0 , 0 ); // switch process group so ctrl-c only interrupts god
52
57
53
- char * child_argv[lengthof (c->args ) + 2 ];
58
+ char * child_argv[len (c->args ) + 2 ];
54
59
child_argv[0 ] = (char *)(c->name );
55
- for (int i=0 ; i < lengthof (c->args ); ++i)
60
+ for (int i=0 ; i < len (c->args ); ++i)
56
61
child_argv[i+1 ] = c->args [i];
57
- child_argv[lengthof (c->args ) + 1 ] = NULL ;
62
+ child_argv[len (c->args ) + 1 ] = NULL ;
58
63
59
64
execv (c->name , child_argv);
60
65
}
@@ -107,13 +112,22 @@ void child_handler(int sig)
107
112
c->alive = 0 ;
108
113
debug (" child %u (%s) exited with status %d\n " , c->pid , c->name , status);
109
114
110
- if (c->respawn != 0 )
115
+ if (( c->respawn != 0 ) )
111
116
{
112
- debug (" respawning child\n " );
113
- fork_child (c);
117
+ int bypass_statuses = 0 ;
118
+ for (int i=0 ; i < len (respawn_bypass_statuses); ++i)
119
+ if (status == respawn_bypass_statuses[i])
120
+ ++bypass_statuses;
121
+
122
+ if (bypass_statuses)
123
+ debug (" respawn bypassed\n " );
124
+ else
125
+ {
126
+ debug (" respawning child\n " );
127
+ fork_child (c);
114
128
115
- if (c->respawn > 0 )
116
129
--c->respawn ;
130
+ }
117
131
}
118
132
}
119
133
0 commit comments