old deadnntpd's, and getpeername

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




First, a hello to the other 3 people actually on this list, thanks
for writing!

Further thoughts on getpeername and select in sockets.c.  Do both!  Best
of both worlds!

  if ((select (scfg->fd + 1, &rdfs, NULL, NULL, &tv) == 0) && 
     (getpeername (scfg->fd, (struct sockaddr *) &sa, &sa_len) == 0))

And now onto the bug-du-jour...

I was getting dead nntpcached's piling up on our system, probably from
when dialup users disconnected (as in hung up).  They were all getting
stuck doing the final flush of their stdout.  Here is a patch that
fixes it.  Two caveats.  I wrote it at 2am, so I was more interested in
"correct" than "fancy".  I was almost going to add some state to the
local alarm handling code, so that it could call itself it it bombed
out in itself, and log an error and then _exit.  Well, I didn't, it was
2AM.  Also added a little protection for an alarm getting raised in 
a term and vice versa.

The second caveat is that I only fixed the hang in the part of Exit
that actually was hanging.  Although it's been running for awhile with
no new dead processes, it's possible that it'll find some new place to
hang further up in Exit and I'll have to protect that too.  So far, there
hasn't been, this code works great!

Oops, third caveat.  On my system, the behavior of signal depend on
which libraires you link in.  If it seems like I'm being pedantic and
setting things that would normaly default that way, that's why.  That's 
also why I'm using sigaction instead of signal.

Ok, here it is!

*** nntpcache-1.0.7.1-stat2-REF/nntpcache.c	Fri Aug 29 03:15:16 1997
--- nntpcache-1.0.7.1-stat2/nntpcache.c	Mon Sep 01 09:08:52 1997
***************
*** 185,191 ****
--- 188,204 ----
  
  X (void Exit (int code))
  {
+ #ifdef ORIG
  	flush ();
+ #else
+ 	sigset_t set;
+ 	struct sigaction action;
+ 	/* don't let anyone interrupt us */
+ 	sigemptyset(&set);
+ 	sigaddset(&set, SIGALRM);
+ 	sigaddset(&set, SIGTERM);
+ 	sigprocmask (SIG_BLOCK, &set, NULL);
+ #endif
  	if (!Daemon || InDaemon)
  	{
  		dbzsync ();
***************
*** 231,236 ****
--- 244,267 ----
  		mmalloc_detach (Mbase);
  #endif
  	closelog ();
+ 
+ #ifndef ORIG
+ 	/* restore default SIGALRM behavior (ie, crash us out) */
+ 	sigemptyset(&action.sa_mask);
+ 	sigaddset(&action.sa_mask, SIGALRM);
+ 	action.sa_flags = 0;
+ 	action.sa_handler = SIG_DFL;
+ 	sigaction(SIGALRM, &action, NULL);
+ 
+ 	/* unblock, since we might be in a SIGALRM handler right now! */
+ 	sigemptyset(&set);
+ 	sigaddset(&set, SIGALRM);
+ 	sigprocmask (SIG_UNBLOCK, &set, NULL);
+ 
+ 	alarm(60);
+ 	flush ();	/* better finish this in 60 seconds, toots. */
+ 	logd (("clean shutdown."));
+ #endif
  	exit (code);
  }
  
***************
*** 680,685 ****
--- 711,720 ----
  	/* init_mmalloc(NULL); */
  #endif
  
+ #ifndef ORIG
+ 	struct sigaction myaction;
+ #endif
+ 
  	if (strstr (VERSION, "UL"))
  		fprintf (stderr, "\
  NOTE:    This version of NNTPCACHE is unlicensed. Government and\n\
***************
*** 842,848 ****
--- 877,892 ----
  		Exit (1);
  	}
  	logd(("cwd now %s", con.cacheDir));
+ #ifdef ORIG
  	signal (SIGTERM, sigterm);
+ #else
+ 	sigemptyset(&myaction.sa_mask);
+ 	sigaddset(&myaction.sa_mask, SIGTERM);
+ 	sigaddset(&myaction.sa_mask, SIGALRM);
+ 	myaction.sa_flags = 0;
+ 	myaction.sa_handler = sigterm;
+ 	sigaction(SIGTERM, &myaction, NULL);
+ #endif
  	signal (SIGINT, sigint);
  	signal (SIGSEGV, sigsegv);
  	signal (SIGFPE, SIG_IGN);
***************
*** 1096,1106 ****
--- 1144,1176 ----
  #endif
  #endif
  	}
+ #ifdef ORIG
  	signal(SIGALRM, sigalrm);
+ #else
+ 	sigemptyset(&myaction.sa_mask);
+ 	sigaddset(&myaction.sa_mask, SIGALRM);
+ 	sigaddset(&myaction.sa_mask, SIGTERM);
+ 	myaction.sa_flags = 0;
+ 	myaction.sa_handler = sigalrm;
+ 	sigaction(SIGALRM, &myaction, NULL);
+ #endif
  	alarm(con.idleTimeout);





[Index of Archives]     [Yosemite]     [Yosemite Campsites]     [Bugtraq]     [Linux]     [Trn]

Powered by Linux