Subject: syslogd does not always disassociate from console (#418)
Index:	usr.sbin/syslogd.c 2.11BSD

Description:
	1. When the system enters multiuser state from a boot the syslog
	   daemon does not disassociate from the console - if a "ps ax"
	   is done syslogd shows up as having 'co' as a control tty.

	2. Porting programs from a 4.4BSD environment pointed out a couple
	   missing declarations in system header files.

Repeat-By:
	1.  Observation.  If syslogd is killed and restarted then it does
	    properly drop into the background as a daemon process should.

	2.  Attempt to compile a program that references 'h_errno' or
	    the getopt(3) external variables 'optind', 'optarg', 'optopt',
	    or 'opterr'.  Note that including unistd.h does not cause
	    the errors to go away.

Fix:
	1. There was apparently an interaction in the existing "daemon"ize
	   code that did not work properly when syslogd was started from
	   /etc/rc.  The fix was to use the libc provided "daemon(3)" 
	   routine.  At the same time (as long as changes were being made)
	   the signal handling was cleaned up (modernized) to use 
	   sigaction() and sigprocmask() calls.

	2.  h_errno  was accidentally omitted from 'netdb.h'.  There was a
	    comment referencing h_errno but the actual 'extern' declaration
	    was missing.  

	    When unistd.h was added to the system a little while back the
	    getopt(3) declarations were overlooked.  They have been added
	    now to ease porting efforts.

	To apply this update cut where indicated and save to a file (/tmp/418).

	Then:

		patch -p0 < /tmp/418
		cd /usr/src/usr.sbin/syslogd
		make 
		make install
		make clean
		kill `cat /var/run/syslog.pid`
		syslogd

	As always this and previous updates to 2.11BSD are available via
	anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the
	directory /pub/2.11BSD.

--------------------------cut here--------------------------
*** /usr/include/netdb.h.old	Wed Jul 10 20:01:54 1996
--- /usr/include/netdb.h	Tue May 25 20:09:58 1999
***************
*** 9,16 ****
   * software without specific prior written permission. This software
   * is provided ``as is'' without express or implied warranty.
   *
!  *	@(#)netdb.h	5.9.2 (2.11BSD GTE) 96/7/10
   */
  
  /*
   * Structures returned by network
--- 9,18 ----
   * software without specific prior written permission. This software
   * is provided ``as is'' without express or implied warranty.
   *
!  *	@(#)netdb.h	5.9.3 (2.11BSD) 99/5/25
   */
+ 
+ extern	int	h_errno;
  
  /*
   * Structures returned by network
*** /usr/include/unistd.h.old	Fri Oct  3 12:14:14 1997
--- /usr/include/unistd.h	Tue May 25 20:13:50 1999
***************
*** 30,36 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)unistd.h	8.10.3 (2.11BSD) 1997/10/3
   */
  
  /*
--- 30,36 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)unistd.h	8.10.4 (2.11BSD) 1999/5/25
   */
  
  /*
***************
*** 89,93 ****
--- 89,96 ----
  unsigned int	 ualarm();
  void	 usleep();
  pid_t	 vfork();
+ 
+ extern	char	*optarg;		/* getopt(3) external variables */
+ extern	int	opterr, optind, optopt;
  
  #endif /* !_UNISTD_H_ */
*** /usr/src/usr.sbin/syslogd/syslogd.c.old	Sat Nov 16 21:19:01 1996
--- /usr/src/usr.sbin/syslogd/syslogd.c	Thu May 27 21:55:56 1999
***************
*** 9,15 ****
  "@(#) Copyright (c) 1983 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)syslogd.c	5.13.4 (2.11BSD GTE) 1996/11/16";
  #endif
  
  /*
--- 9,15 ----
  "@(#) Copyright (c) 1983 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)syslogd.c	5.13.5 (2.11BSD) 1999/5/27";
  #endif
  
  /*
***************
*** 140,145 ****
--- 140,146 ----
  int	Initialized = 0;	/* set when we have initialized ourselves */
  int	MarkInterval = 20;	/* interval between marks in minutes */
  int	MarkSeq = 0;		/* mark sequence number */
+ static	sigset_t block_set;	/* Signals to block while logging */
  
  main(argc, argv)
  	int argc;
***************
*** 152,159 ****
  	struct sockaddr_un sun, fromunix;
  	struct sockaddr_in sin, frominet;
  	FILE *fp;
  	char line[MSG_BSIZE + 1];
! 	extern int die(), domark(), reapchild();
  
  	while (--argc > 0) {
  		p = *++argv;
--- 153,163 ----
  	struct sockaddr_un sun, fromunix;
  	struct sockaddr_in sin, frominet;
  	FILE *fp;
+ 	struct itimerval itv;
+ 	sigset_t oset;
+ 	struct sigaction sigact;
  	char line[MSG_BSIZE + 1];
! 	extern int die(), domark(), reapchild(), init();
  
  	while (--argc > 0) {
  		p = *++argv;
***************
*** 184,201 ****
  		}
  	}
  
! 	if (!Debug) {
! 		if (fork())
! 			exit(0);
! 		for (i = 0; i < 10; i++)
! 			(void) close(i);
! 		(void) open("/", 0);
! 		(void) dup2(0, 1);
! 		(void) dup2(0, 2);
! 		untty();
! 	} else
  		setlinebuf(stdout);
  
  	(void) gethostname(LocalHostName, sizeof LocalHostName);
  	if (p = index(LocalHostName, '.')) {
  		*p++ = '\0';
--- 188,232 ----
  		}
  	}
  
! 	/* Init signal block set and block signals */
! 	(void)sigemptyset(&block_set);
! 	(void)sigaddset(&block_set, SIGHUP);
! 	(void)sigaddset(&block_set, SIGALRM);
! 	sigprocmask(SIG_BLOCK, &block_set, &oset);
! 
! 	/* Setup signals */
! 	sigact.sa_mask = block_set;
! 	sigact.sa_flags = SA_NOCLDSTOP;
! 	sigact.sa_handler = reapchild;
! 	sigaction(SIGCHLD, &sigact, NULL);
! 
! 	sigact.sa_flags = 0;
! 	sigact.sa_handler = die;
! 	sigaction(SIGTERM, &sigact, NULL);
! 
! 	if	(!Debug)
! 		sigact.sa_handler = SIG_IGN;
! 	sigaction(SIGINT, &sigact, NULL);
! 	sigaction(SIGQUIT, &sigact, NULL);
! 
! 	sigact.sa_handler = init;
! 	sigaction(SIGHUP, &sigact, NULL);
! 
! 	sigact.sa_handler = domark;
! 	sigaction(SIGALRM, &sigact, NULL);
! 
! 	if	(!Debug)
! 		daemon(0, 0);
! 	else
  		setlinebuf(stdout);
  
+ 	/* Initialize timer */
+ 	itv.it_interval.tv_sec = MarkInterval * 60 / MARKCOUNT;
+ 	itv.it_interval.tv_usec = 0;
+ 	itv.it_value.tv_sec = MarkInterval * 60 / MARKCOUNT;
+ 	itv.it_value.tv_usec = 0;
+ 	setitimer(ITIMER_REAL, &itv, NULL);
+ 
  	(void) gethostname(LocalHostName, sizeof LocalHostName);
  	if (p = index(LocalHostName, '.')) {
  		*p++ = '\0';
***************
*** 203,214 ****
  	}
  	else
  		LocalDomain = "";
! 	(void) signal(SIGTERM, die);
! 	(void) signal(SIGINT, Debug ? die : SIG_IGN);
! 	(void) signal(SIGQUIT, Debug ? die : SIG_IGN);
! 	(void) signal(SIGCHLD, reapchild);
! 	(void) signal(SIGALRM, domark);
! 	(void) alarm(MarkInterval * 60 / MARKCOUNT);
  	(void) unlink(LogName);
  
  	sun.sun_family = AF_UNIX;
--- 234,240 ----
  	}
  	else
  		LocalDomain = "";
