1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <errno.h>
21: #include <fcntl.h>
22: #include <limits.h>
23: #include <pty.h>
24: #include <stdlib.h>
25: #include <string.h>
26: #include <termios.h>
27: #include <unistd.h>
28: #include <sys/types.h>
29:
30:
31:
32:
33:
34:
35: static int
36: pts_name (int fd, char **pts, size_t buf_len)
37: {
38: int rv;
39: char *buf = *pts;
40:
41: for (;;)
42: {
43: char *new_buf;
44:
45: if (buf_len)
46: {
47: rv = ptsname_r (fd, buf, buf_len);
48:
49: if (rv != 0 || memchr (buf, '\0', buf_len))
50:
51:
52: break;
53:
54:
55: buf_len += buf_len;
56: }
57: else
58:
59: buf_len = 128;
60:
61: if (buf != *pts)
62:
63: new_buf = realloc (buf, buf_len);
64: else
65: new_buf = malloc (buf_len);
66: if (! new_buf)
67: {
68: rv = -1;
69: __set_errno (ENOMEM);
70: break;
71: }
72: buf = new_buf;
73: }
74:
75: if (rv == 0)
76: *pts = buf;
77: else if (buf != *pts)
78: free (buf);
79:
80: return rv;
81: }
82:
83:
84:
85:
86: int
87: openpty (int *amaster, int *aslave, char *name, struct termios *termp,
88: struct winsize *winp)
89: {
90: #ifdef PATH_MAX
91: char _buf[PATH_MAX];
92: #else
93: char _buf[512];
94: #endif
95: char *buf = _buf;
96: int master, slave;
97:
98: master = getpt ();
99: if (master == -1)
100: return -1;
101:
102: if (grantpt (master))
103: goto fail;
104:
105: if (unlockpt (master))
106: goto fail;
107:
108: if (pts_name (master, &buf, sizeof (_buf)))
109: goto fail;
110:
111: slave = open (buf, O_RDWR | O_NOCTTY);
112: if (slave == -1)
113: {
114: if (buf != _buf)
115: free (buf);
116:
117: goto fail;
118: }
119:
120:
121: if(termp)
122: tcsetattr (slave, TCSAFLUSH, termp);
123: if (winp)
124: ioctl (slave, TIOCSWINSZ, winp);
125:
126: *amaster = master;
127: *aslave = slave;
128: if (name != NULL)
129: strcpy (name, buf);
130:
131: if (buf != _buf)
132: free (buf);
133: return 0;
134:
135: fail:
136: close (master);
137: return -1;
138: }
139: libutil_hidden_def (openpty)