xref: /csrg-svn/usr.bin/talk/io.c (revision 34373)
122395Sdist /*
222395Sdist  * Copyright (c) 1983 Regents of the University of California.
3*34373Sbostic  * All rights reserved.
4*34373Sbostic  *
5*34373Sbostic  * Redistribution and use in source and binary forms are permitted
6*34373Sbostic  * provided that this notice is preserved and that due credit is given
7*34373Sbostic  * to the University of California at Berkeley. The name of the University
8*34373Sbostic  * may not be used to endorse or promote products derived from this
9*34373Sbostic  * software without specific prior written permission. This software
10*34373Sbostic  * is provided ``as is'' without express or implied warranty.
1122395Sdist  */
1222395Sdist 
1316364Skarels #ifndef lint
14*34373Sbostic static char sccsid[] = "@(#)io.c	5.2 (Berkeley) 05/20/88";
15*34373Sbostic #endif /* not lint */
1616351Skarels 
1716364Skarels /*
1816364Skarels  * This file contains the I/O handling and the exchange of
1916364Skarels  * edit characters. This connection itself is established in
2016364Skarels  * ctl.c
2116351Skarels  */
2216351Skarels 
2316351Skarels #include "talk.h"
2416351Skarels #include <stdio.h>
2516351Skarels #include <errno.h>
2616351Skarels #include <sys/time.h>
2716351Skarels 
2816351Skarels #define A_LONG_TIME 10000000
2916351Skarels #define STDIN_MASK (1<<fileno(stdin))	/* the bit mask for standard
3016351Skarels 					   input */
3116351Skarels extern int errno;
3216351Skarels 
3316351Skarels /*
3416351Skarels  * The routine to do the actual talking
3516351Skarels  */
3616351Skarels talk()
3716351Skarels {
3816364Skarels 	register int read_template, sockt_mask;
3916364Skarels 	int read_set, nb;
4016364Skarels 	char buf[BUFSIZ];
4116364Skarels 	struct timeval wait;
4216351Skarels 
4316364Skarels 	message("Connection established\007\007\007");
4416364Skarels 	current_line = 0;
4516364Skarels 	sockt_mask = (1<<sockt);
4616351Skarels 
4716351Skarels 	/*
4816364Skarels 	 * Wait on both the other process (sockt_mask) and
4916351Skarels 	 * standard input ( STDIN_MASK )
5016351Skarels 	 */
5116364Skarels 	read_template = sockt_mask | STDIN_MASK;
5216364Skarels 	forever {
5316351Skarels 		read_set = read_template;
5416364Skarels 		wait.tv_sec = A_LONG_TIME;
5516364Skarels 		wait.tv_usec = 0;
5616364Skarels 		nb = select(32, &read_set, 0, 0, &wait);
5716364Skarels 		if (nb <= 0) {
5816364Skarels 			if (errno == EINTR) {
5916364Skarels 				read_set = read_template;
6016364Skarels 				continue;
6116364Skarels 			}
6216364Skarels 			/* panic, we don't know what happened */
6316364Skarels 			p_error("Unexpected error from select");
6416364Skarels 			quit();
6516364Skarels 		}
6616364Skarels 		if (read_set & sockt_mask) {
6716364Skarels 			/* There is data on sockt */
6816364Skarels 			nb = read(sockt, buf, sizeof buf);
6916364Skarels 			if (nb <= 0) {
7016364Skarels 				message("Connection closed. Exiting");
7116364Skarels 				quit();
7216364Skarels 			}
7316364Skarels 			display(&his_win, buf, nb);
7416364Skarels 		}
7516364Skarels 		if (read_set & STDIN_MASK) {
7616364Skarels 			/*
7716364Skarels 			 * We can't make the tty non_blocking, because
7816364Skarels 			 * curses's output routines would screw up
7916364Skarels 			 */
8016364Skarels 			ioctl(0, FIONREAD, (struct sgttyb *) &nb);
8116364Skarels 			nb = read(0, buf, nb);
8216364Skarels 			display(&my_win, buf, nb);
8316364Skarels 			/* might lose data here because sockt is non-blocking */
8416364Skarels 			write(sockt, buf, nb);
8516364Skarels 		}
8616351Skarels 	}
8716351Skarels }
8816351Skarels 
8916364Skarels extern	int errno;
9016364Skarels extern	int sys_nerr;
9116364Skarels extern	char *sys_errlist[];
9216351Skarels 
9316364Skarels /*
9416364Skarels  * p_error prints the system error message on the standard location
9516364Skarels  * on the screen and then exits. (i.e. a curses version of perror)
9616364Skarels  */
9716351Skarels p_error(string)
9816364Skarels 	char *string;
9916351Skarels {
10016364Skarels 	char *sys;
10116351Skarels 
10216364Skarels 	sys = "Unknown error";
10316364Skarels 	if (errno < sys_nerr)
10416364Skarels 		sys = sys_errlist[errno];
10516364Skarels 	wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
10616364Skarels 	wprintw(my_win.x_win, "[%s : %s (%d)]\n", string, sys, errno);
10716364Skarels 	wrefresh(my_win.x_win);
10816364Skarels 	move(LINES-1, 0);
10916364Skarels 	refresh();
11016364Skarels 	quit();
11116351Skarels }
11216351Skarels 
11316364Skarels /*
11416364Skarels  * Display string in the standard location
11516364Skarels  */
11616351Skarels message(string)
11716364Skarels 	char *string;
11816351Skarels {
11916364Skarels 
12016364Skarels 	wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
12116364Skarels 	wprintw(my_win.x_win, "[%s]\n", string);
12216364Skarels 	wrefresh(my_win.x_win);
12316351Skarels }
124