1: /*
2: * Copyright (c) 2005, Matthew Mondor
3: * ALL RIGHTS RESERVED.
4: */
5:
6: /*
7: * Allocates two pty(4) devices and links them together.
8: * Supplies to stdout the two tty(4) devices which may be used for loopback.
9: */
10:
11:
12:
13: #include <sys/types.h>
14: #include <poll.h>
15: #include <fcntl.h>
16: #include <unistd.h>
17:
18: #include <stdlib.h>
19: #include <stdio.h>
20: #include <string.h>
21:
22:
23:
24: int main(void);
25:
26:
27:
28: #define DBUFSIZ 65536
29:
30:
31:
32: int
33: main(void)
34: {
35: char *dbuf;
36: struct pollfd fds[2];
37:
38: if ((dbuf = malloc(DBUFSIZ)) == NULL) {
39: (void) fprintf(stderr,
40: "Couldn't allocate %d bytes of heap memory\n", DBUFSIZ);
41: return EXIT_FAILURE;
42: }
43:
44: if ((fds[0].fd = posix_openpt(O_RDWR)) == -1 ||
45: (fds[1].fd = posix_openpt(O_RDWR)) == -1) {
46: (void) fprintf(stderr,
47: "Couldn't allocate two pty(4) devices\n");
48: return EXIT_FAILURE;
49: }
50:
51: if (grantpt(fds[0].fd) == -1 || grantpt(fds[1].fd) == -1) {
52: (void) fprintf(stderr,
53: "Couldn't grant permissions on tty(4) devices\n");
54: return EXIT_FAILURE;
55: }
56:
57: /*
58: * Output ttys we handle
59: */
60: (void) printf("%s\n", ptsname(fds[0].fd));
61: (void) printf("%s\n", ptsname(fds[1].fd));
62: (void) fflush(stdout);
63:
64: /*
65: * Now redirect any input from any terminal to the other pair.
66: * This basically provides two connected ttys, a sort of loopback
67: * tty system, useful for debugging some applications.
68: */
69: fds[0].events = fds[1].events = POLLIN;
70: fds[0].revents = fds[1].revents = 0;
71: for (;;) {
72: int ret, i;
73:
74: if ((ret = poll(fds, 2, -1)) == -1)
75: break;
76: if (ret == 0)
77: continue;
78: for (i = 0; i < 2; i++) {
79: if ((fds[i].revents & POLLHUP) != 0 ||
80: (fds[i].revents & POLLERR) != 0)
81: goto end;
82: if ((fds[i].revents & POLLIN) != 0) {
83: size_t len;
84:
85: if ((len = read(fds[i].fd, dbuf, DBUFSIZ))
86: == -1)
87: goto end;
88: if (len > 0) {
89: if (write(fds[!i].fd, dbuf, len) == -1)
90: goto end;
91: }
92: }
93: }
94: }
95:
96: end:
97: free(dbuf);
98: (void) unlockpt(fds[0].fd);
99: (void) close(fds[0].fd);
100: (void) unlockpt(fds[1].fd);
101: (void) close(fds[1].fd);
102:
103: return EXIT_SUCCESS;
104: }