! 
  	(void) unlink(LogName);
  
  	sun.sun_family = AF_UNIX;
***************
*** 259,267 ****
  
  	dprintf("off & running....\n");
  
! 	init();
! 	(void) signal(SIGHUP, init);
  
  	for (;;) {
  		int nfds;
  		u_long readfds = FDMASK(funix) | inetm | klogm;
--- 285,295 ----
  
  	dprintf("off & running....\n");
  
! 	init(0);
  
+ 	/* Unblock signals now */
+ 	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ 
  	for (;;) {
  		int nfds;
  		u_long readfds = FDMASK(funix) | inetm | klogm;
***************
*** 433,439 ****
  	register int l;
  	int fac, prilev;
  	time_t now;
! 	long omask;
  	struct iovec iov[6];
  	register struct iovec *v = iov;
  	char line[MAXLINE + 1];
--- 461,467 ----
  	register int l;
  	int fac, prilev;
  	time_t now;
! 	sigset_t oset;
  	struct iovec iov[6];
  	register struct iovec *v = iov;
  	char line[MAXLINE + 1];
***************
*** 440,446 ****
  
  	dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n", pri, flags, from, msg);
  
! 	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM));
  
  	/*
  	 * Check to see if msg looks non-standard.
--- 468,474 ----
  
  	dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n", pri, flags, from, msg);
  
! 	(void)sigprocmask(SIG_BLOCK, &block_set, &oset);
  
  	/*
  	 * Check to see if msg looks non-standard.
***************
*** 456,463 ****
  			/* we found a match, update the time */
  			(void) strncpy(PrevLine, msg, 15);
  			PrevCount++;
