Ejemplo n.º 1
0
/*
 * refclock_open - open serial port for reference clock
 *
 * This routine opens a serial port for I/O and sets default options. It
 * returns the file descriptor if success and zero if failure.
 */
int
refclock_open(
	char	*dev,		/* device name pointer */
	u_int	speed,		/* serial port speed (code) */
	u_int	lflags		/* line discipline flags */
	)
{
	int	fd;
	int	omode;
#ifdef O_NONBLOCK
	char    trash[128];	/* litter bin for old input data */
#endif

	/*
	 * Open serial port and set default options
	 */
	omode = O_RDWR;
#ifdef O_NONBLOCK
	omode |= O_NONBLOCK;
#endif
#ifdef O_NOCTTY
	omode |= O_NOCTTY;
#endif

	fd = open(dev, omode, 0777);
	if (fd < 0) {
		msyslog(LOG_ERR, "refclock_open %s: %m", dev);
		return (0);
	}
	NTP_INSIST(fd != 0);
	if (!refclock_setup(fd, speed, lflags)) {
		close(fd);
		return (0);
	}
	if (!refclock_ioctl(fd, lflags)) {
		close(fd);
		return (0);
	}
#ifdef O_NONBLOCK
	/*
	 * We want to make sure there is no pending trash in the input
	 * buffer. Since we have non-blocking IO available, this is a
	 * good moment to read and dump all available outdated stuff
	 * that might have become toxic for the driver.
	 */
	while (read(fd, trash, sizeof(trash)) > 0 || errno == EINTR)
		/*NOP*/;
#endif
	return (fd);
}
Ejemplo n.º 2
0
/*
 * refclock_open - open serial port for reference clock
 *
 * This routine opens a serial port for I/O and sets default options. It
 * returns the file descriptor if success and zero if failure.
 */
int
refclock_open(
	char	*dev,		/* device name pointer */
	u_int	speed,		/* serial port speed (code) */
	u_int	lflags		/* line discipline flags */
	)
{
	int	fd;
	int	omode;

	/*
	 * Open serial port and set default options
	 */
	omode = O_RDWR;
#ifdef O_NONBLOCK
	omode |= O_NONBLOCK;
#endif
#ifdef O_NOCTTY
	omode |= O_NOCTTY;
#endif

	fd = open(dev, omode, 0777);
	if (fd < 0) {
		msyslog(LOG_ERR, "refclock_open %s: %m", dev);
		return (0);
	}
	if (!refclock_setup(fd, speed, lflags)) {
		close(fd);
		return (0);
	}
	if (!refclock_ioctl(fd, lflags)) {
		close(fd);
		return (0);
	}
	return (fd);
}
Ejemplo n.º 3
0
/*
 * refclock_open - open serial port for reference clock
 *
 * This routine opens a serial port for I/O and sets default options. It
 * returns the file descriptor if success and zero if failure.
 */
