Mercurial > emacs
annotate src/hftctl.c @ 8275:4fdf77f4e45c
type-break-mode: New variable and function.
type-break-interval: Increase default to 1 hour.
type-break-query-interval: Variable renamed from type-break-delay-interval.
type-break-keystroke-interval: Variable deleted.
type-break-keystroke-threshold: New variable.
type-break-demo-life: Function renamed from type-break-life.
type-break-demo-hanoi: Function renamed from type-break-hanoi.
type-break-alarm-p: Variable renamed from type-break-p.
type-break: Don't query.
type-break-query: (New function) query here.
type-break-check: Call type-break-query, not type-break.
Do nothing if type-break-mode is nil.
Increment type-break-keystroke-count with the length of this-command-keys,
not just 1.
Query for break when keystroke count exceeds cdr of keystroke threshold
variable.
Query for break after an alarm only if keystroke count exceeds car of
keystroke threshold variable.
type-break-select: Function deleted.
type-break: Move that code here.
type-break-cancel-schedule: Function renamed from cancel-type-break.
Reset type-break-alarm-p.
type-break-alarm: Function renamed from type-break-soon.
(top level): Call type-break-mode; don't set up hook explicitly.
author | Noah Friedman <friedman@splode.com> |
---|---|
date | Mon, 18 Jul 1994 07:37:18 +0000 |
parents | c52147cf10b1 |
children | b7aa6ac26872 |
rev | line source |
---|---|
102 | 1 /* IBM has disclaimed copyright on this module. */ |
2 | |
3 /***************************************************************/ | |
4 /* */ | |
5 /* Function: hftctl */ | |
6 /* */ | |
7 /* Syntax: */ | |
8 /* #include <sys/ioctl.h> */ | |
9 /* #include <sys/hft.h> */ | |
10 /* */ | |
11 /* int hftctl(fildes, request, arg ) */ | |
485 | 12 /* int fildes, request; */ |
13 /* char *arg; */ | |
102 | 14 /* */ |
15 /* Description: */ | |
16 /* */ | |
17 /* Does the following: */ | |
18 /* 1. determines if fildes is pty */ | |
19 /* does normal ioctl it is not */ | |
20 /* 2. places fildes into raw mode */ | |
21 /* 3. converts ioctl arguments to datastream */ | |
22 /* 4. waits for 2 secs for acknowledgement before */ | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3470
diff
changeset
|
23 /* timing out. */ |
102 | 24 /* 5. places response in callers buffer ( just like */ |
25 /* ioctl. */ | |
26 /* 6. returns fildes to its original mode */ | |
27 /* */ | |
28 /* User of this program should review steps 1,4, and 3. */ | |
29 /* hftctl makes no check on the request type. It must be */ | |
30 /* a HFT ioctl that is supported remotely. */ | |
31 /* This program will use the SIGALRM and alarm(2). Any */ | |
32 /* Previous alarms are lost. */ | |
33 /* */ | |
34 /* Users of this program are free to modify it any way */ | |
35 /* they want. */ | |
36 /* */ | |
37 /* Return Value: */ | |
38 /* */ | |
39 /* If ioctl fails, a value of -1 is returned and errno */ | |
40 /* is set to indicate the error. */ | |
41 /* */ | |
42 /***************************************************************/ | |
43 | |
7897
c52147cf10b1
Put sys/signal.h and errno.h first, then config.h.
Richard M. Stallman <rms@gnu.org>
parents:
5098
diff
changeset
|
44 #include <sys/signal.h> |
c52147cf10b1
Put sys/signal.h and errno.h first, then config.h.
Richard M. Stallman <rms@gnu.org>
parents:
5098
diff
changeset
|
45 #include <errno.h> |
c52147cf10b1
Put sys/signal.h and errno.h first, then config.h.
Richard M. Stallman <rms@gnu.org>
parents:
5098
diff
changeset
|
46 |
c52147cf10b1
Put sys/signal.h and errno.h first, then config.h.
Richard M. Stallman <rms@gnu.org>
parents:
5098
diff
changeset
|
47 #include <config.h> |
102 | 48 |
49 #include <stdio.h> | |
50 #include <fcntl.h> | |
51 #include <setjmp.h> | |
52 #include <sys/ioctl.h> | |
53 #include <sys/devinfo.h> | |
485 | 54 #include <termios.h> |
102 | 55 #include <termio.h> |
56 #include <sys/hft.h> | |
560 | 57 #include <sys/uio.h> |
102 | 58 #include <sys/tty.h> |
59 /* #include <sys/pty.h> */ | |
5098
a770e7708711
Include config.h. Include sys/signal.h before config.h.
Richard M. Stallman <rms@gnu.org>
parents:
3591
diff
changeset
|
60 |
102 | 61 #define REMOTE 0x01 |
62 | |
63 #undef ioctl | |
485 | 64 static char SCCSid[] = "com/gnuemacs/src,3.1,9021-90/05/03-5/3/90"; |
102 | 65 |
66 /*************** LOCAL DEFINES **********************************/ | |
67 | |
68 #define QDEV ((HFQPDEVCH<<8)|HFQPDEVCL) | |
69 #define QLOC ((HFQLOCCH<<8)|HFQLOCCL) | |
70 #define QPS ((HFQPRESCH<<8)|HFQPRESCL) | |
71 | |
485 | 72 #ifndef TCGETS |
73 #define TCGETS TCGETA | |
74 #endif | |
75 #ifndef TCSETS | |
76 #define TCSETS TCSETA | |
77 #endif | |
78 | |
102 | 79 /*************** EXTERNAL / GLOBAL DATA AREA ********************/ |
80 | |
560 | 81 static int hfqry(); |
82 static int hfskbd(); | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
560
diff
changeset
|
83 char *xmalloc(); |
102 | 84 |
485 | 85 extern int errno; |
86 static jmp_buf hftenv; | |
87 static int is_ack_vtd; | |
5098
a770e7708711
Include config.h. Include sys/signal.h before config.h.
Richard M. Stallman <rms@gnu.org>
parents:
3591
diff
changeset
|
88 static SIGTYPE (*sav_alrm) (); |
102 | 89 static struct hfctlreq req = |
90 { 0x1b,'[','x',0,0,0,21,HFCTLREQCH,HFCTLREQCL}; | |
91 static struct hfctlack ACK = | |
92 { 0x1b,'[','x',0,0,0,21,HFCTLACKCH,HFCTLACKCL}; | |
93 | |
485 | 94 /* FUNC signal(); */ |
102 | 95 |
96 /*************** LOCAL MACROS ***********************************/ | |
97 | |
98 #define HFTYPE(p) ((p->hf_typehi<<8)|(p->hf_typelo)) | |
99 | |
485 | 100 #define BYTE4(p) ((p)[0]<<24 | (p)[1]<<16 | (p)[2]<<8 | (p)[3]) |
102 | 101 |
102 /* read a buffer */ | |
103 #define RD_BUF(f,p,l) \ | |
485 | 104 while ((l)) \ |
105 if ((j = read((f),(p),(l))) < 0) \ | |
106 if (errno != EINTR) return (-1); \ | |
107 else continue; \ | |
108 else { (l) -= j; (p) += j; } | |
109 | |
110 /*************** function prototypes ***************************/ | |
111 #ifdef __STDC__ | |
112 static GT_ACK (int fd, int req, char *buf); | |
113 static WR_REQ (int fd, int request, int cmdlen, char *cmd, int resplen); | |
3315
dcc64ab7de8c
* hftctl.c (hft_alrm): Declare and define this to return void, not
Jim Blandy <jimb@redhat.com>
parents:
2439
diff
changeset
|
114 static void hft_alrm(int sig); |
485 | 115 #else |
116 static GT_ACK (); | |
117 static WR_REQ (); | |
3470
a6dde97d8166
(hft_alrm): Don't return a value.
Richard M. Stallman <rms@gnu.org>
parents:
3315
diff
changeset
|
118 static void hft_alrm (); |
485 | 119 #endif |
102 | 120 |
121 /*************** HFTCTL FUNCTION *******************************/ | |
122 | |
485 | 123 hftctl (fd, request, arg) |
124 int fd; | |
125 int request; | |
126 union { | |
127 struct hfintro *intro; | |
128 struct hfquery *query; | |
129 char *c; | |
130 } arg; | |
102 | 131 { |
132 | |
485 | 133 int i; |
134 int fd_flag; /* fcntl flags */ | |
135 register union { | |
136 struct hfintro *cmd; /* p.cmd - intro des. */ | |
137 struct hfqphdevc *ph; /* p.ph - physical dev.*/ | |
138 char *c; /* p.c - char ptr */ | |
139 } p; /* general pointer */ | |
140 int pty_new; /* pty modes */ | |
141 int pty_old; | |
142 int retcode; | |
143 struct termios term_new; /* terminal attributes */ | |
144 struct termios term_old; | |
145 struct devinfo devInfo; /* defined in sys/devinfo.h */ | |
102 | 146 |
147 | |
485 | 148 if (ioctl (fd, IOCINFO, &devInfo) == -1) return(-1); |
102 | 149 |
485 | 150 if (devInfo.devtype != DD_PSEU) /* is it a pty? */ |
151 return (ioctl(fd, request, arg)); /* no, do IOCTL */ | |
102 | 152 |
485 | 153 /******* START PTY **************/ |
154 /** Pty found, possible HFT */ | |
155 /** set new file des as raw */ | |
156 /** as you can. */ | |
157 /********************************/ | |
102 | 158 |
485 | 159 /* Get current state of file */ |
160 /* descriptor & save */ | |
161 if ((fd_flag = fcntl (fd, F_GETFL, 0)) == -1) return (-1); | |
162 if (ioctl (fd, TCGETS, &term_old) == -1) return (-1); | |
163 /* set terminal attr to raw */ | |
164 /* and to delay on read */ | |
165 pty_new = pty_old | REMOTE; | |
166 memcpy (&term_new, &term_old, sizeof (term_new)); | |
167 term_new.c_iflag = 0; | |
168 term_new.c_oflag = 0; | |
169 term_new.c_lflag = 0; | |
170 /* term_new.c_line = 0; */ | |
171 for (i = 1; i <= 5; i++) | |
172 term_new.c_cc[i] = 0; | |
173 term_new.c_cc[0] = -1; | |
174 ioctl (fd, TCSETS, &term_new); | |
175 if (fcntl (fd, F_SETFL, fd_flag & ~O_NDELAY) == -1) | |
176 return(-1); | |
177 /* call spacific function */ | |
178 if (request == HFSKBD) | |
179 retcode = hfskbd (fd, request, arg.c); | |
180 else /* assume HFQUERY */ | |
181 retcode = hfqry (fd, request, arg.c); | |
102 | 182 |
485 | 183 fcntl (fd, F_SETFL, fd_flag); /* reset terminal to original */ |
184 ioctl (fd, TCSETS, &term_old); | |
102 | 185 |
186 | |
485 | 187 return (retcode); /* return error */ |
102 | 188 } |
189 | |
190 /*************** HFSKBD FUNCTION ******************************/ | |
485 | 191 static int |
192 hfskbd (fd, request, arg) | |
193 int fd; | |
194 int request; | |
195 struct hfbuf *arg; | |
102 | 196 { |
485 | 197 WR_REQ(fd, request, arg->hf_buflen, arg->hf_bufp,0); |
198 return (GT_ACK(fd, request, arg->hf_bufp)); | |
102 | 199 } |
200 | |
201 /*************** HFQUERY FUNCTION ******************************/ | |
485 | 202 static int |
203 hfqry (fd, request, arg) | |
204 int fd; | |
205 int request; | |
206 struct hfquery *arg; | |
102 | 207 { |
485 | 208 WR_REQ(fd, request, arg->hf_cmdlen, arg->hf_cmd, arg->hf_resplen); |
209 return (GT_ACK(fd, request, arg->hf_resp)); | |
102 | 210 } |
211 | |
212 | |
213 /*************** GT_ACK FUNCTION ******************************/ | |
485 | 214 static int |
215 GT_ACK (fd, req, buf) | |
216 int fd; | |
217 int req; | |
218 char *buf; | |
102 | 219 { |
485 | 220 struct hfctlack ack; |
221 int i = sizeof (ack); | |
222 int j = 0; | |
223 union { | |
224 char *c; | |
225 struct hfctlack *ack; | |
226 } p; | |
102 | 227 |
485 | 228 is_ack_vtd = 0; /* flag no ACT VTD yet */ |
102 | 229 |
485 | 230 if (setjmp (hftenv)) /* set environment in case */ |
231 { /* of time out */ | |
232 errno = ENODEV; /* if time out, set errno */ | |
233 return (-1); /* flag error */ | |
234 } | |
102 | 235 |
485 | 236 alarm(3); /* time out in 3 secs */ |
237 sav_alrm = signal (SIGALRM, hft_alrm); /* prepare to catch time out */ | |
102 | 238 |
485 | 239 p.ack = &ack; |
240 while (! is_ack_vtd) /* do until valid ACK VTD */ | |
241 { | |
242 RD_BUF(fd, p.c, i); /* read until a ACK VTD is fill*/ | |
102 | 243 |
485 | 244 if (! memcmp (&ack, &ACK, sizeof (HFINTROSZ)) /* the ACK intro & */ |
245 && (ack.hf_request == req)) /* is it the response we want ?*/ | |
246 { /* yes, ACK VTD found */ | |
247 is_ack_vtd = 1; /* quickly, flag it */ | |
248 break; /* get the %$%#@ out of here */ | |
249 } | |
102 | 250 |
485 | 251 p.ack = &ack; /* no, then skip 1st */ |
252 ++p.c; /* char and start over */ | |
253 i = sizeof (ack) - 1; /* one less ESC to cry over */ | |
102 | 254 |
485 | 255 while ((*p.c != 0x1b) && i) /* scan for next ESC */ |
256 { ++p.c; --i; } /* if any */ | |
102 | 257 |
485 | 258 (i ? memcpy (&ack, p.c, i) : 0); /* if any left over, then move */ |
259 p.ack = &ack; /* ESC to front of ack struct */ | |
260 p.c += i; /* skip over whats been read */ | |
261 i = sizeof (ack) - i; /* set whats left to be read */ | |
262 } /***** TRY AGAIN */ | |
102 | 263 |
485 | 264 alarm(0); /* ACK VTD received, reset alrm*/ |
265 signal (SIGALRM, sav_alrm); /* reset signal */ | |
102 | 266 |
485 | 267 if (i = ack.hf_arg_len) /* any data following ? */ |
268 { /* yes, */ | |
269 RD_BUF(fd,buf,i); /* read until it is received */ | |
270 } | |
102 | 271 |
485 | 272 if (errno = ack.hf_retcode) /* set errno based on returned */ |
273 return (-1); /* code, if 0, then no error */ | |
274 else | |
275 return (0); /* if set, then error returned */ | |
102 | 276 } |
277 | |
278 /*************** HFT_ALRM FUNCTION ******************************/ | |
3315
dcc64ab7de8c
* hftctl.c (hft_alrm): Declare and define this to return void, not
Jim Blandy <jimb@redhat.com>
parents:
2439
diff
changeset
|
279 static void |
dcc64ab7de8c
* hftctl.c (hft_alrm): Declare and define this to return void, not
Jim Blandy <jimb@redhat.com>
parents:
2439
diff
changeset
|
280 hft_alrm (sig) /* Function hft_alrm - handle */ |
dcc64ab7de8c
* hftctl.c (hft_alrm): Declare and define this to return void, not
Jim Blandy <jimb@redhat.com>
parents:
2439
diff
changeset
|
281 int sig; /* alarm signal */ |
102 | 282 { |
485 | 283 signal (SIGALRM, sav_alrm); /* reset to previous */ |
102 | 284 |
485 | 285 if (is_ack_vtd) /* has ack vtd arrived ? */ |
3470
a6dde97d8166
(hft_alrm): Don't return a value.
Richard M. Stallman <rms@gnu.org>
parents:
3315
diff
changeset
|
286 return; /* yes, then continue */ |
485 | 287 else /* no, then return with error */ |
288 longjmp (hftenv, -1); | |
102 | 289 |
290 } | |
291 | |
292 /*********************************************************************/ | |
293 /*** ***/ | |
294 /*** NOTE: Both the HFCTLREQ and the arg structure should be ***/ | |
295 /*** sent in one io write operation. If terminal ***/ | |
296 /*** emulators are in NODELAY mode then multiple writes ***/ | |
297 /*** may cause bogus information to be read by the emulator ***/ | |
298 /*** depending on the timing. ***/ | |
299 /*** ***/ | |
300 /*********************************************************************/ | |
301 | |
485 | 302 static int |
303 WR_REQ (fd, request, cmdlen, cmd, resplen) | |
304 int fd; | |
305 int request; | |
306 int cmdlen; | |
307 char *cmd; | |
308 int resplen; | |
102 | 309 { |
485 | 310 struct { |
311 char *c; | |
312 struct hfctlreq *req; | |
313 } p; | |
314 int size; | |
102 | 315 |
485 | 316 req.hf_request = request; |
317 req.hf_arg_len = cmdlen; | |
318 req.hf_rsp_len = resplen; | |
102 | 319 |
485 | 320 if (cmdlen) /* if arg structure to pass */ |
321 { | |
322 size = sizeof (struct hfctlreq) + cmdlen; | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
560
diff
changeset
|
323 if ((p.c = xmalloc(size)) == NULL) /* malloc one area */ |
485 | 324 return (-1); |
102 | 325 |
485 | 326 memcpy (p.c, &req, sizeof (req)); /* copy CTL REQ struct */ |
327 memcpy (p.c + sizeof (req), cmd, cmdlen); /* copy arg struct */ | |
328 } | |
329 else | |
330 { | |
331 p.req = &req; /* otherwise use only CTL REQ */ | |
332 size = sizeof (req); | |
333 } | |
102 | 334 |
485 | 335 /* write request to terminal */ |
336 if (write(fd,p.c,size) == -1) return (-1); | |
337 if (p.req != &req) /* free if allocated */ | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
560
diff
changeset
|
338 xfree (p.c); |
485 | 339 return (0); |
102 | 340 |
341 } |