1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include "qemu/osdep.h"
36#include "qemu-common.h"
37
38#if defined HAVE_PTY_H
39# include <pty.h>
40#elif defined CONFIG_BSD
41# include <termios.h>
42# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
43# include <libutil.h>
44# else
45# include <util.h>
46# endif
47#elif defined CONFIG_SOLARIS
48# include <termios.h>
49# include <stropts.h>
50#else
51# include <termios.h>
52#endif
53
54#ifdef __sun__
55
56#if !defined(HAVE_OPENPTY)
57
58static int openpty(int *amaster, int *aslave, char *name,
59 struct termios *termp, struct winsize *winp)
60{
61 const char *slave;
62 int mfd = -1, sfd = -1;
63
64 *amaster = *aslave = -1;
65
66 mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
67 if (mfd < 0)
68 goto err;
69
70 if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
71 goto err;
72
73 if ((slave = ptsname(mfd)) == NULL)
74 goto err;
75
76 if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
77 goto err;
78
79 if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
80 (termp != NULL && tcgetattr(sfd, termp) < 0))
81 goto err;
82
83 if (amaster)
84 *amaster = mfd;
85 if (aslave)
86 *aslave = sfd;
87 if (winp)
88 ioctl(sfd, TIOCSWINSZ, winp);
89
90 return 0;
91
92err:
93 if (sfd != -1)
94 close(sfd);
95 close(mfd);
96 return -1;
97}
98#endif
99
100static void cfmakeraw (struct termios *termios_p)
101{
102 termios_p->c_iflag &=
103 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
104 termios_p->c_oflag &= ~OPOST;
105 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
106 termios_p->c_cflag &= ~(CSIZE|PARENB);
107 termios_p->c_cflag |= CS8;
108
109 termios_p->c_cc[VMIN] = 0;
110 termios_p->c_cc[VTIME] = 0;
111}
112#endif
113
114int qemu_openpty_raw(int *aslave, char *pty_name)
115{
116 int amaster;
117 struct termios tty;
118#if defined(__OpenBSD__) || defined(__DragonFly__)
119 char pty_buf[PATH_MAX];
120#define q_ptsname(x) pty_buf
121#else
122 char *pty_buf = NULL;
123#define q_ptsname(x) ptsname(x)
124#endif
125
126 if (openpty(&amaster, aslave, pty_buf, NULL, NULL) < 0) {
127 return -1;
128 }
129
130
131 tcgetattr(*aslave, &tty);
132 cfmakeraw(&tty);
133 tcsetattr(*aslave, TCSAFLUSH, &tty);
134
135 if (pty_name) {
136 strcpy(pty_name, q_ptsname(amaster));
137 }
138
139 return amaster;
140}
141