Project

General

Profile

Bug #12306 ยป itest.c

pty test program - Andy Fiddaman, 2020-02-16 11:23 AM

 
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <fcntl.h>
4
#include <errno.h>
5
#include <unistd.h>
6
#include <string.h>
7
#include <termios.h>
8
#include <stropts.h>
9
#include <assert.h>
10

    
11
static void
12
cfmakeraw(struct termios *t)
13
{
14
	t->c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|
15
	    ICRNL|IXON|IGNPAR);
16
	t->c_iflag |= IGNBRK;
17
	t->c_oflag &= ~OPOST;
18
	t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|
19
	    TOSTOP|PENDIN);
20
	t->c_cflag &= ~(CSIZE|PARENB);
21
	t->c_cflag |= CS8|CREAD;
22
	t->c_cc[VMIN] = 1;
23
	t->c_cc[VTIME] = 0;
24
}
25

    
26
int
27
main(void)
28
{
29
	int fdm, fds, rc;
30
	char input[150];
31

    
32
	fdm = posix_openpt(O_RDWR);
33
	assert(fdm >= 0);
34

    
35
	rc = grantpt(fdm);
36
	assert(rc == 0);
37

    
38
	rc = unlockpt(fdm);
39
	assert(rc == 0);
40

    
41
	// Open the slave PTY
42
	fds = open(ptsname(fdm), O_RDWR);
43
	printf("master: %s\n", ptsname(fdm));
44

    
45
	if (ioctl(fds, I_FIND, "ptem") == 0) {
46
		printf("ptem is NOT already pushed\n");
47
		assert(ioctl(fds, I_PUSH, "ptem") == 0);
48
		assert(ioctl(fds, I_PUSH, "ldterm") == 0);
49
		assert(ioctl(fds, I_PUSH, "ttcompat") == 0);
50
	} else {
51
		printf("ptem module already present\n");
52
	}
53

    
54
	if (fork())
55
	{
56
		// parent
57
		close(fds);
58
		for (;;) {
59
			write(1, "Input: ", sizeof("Input: "));
60
			rc = read(0, input, sizeof(input));
61
			if (rc <= 0) break;
62
			write(fdm, input, rc);
63

    
64
			rc = read(fdm, input, sizeof(input) - 1);
65

    
66
			if (rc == 0) {
67
				fprintf(stderr, "Received empty block\n");
68
				rc = read(fdm, input, sizeof(input) - 1);
69
			}
70
			if (rc <= 0) {
71
				fprintf(stderr, "Error %d %s\n", errno,
72
				    strerror(errno));
73
				break;
74
			}
75
			input[rc] = '\0';
76
			fprintf(stderr, "%s", input);
77
		}
78
		return 0;
79
	}
80

    
81
	// Child
82

    
83
	struct termios slave_orig_term_settings;
84
	struct termios new_term_settings;
85

    
86
	close(fdm);
87

    
88
	rc = tcgetattr(fds, &slave_orig_term_settings);
89

    
90
	// Set raw mode on the slave side of the PTY
91
	new_term_settings = slave_orig_term_settings;
92
	cfmakeraw(&new_term_settings);
93
	tcsetattr(fds, TCSANOW, &new_term_settings);
94

    
95
	close(0); close(1); close(2);
96
	dup(fds); dup(fds); dup(fds);
97

    
98
	for (;;) {
99
		rc = read(fds, input, sizeof(input) - 1);
100

    
101
		if (rc <= 0)
102
			break; input[rc - 1] = '\0';
103
		if (!strcmp(input, "nul"))
104
			write(1, NULL, 0);
105
		printf("Child received: '%s'\n", input);
106
	}
107
}
108

    
    (1-1/1)