! 			(void) sigsetmask(omask);
! 			return;
  		} else {
  			/* new line, save it */
  			flushmsg();
--- 484,490 ----
  			/* we found a match, update the time */
  			(void) strncpy(PrevLine, msg, 15);
  			PrevCount++;
! 			goto out;
  		} else {
  			/* new line, save it */
  			flushmsg();
***************
*** 508,515 ****
  			(void) close(cfd);
  		}
  		untty();
! 		(void) sigsetmask(omask);
! 		return;
  	}
  	for (f = Files; f < &Files[NLOGS]; f++) {
  		/* skip messages that are incorrect priority */
--- 535,541 ----
  			(void) close(cfd);
  		}
  		untty();
! 		goto out;
  	}
  	for (f = Files; f < &Files[NLOGS]; f++) {
  		/* skip messages that are incorrect priority */
***************
*** 591,598 ****
  			break;
  		}
  	}
! 
! 	(void) sigsetmask(omask);
  }
  
  
--- 617,624 ----
  			break;
  		}
  	}
! out:
! 	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
  }
  
  
***************
*** 721,733 ****
  
  domark()
  {
- 	int pri;
  
  	if ((++MarkSeq % MARKCOUNT) == 0)
  		logmsg(LOG_INFO, "-- MARK --", LocalHostName, ADDDATE|MARK);
  	else
  		flushmsg();
- 	alarm(MarkInterval * 60 / MARKCOUNT);
  }
  
  flushmsg()
--- 747,757 ----
***************
*** 776,782 ****
   *  INIT -- Initialize syslogd from configuration table
   */
  
! init()
  {
  	register int i;
  	register FILE *cf;
--- 800,808 ----
   *  INIT -- Initialize syslogd from configuration table
   */
  
! /* ARGSUSED */
! init(sig)
! 	int	sig;		/* signal number */
  {
  	register int i;
  	register FILE *cf;
***************
*** 959,966 ****
  
  		/* scan facilities */
  		while (*p && !index("\t.;", *p)) {
- 			int i;
- 
  			for (bp = buf; *p && !index("\t,;.", *p); )
  				*bp++ = *p++;
  			*bp = '\0';
--- 985,990 ----
***************
*** 997,1004 ****
  		(void) strcpy(f->f_un.f_forw.f_hname, ++p);
  		hp = gethostbyname(p);
  		if (hp == NULL) {
- 			char buf[100];
- 
  			(void) sprintf(buf, "unknown host %s", p);
  			errno = 0;
  			logerror(buf);
--- 1021,1026 ----
*** /VERSION.old	Fri May  7 19:40:01 1999
--- /VERSION	Sun May 30 09:27:25 1999
***************
*** 1,5 ****
! Current Patch Level: 417
! Date: May 7, 1999
  
  2.11 BSD
  ============
--- 1,5 ----
! Current Patch Level: 418
! Date: May 27, 1999
  
  2.11 BSD
  ============
