Home | History | Annotate | Line # | Download | only in tty
t_pr.c revision 1.5
      1 /*	$NetBSD: t_pr.c,v 1.5 2011/04/09 11:55:59 martin Exp $	*/
      2 
      3 #include <sys/types.h>
      4 #include <sys/ioctl.h>
      5 #include <sys/tty.h>
      6 
      7 #include <atf-c.h>
      8 #include <fcntl.h>
      9 
     10 #include <stdio.h>
     11 #include <string.h>
     12 #include <errno.h>
     13 #include <rump/rump.h>
     14 #include <rump/rump_syscalls.h>
     15 
     16 static bool init_done = false;
     17 
     18 static void
     19 init(void)
     20 {
     21 	if (init_done)
     22 		return;
     23 	rump_init();
     24 	init_done = true;
     25 }
     26 
     27 static int
     28 sendsome(int from, int to)
     29 {
     30 	size_t i;
     31 	ssize_t cnt;
     32 	static const char msg[] = "hello world\n";
     33 	char buf[sizeof(msg)+10];
     34 
     35 	memset(buf, 0, sizeof(buf));
     36 	rump_sys_write(from, msg, strlen(msg));
     37 	cnt = rump_sys_read(to, buf, sizeof(buf));
     38 	if (cnt < (ssize_t)strlen(msg)) {
     39 		printf("short message read: %zd chars: \"%s\"\n", cnt, buf);
     40 		return 1;
     41 	}
     42 	for (i = 0; i < sizeof(buf); i++) {
     43 		if (buf[i] == '\r' || buf[i] == '\n') {
     44 			buf[i] = '\n';
     45 			buf[i+1] = '\0';
     46 			break;
     47 		}
     48 	}
     49 
     50 	return strcmp(buf, msg) != 0;
     51 }
     52 
     53 static int
     54 exercise_ptytty(int master, int slave)
     55 {
     56 	int error, flags;
     57 
     58 	/*
     59 	 * send a few bytes from master to slave and read them back
     60 	 */
     61 	error = sendsome(master, slave);
     62 	if (error)
     63 		return error;
     64 
     65 	flags = FREAD|FWRITE;
     66 	rump_sys_ioctl(master, TIOCFLUSH, &flags);
     67 
     68 	/*
     69 	 * and the same in the other direction
     70 	 */
     71 	error = sendsome(slave, master);
     72 	if (error)
     73 		return error;
     74 
     75 	flags = FREAD|FWRITE;
     76 	rump_sys_ioctl(master, TIOCFLUSH, &flags);
     77 	return 0;
     78 }
     79 
     80 ATF_TC(client_first);
     81 ATF_TC_HEAD(client_first, tc)
     82 {
     83 
     84 	atf_tc_set_md_var(tc, "descr",
     85 	    "test basic tty/pty operation when opening client side first");
     86 }
     87 
     88 ATF_TC_BODY(client_first, tc)
     89 {
     90 	int master, slave, error, v;
     91 
     92 	init();
     93 	slave =  rump_sys_open("/dev/ttyp1", O_RDWR|O_NONBLOCK);
     94 	ATF_CHECK(slave != -1);
     95 
     96 	master = rump_sys_open("/dev/ptyp1", O_RDWR);
     97 	ATF_CHECK(master != -1);
     98 
     99 	v = 0;
    100 	rump_sys_ioctl(slave, FIOASYNC, &v);
    101 	error = exercise_ptytty(master, slave);
    102 	ATF_CHECK(error == 0);
    103 
    104 	rump_sys_close(master);
    105 	rump_sys_close(slave);
    106 }
    107 
    108 ATF_TC(master_first);
    109 ATF_TC_HEAD(master_first, tc)
    110 {
    111 
    112 	atf_tc_set_md_var(tc, "descr",
    113 	    "test basic tty/pty operation when opening master side first");
    114 }
    115 
    116 ATF_TC_BODY(master_first, tc)
    117 {
    118 	int master, slave, error;
    119 
    120 	init();
    121 	master = rump_sys_open("/dev/ptyp1", O_RDWR);
    122 	ATF_CHECK(master != -1);
    123 
    124 	slave =  rump_sys_open("/dev/ttyp1", O_RDWR);
    125 	ATF_CHECK(slave != -1);
    126 
    127 	error = exercise_ptytty(master, slave);
    128 	ATF_CHECK(error == 0);
    129 
    130 	rump_sys_close(master);
    131 	rump_sys_close(slave);
    132 }
    133 
    134 ATF_TC(ptyioctl);
    135 ATF_TC_HEAD(ptyioctl, tc)
    136 {
    137 
    138 	atf_tc_set_md_var(tc, "descr",
    139 	    "ioctl on pty with client side not open");
    140 }
    141 
    142 ATF_TC_BODY(ptyioctl, tc)
    143 {
    144 	struct termios tio;
    145 	int fd;
    146 
    147 	init();
    148 	fd = rump_sys_open("/dev/ptyp1", O_RDWR);
    149 	ATF_CHECK(fd != -1);
    150 
    151 	/*
    152 	 * This used to die with null deref under ptcwakeup()
    153 	 * atf_tc_expect_signal(-1, "PR kern/40688");
    154 	 */
    155 	rump_sys_ioctl(fd, TIOCGETA, &tio);
    156 
    157 	rump_sys_close(fd);
    158 }
    159 
    160 ATF_TP_ADD_TCS(tp)
    161 {
    162 
    163 	ATF_TP_ADD_TC(tp, ptyioctl);
    164 	ATF_TP_ADD_TC(tp, client_first);
    165 	ATF_TP_ADD_TC(tp, master_first);
    166 
    167 	return atf_no_error();
    168 }
    169