| #include <u.h> | 
 | #include <sys/types.h> | 
 | #include <sys/ioctl.h> | 
 | #include <sys/stat.h> | 
 | #include <errno.h> | 
 | #include <grp.h> | 
 | #include <termios.h> | 
 | #include <sys/termios.h> | 
 | #ifdef __linux__ | 
 | #include <pty.h> | 
 | #endif | 
 | #include <fcntl.h> | 
 | #include <libc.h> | 
 | #include "term.h" | 
 |  | 
 | #define debug 0 | 
 |  | 
 | static char *abc = | 
 | 	"abcdefghijklmnopqrstuvwxyz" | 
 | 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | 
 | 	"0123456789"; | 
 | static char *_123 =  | 
 | 	"0123456789" | 
 | 	"abcdefghijklmnopqrstuvwxyz" | 
 | 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | 
 |  | 
 | int | 
 | getpts(int fd[], char *slave) | 
 | { | 
 | 	char *a, *z; | 
 | 	char pty[] = "/dev/ptyXX"; | 
 |  | 
 | 	for(a=abc; *a; a++) | 
 | 	for(z=_123; *z; z++){ | 
 | 		pty[8] = *a; | 
 | 		pty[9] = *z; | 
 | 		if((fd[1] = open(pty, ORDWR)) < 0){ | 
 | 			if(errno == ENOENT) | 
 | 				break; | 
 | 		}else{ | 
 | 			fchmod(fd[1], 0620); | 
 | 			strcpy(slave, pty); | 
 | 			slave[5] = 't'; | 
 | 			if((fd[0] = open(slave, ORDWR)) >= 0) | 
 | 				return 0; | 
 | 			close(fd[1]); | 
 | 		} | 
 | 	} | 
 | 	sysfatal("no ptys"); | 
 | 	return 0; | 
 | } | 
 |  | 
 | int | 
 | childpty(int fd[], char *slave) | 
 | { | 
 | 	int sfd; | 
 |  | 
 | 	close(fd[1]);	/* drop master */ | 
 | 	setsid(); | 
 | 	sfd = open(slave, ORDWR); | 
 | 	if(sfd < 0) | 
 | 		sysfatal("child open %s: %r\n", slave); | 
 | 	if(ioctl(sfd, TIOCSCTTY, 0) < 0) | 
 | 		fprint(2, "ioctl TIOCSCTTY: %r\n"); | 
 | 	return sfd; | 
 | } | 
 |  | 
 | struct winsize ows; | 
 |  | 
 | void | 
 | updatewinsize(int row, int col, int dx, int dy) | 
 | { | 
 | 	struct winsize ws; | 
 |  | 
 | 	ws.ws_row = row; | 
 | 	ws.ws_col = col; | 
 | 	ws.ws_xpixel = dx; | 
 | 	ws.ws_ypixel = dy; | 
 | 	if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col){ | 
 | 		if(ioctl(rcfd, TIOCSWINSZ, &ws) < 0) | 
 | 			fprint(2, "ioctl: %r\n"); | 
 | 	} | 
 | 	ows = ws; | 
 | } | 
 |  | 
 | static struct termios ttmode; | 
 |  | 
 | int | 
 | isecho(int fd) | 
 | { | 
 | 	if(tcgetattr(fd, &ttmode) < 0) | 
 | 		fprint(2, "tcgetattr: %r\n"); | 
 | 	if(debug) fprint(2, "israw %c%c\n", | 
 | 		ttmode.c_lflag&ICANON ? 'c' : '-', | 
 | 		ttmode.c_lflag&ECHO ? 'e' : '-'); | 
 | 	return ttmode.c_lflag&ECHO; | 
 | } | 
 |  | 
 | int | 
 | getintr(int fd) | 
 | { | 
 | 	if(tcgetattr(fd, &ttmode) < 0) | 
 | 		return 0x7F; | 
 | 	return ttmode.c_cc[VINTR]; | 
 | } | 
 |  |