int
refclock_open(
	char *dev,		/* device name pointer */
	int speed,		/* serial port speed (code) */
	int lflags		/* line discipline flags */
	)
{
	int fd, i;
	int flags;
	TTY ttyb, *ttyp;
#ifdef TIOCMGET
	u_long ltemp;
#endif /* TIOCMGET */
	int omode;

	/*
	 * Open serial port and set default options
	 */
	flags = lflags;

	omode = O_RDWR;
#ifdef O_NONBLOCK
	omode |= O_NONBLOCK;
#endif
#ifdef O_NOCTTY
	omode |= O_NOCTTY;
#endif

	fd = open(dev, omode, 0777);

	if (fd < 0) {
		msyslog(LOG_ERR, "refclock_open: %s: %m", dev);
		return (0);
	}

	/*
	 * This little jewel lights up the PPS file descriptor if the
	 * device name matches the name in the pps line in the
	 * configuration file. This is so the atom driver can glom onto
	 * the right device. Very silly.
	 */
	if (strcmp(dev, pps_device) == 0)
		fdpps = fd;

	/*
	 * The following sections initialize the serial line port in
	 * canonical (line-oriented) mode and set the specified line
	 * speed, 8 bits and no parity. The modem control, break, erase
	 * and kill functions are normally disabled. There is a
	 * different section for each terminal interface, as selected at
	 * compile time.
	 */
	ttyp = &ttyb;

#ifdef HAVE_TERMIOS
	/*
	 * POSIX serial line parameters (termios interface)
	 */
	if (tcgetattr(fd, ttyp) < 0) {
		msyslog(LOG_ERR,
			"refclock_open: fd %d tcgetattr: %m", fd);
		return (0);
	}

	/*
	 * Set canonical mode and local connection; set specified speed,
	 * 8 bits and no parity; map CR to NL; ignore break.
	 */
	ttyp->c_iflag = IGNBRK | IGNPAR | ICRNL;
	ttyp->c_oflag = 0;
	ttyp->c_cflag = CS8 | CLOCAL | CREAD;
	(void)cfsetispeed(&ttyb, (u_int)speed);
	(void)cfsetospeed(&ttyb, (u_int)speed);
	ttyp->c_lflag = ICANON;
	for (i = 0; i < NCCS; ++i)
	{
		ttyp->c_cc[i] = '\0';
	}

	/*
	 * Some special cases
	 */
	if (flags & LDISC_RAW) {
		ttyp->c_iflag = 0;
		ttyp->c_lflag = 0;
		ttyp->c_cc[VMIN] = 1;
	}
#if defined(TIOCMGET) && !defined(SCO5_CLOCK)
	/*
	 * If we have modem control, check to see if modem leads are
	 * active; if so, set remote connection. This is necessary for
	 * the kernel pps mods to work.
	 */
	ltemp = 0;
	if (ioctl(fd, TIOCMGET, (char *)&ltemp) < 0)
		msyslog(LOG_ERR,
			"refclock_open: fd %d TIOCMGET failed: %m", fd);
#ifdef DEBUG
	if (debug)
		printf("refclock_open: fd %d modem status 0x%lx\n",
		    fd, ltemp);
#endif
	if (ltemp & TIOCM_DSR)
		ttyp->c_cflag &= ~CLOCAL;
#endif /* TIOCMGET */
	if (tcsetattr(fd, TCSANOW, ttyp) < 0) {
		msyslog(LOG_ERR,
		    "refclock_open: fd %d TCSANOW failed: %m", fd);
		return (0);
	}
	if (tcflush(fd, TCIOFLUSH) < 0) {
		msyslog(LOG_ERR,
		    "refclock_open: fd %d TCIOFLUSH failed: %m", fd);
		return (0);
	}
#endif /* HAVE_TERMIOS */

#ifdef HAVE_SYSV_TTYS

	/*
	 * System V serial line parameters (termio interface)
	 *
	 */
	if (ioctl(fd, TCGETA, ttyp) < 0) {
		msyslog(LOG_ERR,
		    "refclock_open: fd %d TCGETA failed: %m", fd);
		return (0);
	}

	/*
	 * Set canonical mode and local connection; set specified speed,
	 * 8 bits and no parity; map CR to NL; ignore break.
	 */
	ttyp->c_iflag = IGNBRK | IGNPAR | ICRNL;
	ttyp->c_oflag = 0;
	ttyp->c_cflag = speed | CS8 | CLOCAL | CREAD;
	ttyp->c_lflag = ICANON;
	ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\0';

	/*
	 * Some special cases
	 */
	if (flags & LDISC_RAW) {
		ttyp->c_iflag = 0;
		ttyp->c_lflag = 0;
	}
#ifdef TIOCMGET
	/*
	 * If we have modem control, check to see if modem leads are
	 * active; if so, set remote connection. This is necessary for
	 * the kernel pps mods to work.
	 */
	ltemp = 0;
	if (ioctl(fd, TIOCMGET, (char *)&ltemp) < 0)
		msyslog(LOG_ERR,
		    "refclock_open: fd %d TIOCMGET failed: %m", fd);
#ifdef DEBUG
	if (debug)
		printf("refclock_open: fd %d modem status %lx\n",
		    fd, ltemp);
#endif
	if (ltemp & TIOCM_DSR)
		ttyp->c_cflag &= ~CLOCAL;
#endif /* TIOCMGET */
	if (ioctl(fd, TCSETA, ttyp) < 0) {
		msyslog(LOG_ERR,
		    "refclock_open: fd %d TCSETA failed: %m", fd);
		return (0);
	}
#endif /* HAVE_SYSV_TTYS */

#ifdef HAVE_BSD_TTYS

	/*
	 * 4.3bsd serial line parameters (sgttyb interface)
	 */
	if (ioctl(fd, TIOCGETP, (char *)ttyp) < 0) {
		msyslog(LOG_ERR,
		    "refclock_open: fd %d TIOCGETP %m", fd);
		return (0);
	}
	ttyp->sg_ispeed = ttyp->sg_ospeed = speed;
	ttyp->sg_flags = EVENP | ODDP | CRMOD;
	if (ioctl(fd, TIOCSETP, (char *)ttyp) < 0) {
		msyslog(LOG_ERR,
		    "refclock_open: TIOCSETP failed: %m");
		return (0);
	}
#endif /* HAVE_BSD_TTYS */
	if (!refclock_ioctl(fd, flags)) {
		(void)close(fd);
		msyslog(LOG_ERR,
		    "refclock_open: fd %d ioctl failed: %m", fd);
		return (0);
	}
	return (fd);
}