Subject: new slattach program (slip_attach)
To: None <current-users@NetBSD.ORG>
From: VaX#n8 <vax@ccwf.cc.utexas.edu>
List: current-users
Date: 01/13/1995 21:43:28
I've been trying to get a slip-maintaining program to work, and needed
slattach to clean up after itself.  Here is what I wrote to fix this.
It's my first attempt at signal handling from C, as well as hard-core
termio stuff.  Comments are welcome.
PS: currently, my slip program can dial out again (after having slip die
once), but it can't read any chars from the port.  Any idea why?
Diffs are same size as original (almost), so whole file is here.
Changes:
	1) signal handling added
	2) old tty attributes saved & restored
	3) slip disc restored to termio discipline
	4) 'f' option (foreground mode) added.
Problems:
	1) DTR not lowered, even though code explicitly clears it
	2) some problems reading from device later

/*
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Rick Adams.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1988, 1993\n\
	The Regents of the University of California.  All rights reserved.\n";
#endif /* not lint */

#ifndef lint
/*static char sccsid[] = "from: @(#)slattach.c	8.2 (Berkeley) 1/7/94";*/
static char *rcsid = "$Id: slattach.c,v 1.14 1994/12/18 00:26:34 cgd Exp $";
#endif /* not lint */

#include <sys/param.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>

#include <net/if.h>
#include <netinet/in.h>

#include <err.h>
#include <fcntl.h>
#include <netdb.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

static int	speed = 9600;
static int	slipdisc = SLIPDISC;

static char	devicename[PATH_MAX];

static struct termios	old_tty_values;
static int	fd;

void	usage __P((void));
static void	handler __P((int signo, int code, struct sigcontext *scp));

int
main(argc, argv)
	int argc;
	char *argv[];
{
	register char *dev;
	struct termios tty;
	tcflag_t cflag = HUPCL;
	int ch;
	short foreground_mode = 0;
	pid_t pid;
	struct sigaction act;

	while ((ch = getopt(argc, argv, "fhms:")) != -1) {
		switch (ch) {
		case 'f':
			foreground_mode = 1;
			break;
		case 'h':
			cflag |= CRTSCTS;
			break;
		case 'm':
			cflag &= ~HUPCL;
			break;
		case 's':
			speed = atoi(optarg);
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 1)
		usage();

	dev = *argv;
	if (strncmp(_PATH_DEV, dev, sizeof(_PATH_DEV) - 1)) {
		(void)snprintf(devicename, sizeof(devicename),
		    "%s%s", _PATH_DEV, dev);
		dev = devicename;
	}
	if ((fd = open(dev, O_RDWR | O_NONBLOCK)) < 0)
		err(1, dev);

	if (tcgetattr(fd,&old_tty_values) < 0)
		err(1, "getting terminal attributes");

	tty = old_tty_values;
	tty.c_cflag = CREAD | CS8 | cflag;
	tty.c_iflag = 0;
	tty.c_lflag = 0;
	tty.c_oflag = 0;
	tty.c_cc[VMIN] = 1;
	tty.c_cc[VTIME] = 0;

	/* set up signal handler to restore tty state */
	act.sa_handler = handler;
	sigemptyset(&act.sa_mask);
	sigaddset(&act.sa_mask,SIGINT);
	sigaddset(&act.sa_mask,SIGQUIT);
	sigaddset(&act.sa_mask,SIGTERM);
	act.sa_flags = 0;

	if (sigaction(SIGHUP,&act,NULL) < 0)
		err(1, "sigaction");

	cfsetspeed(&tty, speed);
	if (tcsetattr(fd, TCSADRAIN, &tty) < 0)
		err(1, "tcsetattr");

	if (ioctl(fd, TIOCSDTR, 0) < 0)
		err(1, "TIOCSDTR");
	if (ioctl(fd, TIOCSETD, &slipdisc) < 0)
		err(1, "TIOCSETD");

	if (!foreground_mode) {
		if ((pid = fork()) < 0)
			err(1,"fork error");
		if (pid > 0)
			exit(0);
	}
	sigpause(0L);
	return 0;
}

void
usage()
{
	(void)fprintf(stderr, "usage: slattach [-fhm] [-s baudrate] ttyname\n");
	exit(1);
}

static
void
handler (int signo, int code, struct sigcontext *scp)
{
	slipdisc = TTYDISC;
	if (ioctl(fd, TIOCSETD, &slipdisc) < 0)
		err(1, "TIOCSETD");

	if (ioctl(fd, TIOCCDTR, 0) < 0)
		err(1, "TIOCCDTR");

	if (tcsetattr(fd, TCSADRAIN, &old_tty_values) < 0)
		err(1, "tcsetattr");
	return;
}
-- 
VaX#n8 (vak-sa-nate) - n, CS senior++ and Unix junkie - vax@ccwf.cc.utexas.edu
Just the vax-man.  Read my MIPS, no new VAXes!        - PGP key on request