Browse code

- fixed kill all process group when not having our own group bug :-) : (this would kill the calling script if ser exits before forking, e.g config parse error) -- added kill_all_children instead of kill(0, sig).

kill_all_children comment:

* tries to send a signal to all our processes
* if daemonized is ok to send the signal to all the process group,
* however if not daemonized we might end up sending the signal also
* to the shell which launched us => most signals will kill it if
* it's not in interactive mode and we don't want this. The non-daemonized
* case can occur when an error is encountered before daemonize is called
* (e.g. when parsing the config file) or when ser is started in "dont-fork"
* mode. Sending the signal to all the processes in pt[] will not work
* for processes forked from modules (which have no correspondent entry in
* pt), but this can happen only in dont_fork mode (which is only for
* debugging). So in the worst case + "dont-fork" we might leave some
* zombies

Andrei Pelinescu-Onciul authored on 28/06/2003 17:10:36
Showing 2 changed files
... ...
@@ -40,7 +40,7 @@ export makefile_defs
40 40
 VERSION = 0
41 41
 PATCHLEVEL = 8
42 42
 SUBLEVEL =   11
43
-EXTRAVERSION = pre34
43
+EXTRAVERSION = pre35
44 44
 
45 45
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
46 46
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -40,6 +40,8 @@
40 40
  *               after daemonize (so that we won't catch anymore our own
41 41
  *               SIGCHLD generated when becoming session leader) (andrei)
42 42
  *              changed is_main default value to 1 (andrei)
43
+ *  2003-06-28  kill_all_children is now used instead of kill(0, sig)
44
+ *                see comment above it for explanations. (andrei)
43 45
  *
44 46
  */
45 47
 
... ...
@@ -257,6 +259,8 @@ void receive_stdin_loop()
257 259
 
258 260
 /* global vars */
259 261
 
262
+int own_pgid = 0; /* whether or not we have our own pgid (and it's ok
263
+					 to use kill(0, sig) */
260 264
 char* cfg_file = 0;
261 265
 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
262 266
 												  not want to exceed durig the
... ...
@@ -434,6 +438,8 @@ int daemonize(char*  name)
434 438
 	/* become session leader to drop the ctrl. terminal */
435 439
 	if (setsid()<0){
436 440
 		LOG(L_WARN, "setsid failed: %s\n",strerror(errno));
441
+	}else{
442
+		own_pgid=1; /* we have our own process group */
437 443
 	}
438 444
 	/* fork again to drop group  leadership */
439 445
 	if ((pid=fork())<0){
... ...
@@ -509,6 +515,29 @@ error:
509 515
 
510 516
 
511 517
 
518
+/* tries to send a signal to all our processes
519
+ * if daemonized  is ok to send the signal to all the process group,
520
+ * however if not daemonized we might end up sending the signal also
521
+ * to the shell which launched us => most signals will kill it if 
522
+ * it's not in interactive mode and we don't want this. The non-daemonized 
523
+ * case can occur when an error is encountered before daemonize is called 
524
+ * (e.g. when parsing the config file) or when ser is started in "dont-fork"
525
+ *  mode. Sending the signal to all the processes in pt[] will not work
526
+ *  for processes forked from modules (which have no correspondent entry in 
527
+ *  pt), but this can happen only in dont_fork mode (which is only for
528
+ *  debugging). So in the worst case + "dont-fork" we might leave some
529
+ *  zombies. -- andrei */
530
+static void kill_all_children(int signum)
531
+{
532
+	int r;
533
+	if (own_pgid) kill(0, signum);
534
+	else if (pt)
535
+		for (r=1; r<process_count(); r++)
536
+			if (pt[r].pid) kill(pt[r].pid, signum);
537
+}
538
+
539
+
540
+
512 541
 void handle_sigs()
513 542
 {
514 543
 	pid_t	chld;
... ...
@@ -531,7 +560,7 @@ void handle_sigs()
531 560
 				DBG("SIGTERM received, program terminates\n");
532 561
 				
533 562
 			/* first of all, kill the children also */
534
-			kill(0, SIGTERM);
563
+			kill_all_children(SIGTERM);
535 564
 
536 565
 			     /* Wait for all the children to die */
537 566
 			while(wait(0) > 0);
... ...
@@ -581,7 +610,7 @@ void handle_sigs()
581 610
 			LOG(L_INFO, "INFO: terminating due to SIGCHLD\n");
582 611
 #endif
583 612
 			/* exit */
584
-			kill(0, SIGTERM);
613
+			kill_all_children(SIGTERM);
585 614
 			while(wait(0) > 0); /* wait for all the children to terminate*/
586 615
 			cleanup(1); /* cleanup & show status*/
587 616
 			DBG("terminating due to SIGCHLD\n");
... ...
@@ -1682,14 +1711,14 @@ try_again:
1682 1711
 	
1683 1712
 	ret=main_loop();
1684 1713
 	/*kill everything*/
1685
-	kill(0, SIGTERM);
1714
+	kill_all_children(SIGTERM);
1686 1715
 	/*clean-up*/
1687 1716
 	cleanup(0);
1688 1717
 	return ret;
1689 1718
 
1690 1719
 error:
1691 1720
 	/*kill everything*/
1692
-	kill(0, SIGTERM);
1721
+	kill_all_children(SIGTERM);
1693 1722
 	/*clean-up*/
1694 1723
 	cleanup(0);
1695 1724
 	return -1;