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:
36:
37:
38:
39:
40:
41:
42:
43:
44: #include <config.h>
45: #include <sys/signal.h>
46: #include <errno.h>
47: #include <stdio.h>
48: #include <fcntl.h>
49: #include <setjmp.h>
50: #include <sys/ioctl.h>
51: #include <sys/devinfo.h>
52: #include <termios.h>
53: #include <termio.h>
54: #include <sys/hft.h>
55: #include <sys/uio.h>
56: #include <sys/tty.h>
57:
58:
59: #define REMOTE 0x01
60:
61: #undef ioctl
62: static char SCCSid[] = "com/gnuemacs/src,3.1,9021-90/05/03-5/3/90";
63:
64:
65:
66: #define QDEV ((HFQPDEVCH<<8)|HFQPDEVCL)
67: #define QLOC ((HFQLOCCH<<8)|HFQLOCCL)
68: #define QPS ((HFQPRESCH<<8)|HFQPRESCL)
69:
70: #ifndef TCGETS
71: #define TCGETS TCGETA
72: #endif
73: #ifndef TCSETS
74: #define TCSETS TCSETA
75: #endif
76:
77:
78:
79: static int hfqry();
80: static int hfskbd();
81: char *xmalloc();
82:
83: extern int errno;
84: static jmp_buf hftenv;
85: static int is_ack_vtd;
86: static SIGTYPE (*sav_alrm) ();
87: static struct hfctlreq req =
88: { 0x1b,'[','x',0,0,0,21,HFCTLREQCH,HFCTLREQCL};
89: static struct hfctlack ACK =
90: { 0x1b,'[','x',0,0,0,21,HFCTLACKCH,HFCTLACKCL};
91:
92:
93:
94:
95:
96: #define HFTYPE(p) ((p->hf_typehi<<8)|(p->hf_typelo))
97:
98: #define BYTE4(p) ((p)[0]<<24 | (p)[1]<<16 | (p)[2]<<8 | (p)[3])
99:
100:
101: #define RD_BUF(f,p,l) \
102: while ((l)) \
103: if ((j = emacs_read (f, p, l)) < 0) \
104: if (errno != EINTR) return (-1); \
105: else continue; \
106: else { (l) -= j; (p) += j; }
107:
108:
109: #ifdef PROTOTYPES
110: static GT_ACK (int fd, int req, char *buf);
111: static WR_REQ (int fd, int request, int cmdlen, char *cmd, int resplen);
112: static void hft_alrm(int sig);
113: #else
114: static GT_ACK ();
115: static WR_REQ ();
116: static void hft_alrm ();
117: #endif
118:
119:
120:
121: hftctl (fd, request, arg)
122: int fd;
123: int request;
124: union {
125: struct hfintro *intro;
126: struct hfquery *query;
127: char *c;
128: } arg;
129: {
130:
131: int i;
132: int fd_flag;
133: register union {
134: struct hfintro *cmd;
135: struct hfqphdevc *ph;
136: char *c;
137: } p;
138: int pty_new;
139: int pty_old;
140: int retcode;
141: struct termios term_new;
142: struct termios term_old;
143: struct devinfo devInfo;
144:
145:
146: if (ioctl (fd, IOCINFO, &devInfo) == -1) return(-1);
147:
148: if (devInfo.devtype != DD_PSEU)
149: return (ioctl(fd, request, arg));
150:
151:
152:
153:
154:
155:
156:
157:
158:
159: if ((fd_flag = fcntl (fd, F_GETFL, 0)) == -1) return (-1);
160: if (ioctl (fd, TCGETS, &term_old) == -1) return (-1);
161:
162:
163: pty_new = pty_old | REMOTE;
164: memcpy (&term_new, &term_old, sizeof (term_new));
165: term_new.c_iflag = 0;
166: term_new.c_oflag = 0;
167: term_new.c_lflag = 0;
168:
169: for (i = 1; i <= 5; i++)
170: term_new.c_cc[i] = 0;
171: term_new.c_cc[0] = -1;
172: ioctl (fd, TCSETS, &term_new);
173: if (fcntl (fd, F_SETFL, fd_flag & ~O_NDELAY) == -1)
174: return(-1);
175:
176: if (request == HFSKBD)
177: retcode = hfskbd (fd, request, arg.c);
178: else
179: retcode = hfqry (fd, request, arg.c);
180:
181: fcntl (fd, F_SETFL, fd_flag);
182: ioctl (fd, TCSETS, &term_old);
183:
184:
185: return (retcode);
186: }
187:
188:
189: static int
190: hfskbd (fd, request, arg)
191: int fd;
192: int request;
193: struct hfbuf *arg;
194: {
195: WR_REQ(fd, request, arg->hf_buflen, arg->hf_bufp,0);
196: return (GT_ACK(fd, request, arg->hf_bufp));
197: }
198:
199:
200: static int
201: hfqry (fd, request, arg)
202: int fd;
203: int request;
204: struct hfquery *arg;
205: {
206: WR_REQ(fd, request, arg->hf_cmdlen, arg->hf_cmd, arg->hf_resplen);
207: return (GT_ACK(fd, request, arg->hf_resp));
208: }
209:
210:
211:
212: static int
213: GT_ACK (fd, req, buf)
214: int fd;
215: int req;
216: char *buf;
217: {
218: struct hfctlack ack;
219: int i = sizeof (ack);
220: int j = 0;
221: union {
222: char *c;
223: struct hfctlack *ack;
224: } p;
225:
226: is_ack_vtd = 0;
227:
228: if (setjmp (hftenv))
229: {
230: errno = ENODEV;
231: return (-1);
232: }
233:
234: alarm(3);
235: sav_alrm = signal (SIGALRM, hft_alrm);
236:
237: p.ack = &ack;
238: while (! is_ack_vtd)
239: {
240: RD_BUF(fd, p.c, i);
241:
242: if (! memcmp (&ack, &ACK, sizeof (HFINTROSZ))
243: && (ack.hf_request == req))
244: {
245: is_ack_vtd = 1;
246: break;
247: }
248:
249: p.ack = &ack;
250: ++p.c;
251: i = sizeof (ack) - 1;
252:
253: while ((*p.c != 0x1b) && i)
254: { ++p.c; --i; }
255:
256: (i ? memcpy (&ack, p.c, i) : 0);
257: p.ack = &ack;
258: p.c += i;
259: i = sizeof (ack) - i;
260: }
261:
262: alarm(0);
263: signal (SIGALRM, sav_alrm);
264:
265: if (i = ack.hf_arg_len)
266: {
267: RD_BUF(fd,buf,i);
268: }
269:
270: if (errno = ack.hf_retcode)
271: return (-1);
272: else
273: return (0);
274: }
275:
276:
277: static void
278: hft_alrm (sig)
279: int sig;
280: {
281: signal (SIGALRM, sav_alrm);
282:
283: if (is_ack_vtd)
284: return;
285: else
286: longjmp (hftenv, -1);
287:
288: }
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300: static int
301: WR_REQ (fd, request, cmdlen, cmd, resplen)
302: int fd;
303: int request;
304: int cmdlen;
305: char *cmd;
306: int resplen;
307: {
308: struct {
309: char *c;
310: struct hfctlreq *req;
311: } p;
312: int size;
313:
314: req.hf_request = request;
315: req.hf_arg_len = cmdlen;
316: req.hf_rsp_len = resplen;
317:
318: if (cmdlen)
319: {
320: size = sizeof (struct hfctlreq) + cmdlen;
321: if ((p.c = xmalloc(size)) == NULL)
322: return (-1);
323:
324: memcpy (p.c, &req, sizeof (req));
325: memcpy (p.c + sizeof (req), cmd, cmdlen);
326: }
327: else
328: {
329: p.req = &req;
330: size = sizeof (req);
331: }
332:
333:
334: if (emacs_write (fd, p.c, size) == -1) return (-1);
335: if (p.req != &req)
336: xfree (p.c);
337: return (0);
338:
339: }
340:
341:
342: