]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windows/winhandl.c
193f24d76a6d529367fdfa57682e7441cb3dcc49
[PuTTY.git] / windows / winhandl.c
1 /*
2  * winhandl.c: Module to give Windows front ends the general
3  * ability to deal with consoles, pipes, serial ports, or any other
4  * type of data stream accessed through a Windows API HANDLE rather
5  * than a WinSock SOCKET.
6  *
7  * We do this by spawning a subthread to continuously try to read
8  * from the handle. Every time a read successfully returns some
9  * data, the subthread sets an event object which is picked up by
10  * the main thread, and the main thread then sets an event in
11  * return to instruct the subthread to resume reading.
12  * 
13  * Output works precisely the other way round, in a second
14  * subthread. The output subthread should not be attempting to
15  * write all the time, because it hasn't always got data _to_
16  * write; so the output thread waits for an event object notifying
17  * it to _attempt_ a write, and then it sets an event in return
18  * when one completes.
19  * 
20  * (It's terribly annoying having to spawn a subthread for each
21  * direction of each handle. Technically it isn't necessary for
22  * serial ports, since we could use overlapped I/O within the main
23  * thread and wait directly on the event objects in the OVERLAPPED
24  * structures. However, we can't use this trick for some types of
25  * file handle at all - for some reason Windows restricts use of
26  * OVERLAPPED to files which were opened with the overlapped flag -
27  * and so we must use threads for those. This being the case, it's
28  * simplest just to use threads for everything rather than trying
29  * to keep track of multiple completely separate mechanisms.)
30  */
31
32 #include <assert.h>
33
34 #include "putty.h"
35
36 /* ----------------------------------------------------------------------
37  * Generic definitions.
38  */
39
40 /*
41  * Maximum amount of backlog we will allow to build up on an input
42  * handle before we stop reading from it.
43  */
44 #define MAX_BACKLOG 32768
45
46 struct handle_generic {
47     /*
48      * Initial fields common to both handle_input and handle_output
49      * structures.
50      * 
51      * The three HANDLEs are set up at initialisation time and are
52      * thereafter read-only to both main thread and subthread.
53      * `moribund' is only used by the main thread; `done' is
54      * written by the main thread before signalling to the
55      * subthread. `defunct' and `busy' are used only by the main
56      * thread.
57      */
58     HANDLE h;                          /* the handle itself */
59     HANDLE ev_to_main;                 /* event used to signal main thread */
60     HANDLE ev_from_main;               /* event used to signal back to us */
61     int moribund;                      /* are we going to kill this soon? */
62     int done;                          /* request subthread to terminate */
63     int defunct;                       /* has the subthread already gone? */
64     int busy;                          /* operation currently in progress? */
65     void *privdata;                    /* for client to remember who they are */
66 };
67
68 typedef enum { HT_INPUT, HT_OUTPUT, HT_FOREIGN } HandleType;
69
70 /* ----------------------------------------------------------------------
71  * Input threads.
72  */
73
74 /*
75  * Data required by an input thread.
76  */
77 struct handle_input {
78     /*
79      * Copy of the handle_generic structure.
80      */
81     HANDLE h;                          /* the handle itself */
82     HANDLE ev_to_main;                 /* event used to signal main thread */
83     HANDLE ev_from_main;               /* event used to signal back to us */
84     int moribund;                      /* are we going to kill this soon? */
85     int done;                          /* request subthread to terminate */
86     int defunct;                       /* has the subthread already gone? */
87     int busy;                          /* operation currently in progress? */
88     void *privdata;                    /* for client to remember who they are */
89
90     /*
91      * Data set at initialisation and then read-only.
92      */
93     int flags;
94
95     /*
96      * Data set by the input thread before signalling ev_to_main,
97      * and read by the main thread after receiving that signal.
98      */
99     char buffer[4096];                 /* the data read from the handle */
100     DWORD len;                         /* how much data that was */
101     int readerr;                       /* lets us know about read errors */
102
103     /*
104      * Callback function called by this module when data arrives on
105      * an input handle.
106      */
107     handle_inputfn_t gotdata;
108 };
109
110 /*
111  * The actual thread procedure for an input thread.
112  */
113 static DWORD WINAPI handle_input_threadfunc(void *param)
114 {
115     struct handle_input *ctx = (struct handle_input *) param;
116     OVERLAPPED ovl, *povl;
117     HANDLE oev;
118     int readret, readlen;
119
120     if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
121         povl = &ovl;
122         oev = CreateEvent(NULL, TRUE, FALSE, NULL);
123     } else {
124         povl = NULL;
125     }
126
127     if (ctx->flags & HANDLE_FLAG_UNITBUFFER)
128         readlen = 1;
129     else
130         readlen = sizeof(ctx->buffer);
131
132     while (1) {
133         if (povl) {
134             memset(povl, 0, sizeof(OVERLAPPED));
135             povl->hEvent = oev;
136         }
137         readret = ReadFile(ctx->h, ctx->buffer,readlen, &ctx->len, povl);
138         if (!readret)
139             ctx->readerr = GetLastError();
140         else
141             ctx->readerr = 0;
142         if (povl && !readret && ctx->readerr == ERROR_IO_PENDING) {
143             WaitForSingleObject(povl->hEvent, INFINITE);
144             readret = GetOverlappedResult(ctx->h, povl, &ctx->len, FALSE);
145             if (!readret)
146                 ctx->readerr = GetLastError();
147             else
148                 ctx->readerr = 0;
149         }
150
151         if (!readret) {
152             /*
153              * Windows apparently sends ERROR_BROKEN_PIPE when a
154              * pipe we're reading from is closed normally from the
155              * writing end. This is ludicrous; if that situation
156              * isn't a natural EOF, _nothing_ is. So if we get that
157              * particular error, we pretend it's EOF.
158              */
159             if (ctx->readerr == ERROR_BROKEN_PIPE)
160                 ctx->readerr = 0;
161             ctx->len = 0;
162         }
163
164         if (readret && ctx->len == 0 &&
165             (ctx->flags & HANDLE_FLAG_IGNOREEOF))
166             continue;
167
168         SetEvent(ctx->ev_to_main);
169
170         if (!ctx->len)
171             break;
172
173         WaitForSingleObject(ctx->ev_from_main, INFINITE);
174         if (ctx->done) {
175             SetEvent(ctx->ev_to_main);
176             break;                     /* main thread told us to shut down */
177         }
178     }
179
180     if (povl)
181         CloseHandle(oev);
182
183     return 0;
184 }
185
186 /*
187  * This is called after a succcessful read, or from the
188  * `unthrottle' function. It decides whether or not to begin a new
189  * read operation.
190  */
191 static void handle_throttle(struct handle_input *ctx, int backlog)
192 {
193     if (ctx->defunct)
194         return;
195
196     /*
197      * If there's a read operation already in progress, do nothing:
198      * when that completes, we'll come back here and be in a
199      * position to make a better decision.
200      */
201     if (ctx->busy)
202         return;
203
204     /*
205      * Otherwise, we must decide whether to start a new read based
206      * on the size of the backlog.
207      */
208     if (backlog < MAX_BACKLOG) {
209         SetEvent(ctx->ev_from_main);
210         ctx->busy = TRUE;
211     }
212 }
213
214 /* ----------------------------------------------------------------------
215  * Output threads.
216  */
217
218 /*
219  * Data required by an output thread.
220  */
221 struct handle_output {
222     /*
223      * Copy of the handle_generic structure.
224      */
225     HANDLE h;                          /* the handle itself */
226     HANDLE ev_to_main;                 /* event used to signal main thread */
227     HANDLE ev_from_main;               /* event used to signal back to us */
228     int moribund;                      /* are we going to kill this soon? */
229     int done;                          /* request subthread to terminate */
230     int defunct;                       /* has the subthread already gone? */
231     int busy;                          /* operation currently in progress? */
232     void *privdata;                    /* for client to remember who they are */
233
234     /*
235      * Data set at initialisation and then read-only.
236      */
237     int flags;
238
239     /*
240      * Data set by the main thread before signalling ev_from_main,
241      * and read by the input thread after receiving that signal.
242      */
243     char *buffer;                      /* the data to write */
244     DWORD len;                         /* how much data there is */
245
246     /*
247      * Data set by the input thread before signalling ev_to_main,
248      * and read by the main thread after receiving that signal.
249      */
250     DWORD lenwritten;                  /* how much data we actually wrote */
251     int writeerr;                      /* return value from WriteFile */
252
253     /*
254      * Data only ever read or written by the main thread.
255      */
256     bufchain queued_data;              /* data still waiting to be written */
257     enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
258
259     /*
260      * Callback function called when the backlog in the bufchain
261      * drops.
262      */
263     handle_outputfn_t sentdata;
264 };
265
266 static DWORD WINAPI handle_output_threadfunc(void *param)
267 {
268     struct handle_output *ctx = (struct handle_output *) param;
269     OVERLAPPED ovl, *povl;
270     HANDLE oev;
271     int writeret;
272
273     if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
274         povl = &ovl;
275         oev = CreateEvent(NULL, TRUE, FALSE, NULL);
276     } else {
277         povl = NULL;
278     }
279
280     while (1) {
281         WaitForSingleObject(ctx->ev_from_main, INFINITE);
282         if (ctx->done) {
283             SetEvent(ctx->ev_to_main);
284             break;
285         }
286         if (povl) {
287             memset(povl, 0, sizeof(OVERLAPPED));
288             povl->hEvent = oev;
289         }
290
291         writeret = WriteFile(ctx->h, ctx->buffer, ctx->len,
292                              &ctx->lenwritten, povl);
293         if (!writeret)
294             ctx->writeerr = GetLastError();
295         else
296             ctx->writeerr = 0;
297         if (povl && !writeret && GetLastError() == ERROR_IO_PENDING) {
298             writeret = GetOverlappedResult(ctx->h, povl,
299                                            &ctx->lenwritten, TRUE);
300             if (!writeret)
301                 ctx->writeerr = GetLastError();
302             else
303                 ctx->writeerr = 0;
304         }
305
306         SetEvent(ctx->ev_to_main);
307         if (!writeret)
308             break;
309     }
310
311     if (povl)
312         CloseHandle(oev);
313
314     return 0;
315 }
316
317 static void handle_try_output(struct handle_output *ctx)
318 {
319     void *senddata;
320     int sendlen;
321
322     if (!ctx->busy && bufchain_size(&ctx->queued_data)) {
323         bufchain_prefix(&ctx->queued_data, &senddata, &sendlen);
324         ctx->buffer = senddata;
325         ctx->len = sendlen;
326         SetEvent(ctx->ev_from_main);
327         ctx->busy = TRUE;
328     } else if (!ctx->busy && bufchain_size(&ctx->queued_data) == 0 &&
329                ctx->outgoingeof == EOF_PENDING) {
330         CloseHandle(ctx->h);
331         ctx->h = INVALID_HANDLE_VALUE;
332         ctx->outgoingeof = EOF_SENT;
333     }
334 }
335
336 /* ----------------------------------------------------------------------
337  * 'Foreign events'. These are handle structures which just contain a
338  * single event object passed to us by another module such as
339  * winnps.c, so that they can make use of our handle_get_events /
340  * handle_got_event mechanism for communicating with application main
341  * loops.
342  */
343 struct handle_foreign {
344     /*
345      * Copy of the handle_generic structure.
346      */
347     HANDLE h;                          /* the handle itself */
348     HANDLE ev_to_main;                 /* event used to signal main thread */
349     HANDLE ev_from_main;               /* event used to signal back to us */
350     int moribund;                      /* are we going to kill this soon? */
351     int done;                          /* request subthread to terminate */
352     int defunct;                       /* has the subthread already gone? */
353     int busy;                          /* operation currently in progress? */
354     void *privdata;                    /* for client to remember who they are */
355
356     /*
357      * Our own data, just consisting of knowledge of who to call back.
358      */
359     void (*callback)(void *);
360     void *ctx;
361 };
362
363 /* ----------------------------------------------------------------------
364  * Unified code handling both input and output threads.
365  */
366
367 struct handle {
368     HandleType type;
369     union {
370         struct handle_generic g;
371         struct handle_input i;
372         struct handle_output o;
373         struct handle_foreign f;
374     } u;
375 };
376
377 static tree234 *handles_by_evtomain;
378
379 static int handle_cmp_evtomain(void *av, void *bv)
380 {
381     struct handle *a = (struct handle *)av;
382     struct handle *b = (struct handle *)bv;
383
384     if ((unsigned)a->u.g.ev_to_main < (unsigned)b->u.g.ev_to_main)
385         return -1;
386     else if ((unsigned)a->u.g.ev_to_main > (unsigned)b->u.g.ev_to_main)
387         return +1;
388     else
389         return 0;
390 }
391
392 static int handle_find_evtomain(void *av, void *bv)
393 {
394     HANDLE *a = (HANDLE *)av;
395     struct handle *b = (struct handle *)bv;
396
397     if ((unsigned)*a < (unsigned)b->u.g.ev_to_main)
398         return -1;
399     else if ((unsigned)*a > (unsigned)b->u.g.ev_to_main)
400         return +1;
401     else
402         return 0;
403 }
404
405 struct handle *handle_input_new(HANDLE handle, handle_inputfn_t gotdata,
406                                 void *privdata, int flags)
407 {
408     struct handle *h = snew(struct handle);
409     DWORD in_threadid; /* required for Win9x */
410
411     h->type = HT_INPUT;
412     h->u.i.h = handle;
413     h->u.i.ev_to_main = CreateEvent(NULL, FALSE, FALSE, NULL);
414     h->u.i.ev_from_main = CreateEvent(NULL, FALSE, FALSE, NULL);
415     h->u.i.gotdata = gotdata;
416     h->u.i.defunct = FALSE;
417     h->u.i.moribund = FALSE;
418     h->u.i.done = FALSE;
419     h->u.i.privdata = privdata;
420     h->u.i.flags = flags;
421
422     if (!handles_by_evtomain)
423         handles_by_evtomain = newtree234(handle_cmp_evtomain);
424     add234(handles_by_evtomain, h);
425
426     CreateThread(NULL, 0, handle_input_threadfunc,
427                  &h->u.i, 0, &in_threadid);
428     h->u.i.busy = TRUE;
429
430     return h;
431 }
432
433 struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata,
434                                  void *privdata, int flags)
435 {
436     struct handle *h = snew(struct handle);
437     DWORD out_threadid; /* required for Win9x */
438
439     h->type = HT_OUTPUT;
440     h->u.o.h = handle;
441     h->u.o.ev_to_main = CreateEvent(NULL, FALSE, FALSE, NULL);
442     h->u.o.ev_from_main = CreateEvent(NULL, FALSE, FALSE, NULL);
443     h->u.o.busy = FALSE;
444     h->u.o.defunct = FALSE;
445     h->u.o.moribund = FALSE;
446     h->u.o.done = FALSE;
447     h->u.o.privdata = privdata;
448     bufchain_init(&h->u.o.queued_data);
449     h->u.o.outgoingeof = EOF_NO;
450     h->u.o.sentdata = sentdata;
451     h->u.o.flags = flags;
452
453     if (!handles_by_evtomain)
454         handles_by_evtomain = newtree234(handle_cmp_evtomain);
455     add234(handles_by_evtomain, h);
456
457     CreateThread(NULL, 0, handle_output_threadfunc,
458                  &h->u.o, 0, &out_threadid);
459
460     return h;
461 }
462
463 struct handle *handle_add_foreign_event(HANDLE event,
464                                         void (*callback)(void *), void *ctx)
465 {
466     struct handle *h = snew(struct handle);
467
468     h->type = HT_FOREIGN;
469     h->u.f.h = INVALID_HANDLE_VALUE;
470     h->u.f.ev_to_main = event;
471     h->u.f.ev_from_main = INVALID_HANDLE_VALUE;
472     h->u.f.defunct = TRUE;  /* we have no thread in the first place */
473     h->u.f.moribund = FALSE;
474     h->u.f.done = FALSE;
475     h->u.f.privdata = NULL;
476     h->u.f.callback = callback;
477     h->u.f.ctx = ctx;
478     h->u.f.busy = TRUE;
479
480     if (!handles_by_evtomain)
481         handles_by_evtomain = newtree234(handle_cmp_evtomain);
482     add234(handles_by_evtomain, h);
483
484     return h;
485 }
486
487 int handle_write(struct handle *h, const void *data, int len)
488 {
489     assert(h->type == HT_OUTPUT);
490     assert(h->u.o.outgoingeof == EOF_NO);
491     bufchain_add(&h->u.o.queued_data, data, len);
492     handle_try_output(&h->u.o);
493     return bufchain_size(&h->u.o.queued_data);
494 }
495
496 void handle_write_eof(struct handle *h)
497 {
498     /*
499      * This function is called when we want to proactively send an
500      * end-of-file notification on the handle. We can only do this by
501      * actually closing the handle - so never call this on a
502      * bidirectional handle if we're still interested in its incoming
503      * direction!
504      */
505     assert(h->type == HT_OUTPUT);
506     if (!h->u.o.outgoingeof == EOF_NO) {
507         h->u.o.outgoingeof = EOF_PENDING;
508         handle_try_output(&h->u.o);
509     }
510 }
511
512 HANDLE *handle_get_events(int *nevents)
513 {
514     HANDLE *ret;
515     struct handle *h;
516     int i, n, size;
517
518     /*
519      * Go through our tree counting the handle objects currently
520      * engaged in useful activity.
521      */
522     ret = NULL;
523     n = size = 0;
524     if (handles_by_evtomain) {
525         for (i = 0; (h = index234(handles_by_evtomain, i)) != NULL; i++) {
526             if (h->u.g.busy) {
527                 if (n >= size) {
528                     size += 32;
529                     ret = sresize(ret, size, HANDLE);
530                 }
531                 ret[n++] = h->u.g.ev_to_main;
532             }
533         }
534     }
535
536     *nevents = n;
537     return ret;
538 }
539
540 static void handle_destroy(struct handle *h)
541 {
542     if (h->type == HT_OUTPUT)
543         bufchain_clear(&h->u.o.queued_data);
544     CloseHandle(h->u.g.ev_from_main);
545     CloseHandle(h->u.g.ev_to_main);
546     del234(handles_by_evtomain, h);
547     sfree(h);
548 }
549
550 void handle_free(struct handle *h)
551 {
552     /*
553      * If the handle is currently busy, we cannot immediately free
554      * it. Instead we must wait until it's finished its current
555      * operation, because otherwise the subthread will write to
556      * invalid memory after we free its context from under it.
557      */
558     assert(h && !h->u.g.moribund);
559     if (h->u.g.busy) {
560         /*
561          * Just set the moribund flag, which will be noticed next
562          * time an operation completes.
563          */
564         h->u.g.moribund = TRUE;
565     } else if (h->u.g.defunct) {
566         /*
567          * There isn't even a subthread; we can go straight to
568          * handle_destroy.
569          */
570         handle_destroy(h);
571     } else {
572         /*
573          * The subthread is alive but not busy, so we now signal it
574          * to die. Set the moribund flag to indicate that it will
575          * want destroying after that.
576          */
577         h->u.g.moribund = TRUE;
578         h->u.g.done = TRUE;
579         h->u.g.busy = TRUE;
580         SetEvent(h->u.g.ev_from_main);
581     }
582 }
583
584 void handle_got_event(HANDLE event)
585 {
586     struct handle *h;
587
588     assert(handles_by_evtomain);
589     h = find234(handles_by_evtomain, &event, handle_find_evtomain);
590     if (!h) {
591         /*
592          * This isn't an error condition. If two or more event
593          * objects were signalled during the same select operation,
594          * and processing of the first caused the second handle to
595          * be closed, then it will sometimes happen that we receive
596          * an event notification here for a handle which is already
597          * deceased. In that situation we simply do nothing.
598          */
599         return;
600     }
601
602     if (h->u.g.moribund) {
603         /*
604          * A moribund handle is already treated as dead from the
605          * external user's point of view, so do nothing with the
606          * actual event. Just signal the thread to die if
607          * necessary, or destroy the handle if not.
608          */
609         if (h->u.g.done) {
610             handle_destroy(h);
611         } else {
612             h->u.g.done = TRUE;
613             h->u.g.busy = TRUE;
614             SetEvent(h->u.g.ev_from_main);
615         }
616         return;
617     }
618
619     switch (h->type) {
620         int backlog;
621
622       case HT_INPUT:
623         h->u.i.busy = FALSE;
624
625         /*
626          * A signal on an input handle means data has arrived.
627          */
628         if (h->u.i.len == 0) {
629             /*
630              * EOF, or (nearly equivalently) read error.
631              */
632             h->u.i.gotdata(h, NULL, -h->u.i.readerr);
633             h->u.i.defunct = TRUE;
634         } else {
635             backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len);
636             handle_throttle(&h->u.i, backlog);
637         }
638         break;
639
640       case HT_OUTPUT:
641         h->u.o.busy = FALSE;
642
643         /*
644          * A signal on an output handle means we have completed a
645          * write. Call the callback to indicate that the output
646          * buffer size has decreased, or to indicate an error.
647          */
648         if (h->u.o.writeerr) {
649             /*
650              * Write error. Send a negative value to the callback,
651              * and mark the thread as defunct (because the output
652              * thread is terminating by now).
653              */
654             h->u.o.sentdata(h, -h->u.o.writeerr);
655             h->u.o.defunct = TRUE;
656         } else {
657             bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten);
658             h->u.o.sentdata(h, bufchain_size(&h->u.o.queued_data));
659             handle_try_output(&h->u.o);
660         }
661         break;
662
663       case HT_FOREIGN:
664         /* Just call the callback. */
665         h->u.f.callback(h->u.f.ctx);
666         break;
667     }
668 }
669
670 void handle_unthrottle(struct handle *h, int backlog)
671 {
672     assert(h->type == HT_INPUT);
673     handle_throttle(&h->u.i, backlog);
674 }
675
676 int handle_backlog(struct handle *h)
677 {
678     assert(h->type == HT_OUTPUT);
679     return bufchain_size(&h->u.o.queued_data);
680 }
681
682 void *handle_get_privdata(struct handle *h)
683 {
684     return h->u.g.privdata;
685 }