]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windows/winhandl.c
d81054f36414c355b205ae1a612ab86733e1d08d
[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             /*
172              * The read operation has returned end-of-file. Telling
173              * that to the main thread will cause it to set its
174              * 'defunct' flag and dispose of the handle structure at
175              * the next opportunity, so we must not touch ctx at all
176              * after this.
177              */
178             break;
179         }
180
181         WaitForSingleObject(ctx->ev_from_main, INFINITE);
182         if (ctx->done) {
183             /*
184              * The main thread has asked us to shut down. Send back an
185              * event indicating that we've done so. Hereafter we must
186              * not touch ctx at all, because the main thread might
187              * have freed it.
188              */
189             SetEvent(ctx->ev_to_main);
190             break;
191         }
192     }
193
194     if (povl)
195         CloseHandle(oev);
196
197     return 0;
198 }
199
200 /*
201  * This is called after a succcessful read, or from the
202  * `unthrottle' function. It decides whether or not to begin a new
203  * read operation.
204  */
205 static void handle_throttle(struct handle_input *ctx, int backlog)
206 {
207     if (ctx->defunct)
208         return;
209
210     /*
211      * If there's a read operation already in progress, do nothing:
212      * when that completes, we'll come back here and be in a
213      * position to make a better decision.
214      */
215     if (ctx->busy)
216         return;
217
218     /*
219      * Otherwise, we must decide whether to start a new read based
220      * on the size of the backlog.
221      */
222     if (backlog < MAX_BACKLOG) {
223         SetEvent(ctx->ev_from_main);
224         ctx->busy = TRUE;
225     }
226 }
227
228 /* ----------------------------------------------------------------------
229  * Output threads.
230  */
231
232 /*
233  * Data required by an output thread.
234  */
235 struct handle_output {
236     /*
237      * Copy of the handle_generic structure.
238      */
239     HANDLE h;                          /* the handle itself */
240     HANDLE ev_to_main;                 /* event used to signal main thread */
241     HANDLE ev_from_main;               /* event used to signal back to us */
242     int moribund;                      /* are we going to kill this soon? */
243     int done;                          /* request subthread to terminate */
244     int defunct;                       /* has the subthread already gone? */
245     int busy;                          /* operation currently in progress? */
246     void *privdata;                    /* for client to remember who they are */
247
248     /*
249      * Data set at initialisation and then read-only.
250      */
251     int flags;
252
253     /*
254      * Data set by the main thread before signalling ev_from_main,
255      * and read by the input thread after receiving that signal.
256      */
257     char *buffer;                      /* the data to write */
258     DWORD len;                         /* how much data there is */
259
260     /*
261      * Data set by the input thread before signalling ev_to_main,
262      * and read by the main thread after receiving that signal.
263      */
264     DWORD lenwritten;                  /* how much data we actually wrote */
265     int writeerr;                      /* return value from WriteFile */
266
267     /*
268      * Data only ever read or written by the main thread.
269      */
270     bufchain queued_data;              /* data still waiting to be written */
271     enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
272
273     /*
274      * Callback function called when the backlog in the bufchain
275      * drops.
276      */
277     handle_outputfn_t sentdata;
278 };
279
280 static DWORD WINAPI handle_output_threadfunc(void *param)
281 {
282     struct handle_output *ctx = (struct handle_output *) param;
283     OVERLAPPED ovl, *povl;
284     HANDLE oev;
285     int writeret;
286
287     if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
288         povl = &ovl;
289         oev = CreateEvent(NULL, TRUE, FALSE, NULL);
290     } else {
291         povl = NULL;
292     }
293
294     while (1) {
295         WaitForSingleObject(ctx->ev_from_main, INFINITE);
296         if (ctx->done) {
297             /*
298              * The main thread has asked us to shut down. Send back an
299              * event indicating that we've done so. Hereafter we must
300              * not touch ctx at all, because the main thread might
301              * have freed it.
302              */
303             SetEvent(ctx->ev_to_main);
304             break;
305         }
306         if (povl) {
307             memset(povl, 0, sizeof(OVERLAPPED));
308             povl->hEvent = oev;
309         }
310
311         writeret = WriteFile(ctx->h, ctx->buffer, ctx->len,
312                              &ctx->lenwritten, povl);
313         if (!writeret)
314             ctx->writeerr = GetLastError();
315         else
316             ctx->writeerr = 0;
317         if (povl && !writeret && GetLastError() == ERROR_IO_PENDING) {
318             writeret = GetOverlappedResult(ctx->h, povl,
319                                            &ctx->lenwritten, TRUE);
320             if (!writeret)
321                 ctx->writeerr = GetLastError();
322             else
323                 ctx->writeerr = 0;
324         }
325
326         SetEvent(ctx->ev_to_main);
327         if (!writeret) {
328             /*
329              * The write operation has suffered an error. Telling that
330              * to the main thread will cause it to set its 'defunct'
331              * flag and dispose of the handle structure at the next
332              * opportunity, so we must not touch ctx at all after
333              * this.
334              */
335             break;
336         }
337     }
338
339     if (povl)
340         CloseHandle(oev);
341
342     return 0;
343 }
344
345 static void handle_try_output(struct handle_output *ctx)
346 {
347     void *senddata;
348     int sendlen;
349
350     if (!ctx->busy && bufchain_size(&ctx->queued_data)) {
351         bufchain_prefix(&ctx->queued_data, &senddata, &sendlen);
352         ctx->buffer = senddata;
353         ctx->len = sendlen;
354         SetEvent(ctx->ev_from_main);
355         ctx->busy = TRUE;
356     } else if (!ctx->busy && bufchain_size(&ctx->queued_data) == 0 &&
357                ctx->outgoingeof == EOF_PENDING) {
358         CloseHandle(ctx->h);
359         ctx->h = INVALID_HANDLE_VALUE;
360         ctx->outgoingeof = EOF_SENT;
361     }
362 }
363
364 /* ----------------------------------------------------------------------
365  * 'Foreign events'. These are handle structures which just contain a
366  * single event object passed to us by another module such as
367  * winnps.c, so that they can make use of our handle_get_events /
368  * handle_got_event mechanism for communicating with application main
369  * loops.
370  */
371 struct handle_foreign {
372     /*
373      * Copy of the handle_generic structure.
374      */
375     HANDLE h;                          /* the handle itself */
376     HANDLE ev_to_main;                 /* event used to signal main thread */
377     HANDLE ev_from_main;               /* event used to signal back to us */
378     int moribund;                      /* are we going to kill this soon? */
379     int done;                          /* request subthread to terminate */
380     int defunct;                       /* has the subthread already gone? */
381     int busy;                          /* operation currently in progress? */
382     void *privdata;                    /* for client to remember who they are */
383
384     /*
385      * Our own data, just consisting of knowledge of who to call back.
386      */
387     void (*callback)(void *);
388     void *ctx;
389 };
390
391 /* ----------------------------------------------------------------------
392  * Unified code handling both input and output threads.
393  */
394
395 struct handle {
396     HandleType type;
397     union {
398         struct handle_generic g;
399         struct handle_input i;
400         struct handle_output o;
401         struct handle_foreign f;
402     } u;
403 };
404
405 static tree234 *handles_by_evtomain;
406
407 static int handle_cmp_evtomain(void *av, void *bv)
408 {
409     struct handle *a = (struct handle *)av;
410     struct handle *b = (struct handle *)bv;
411
412     if ((unsigned)a->u.g.ev_to_main < (unsigned)b->u.g.ev_to_main)
413         return -1;
414     else if ((unsigned)a->u.g.ev_to_main > (unsigned)b->u.g.ev_to_main)
415         return +1;
416     else
417         return 0;
418 }
419
420 static int handle_find_evtomain(void *av, void *bv)
421 {
422     HANDLE *a = (HANDLE *)av;
423     struct handle *b = (struct handle *)bv;
424
425     if ((unsigned)*a < (unsigned)b->u.g.ev_to_main)
426         return -1;
427     else if ((unsigned)*a > (unsigned)b->u.g.ev_to_main)
428         return +1;
429     else
430         return 0;
431 }
432
433 struct handle *handle_input_new(HANDLE handle, handle_inputfn_t gotdata,
434                                 void *privdata, int flags)
435 {
436     struct handle *h = snew(struct handle);
437     DWORD in_threadid; /* required for Win9x */
438
439     h->type = HT_INPUT;
440     h->u.i.h = handle;
441     h->u.i.ev_to_main = CreateEvent(NULL, FALSE, FALSE, NULL);
442     h->u.i.ev_from_main = CreateEvent(NULL, FALSE, FALSE, NULL);
443     h->u.i.gotdata = gotdata;
444     h->u.i.defunct = FALSE;
445     h->u.i.moribund = FALSE;
446     h->u.i.done = FALSE;
447     h->u.i.privdata = privdata;
448     h->u.i.flags = flags;
449
450     if (!handles_by_evtomain)
451         handles_by_evtomain = newtree234(handle_cmp_evtomain);
452     add234(handles_by_evtomain, h);
453
454     CreateThread(NULL, 0, handle_input_threadfunc,
455                  &h->u.i, 0, &in_threadid);
456     h->u.i.busy = TRUE;
457
458     return h;
459 }
460
461 struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata,
462                                  void *privdata, int flags)
463 {
464     struct handle *h = snew(struct handle);
465     DWORD out_threadid; /* required for Win9x */
466
467     h->type = HT_OUTPUT;
468     h->u.o.h = handle;
469     h->u.o.ev_to_main = CreateEvent(NULL, FALSE, FALSE, NULL);
470     h->u.o.ev_from_main = CreateEvent(NULL, FALSE, FALSE, NULL);
471     h->u.o.busy = FALSE;
472     h->u.o.defunct = FALSE;
473     h->u.o.moribund = FALSE;
474     h->u.o.done = FALSE;
475     h->u.o.privdata = privdata;
476     bufchain_init(&h->u.o.queued_data);
477     h->u.o.outgoingeof = EOF_NO;
478     h->u.o.sentdata = sentdata;
479     h->u.o.flags = flags;
480
481     if (!handles_by_evtomain)
482         handles_by_evtomain = newtree234(handle_cmp_evtomain);
483     add234(handles_by_evtomain, h);
484
485     CreateThread(NULL, 0, handle_output_threadfunc,
486                  &h->u.o, 0, &out_threadid);
487
488     return h;
489 }
490
491 struct handle *handle_add_foreign_event(HANDLE event,
492                                         void (*callback)(void *), void *ctx)
493 {
494     struct handle *h = snew(struct handle);
495
496     h->type = HT_FOREIGN;
497     h->u.f.h = INVALID_HANDLE_VALUE;
498     h->u.f.ev_to_main = event;
499     h->u.f.ev_from_main = INVALID_HANDLE_VALUE;
500     h->u.f.defunct = TRUE;  /* we have no thread in the first place */
501     h->u.f.moribund = FALSE;
502     h->u.f.done = FALSE;
503     h->u.f.privdata = NULL;
504     h->u.f.callback = callback;
505     h->u.f.ctx = ctx;
506     h->u.f.busy = TRUE;
507
508     if (!handles_by_evtomain)
509         handles_by_evtomain = newtree234(handle_cmp_evtomain);
510     add234(handles_by_evtomain, h);
511
512     return h;
513 }
514
515 int handle_write(struct handle *h, const void *data, int len)
516 {
517     assert(h->type == HT_OUTPUT);
518     assert(h->u.o.outgoingeof == EOF_NO);
519     bufchain_add(&h->u.o.queued_data, data, len);
520     handle_try_output(&h->u.o);
521     return bufchain_size(&h->u.o.queued_data);
522 }
523
524 void handle_write_eof(struct handle *h)
525 {
526     /*
527      * This function is called when we want to proactively send an
528      * end-of-file notification on the handle. We can only do this by
529      * actually closing the handle - so never call this on a
530      * bidirectional handle if we're still interested in its incoming
531      * direction!
532      */
533     assert(h->type == HT_OUTPUT);
534     if (!h->u.o.outgoingeof == EOF_NO) {
535         h->u.o.outgoingeof = EOF_PENDING;
536         handle_try_output(&h->u.o);
537     }
538 }
539
540 HANDLE *handle_get_events(int *nevents)
541 {
542     HANDLE *ret;
543     struct handle *h;
544     int i, n, size;
545
546     /*
547      * Go through our tree counting the handle objects currently
548      * engaged in useful activity.
549      */
550     ret = NULL;
551     n = size = 0;
552     if (handles_by_evtomain) {
553         for (i = 0; (h = index234(handles_by_evtomain, i)) != NULL; i++) {
554             if (h->u.g.busy) {
555                 if (n >= size) {
556                     size += 32;
557                     ret = sresize(ret, size, HANDLE);
558                 }
559                 ret[n++] = h->u.g.ev_to_main;
560             }
561         }
562     }
563
564     *nevents = n;
565     return ret;
566 }
567
568 static void handle_destroy(struct handle *h)
569 {
570     if (h->type == HT_OUTPUT)
571         bufchain_clear(&h->u.o.queued_data);
572     CloseHandle(h->u.g.ev_from_main);
573     CloseHandle(h->u.g.ev_to_main);
574     del234(handles_by_evtomain, h);
575     sfree(h);
576 }
577
578 void handle_free(struct handle *h)
579 {
580     /*
581      * If the handle is currently busy, we cannot immediately free
582      * it. Instead we must wait until it's finished its current
583      * operation, because otherwise the subthread will write to
584      * invalid memory after we free its context from under it.
585      */
586     assert(h && !h->u.g.moribund);
587     if (h->u.g.busy) {
588         /*
589          * Just set the moribund flag, which will be noticed next
590          * time an operation completes.
591          */
592         h->u.g.moribund = TRUE;
593     } else if (h->u.g.defunct) {
594         /*
595          * There isn't even a subthread; we can go straight to
596          * handle_destroy.
597          */
598         handle_destroy(h);
599     } else {
600         /*
601          * The subthread is alive but not busy, so we now signal it
602          * to die. Set the moribund flag to indicate that it will
603          * want destroying after that.
604          */
605         h->u.g.moribund = TRUE;
606         h->u.g.done = TRUE;
607         h->u.g.busy = TRUE;
608         SetEvent(h->u.g.ev_from_main);
609     }
610 }
611
612 void handle_got_event(HANDLE event)
613 {
614     struct handle *h;
615
616     assert(handles_by_evtomain);
617     h = find234(handles_by_evtomain, &event, handle_find_evtomain);
618     if (!h) {
619         /*
620          * This isn't an error condition. If two or more event
621          * objects were signalled during the same select operation,
622          * and processing of the first caused the second handle to
623          * be closed, then it will sometimes happen that we receive
624          * an event notification here for a handle which is already
625          * deceased. In that situation we simply do nothing.
626          */
627         return;
628     }
629
630     if (h->u.g.moribund) {
631         /*
632          * A moribund handle is one which we have either already
633          * signalled to die, or are waiting until its current I/O op
634          * completes to do so. Either way, it's treated as already
635          * dead from the external user's point of view, so we ignore
636          * the actual I/O result. We just signal the thread to die if
637          * we haven't yet done so, or destroy the handle if not.
638          */
639         if (h->u.g.done) {
640             handle_destroy(h);
641         } else {
642             h->u.g.done = TRUE;
643             h->u.g.busy = TRUE;
644             SetEvent(h->u.g.ev_from_main);
645         }
646         return;
647     }
648
649     switch (h->type) {
650         int backlog;
651
652       case HT_INPUT:
653         h->u.i.busy = FALSE;
654
655         /*
656          * A signal on an input handle means data has arrived.
657          */
658         if (h->u.i.len == 0) {
659             /*
660              * EOF, or (nearly equivalently) read error.
661              */
662             h->u.i.defunct = TRUE;
663             h->u.i.gotdata(h, NULL, -h->u.i.readerr);
664         } else {
665             backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len);
666             handle_throttle(&h->u.i, backlog);
667         }
668         break;
669
670       case HT_OUTPUT:
671         h->u.o.busy = FALSE;
672
673         /*
674          * A signal on an output handle means we have completed a
675          * write. Call the callback to indicate that the output
676          * buffer size has decreased, or to indicate an error.
677          */
678         if (h->u.o.writeerr) {
679             /*
680              * Write error. Send a negative value to the callback,
681              * and mark the thread as defunct (because the output
682              * thread is terminating by now).
683              */
684             h->u.o.defunct = TRUE;
685             h->u.o.sentdata(h, -h->u.o.writeerr);
686         } else {
687             bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten);
688             h->u.o.sentdata(h, bufchain_size(&h->u.o.queued_data));
689             handle_try_output(&h->u.o);
690         }
691         break;
692
693       case HT_FOREIGN:
694         /* Just call the callback. */
695         h->u.f.callback(h->u.f.ctx);
696         break;
697     }
698 }
699
700 void handle_unthrottle(struct handle *h, int backlog)
701 {
702     assert(h->type == HT_INPUT);
703     handle_throttle(&h->u.i, backlog);
704 }
705
706 int handle_backlog(struct handle *h)
707 {
708     assert(h->type == HT_OUTPUT);
709     return bufchain_size(&h->u.o.queued_data);
710 }
711
712 void *handle_get_privdata(struct handle *h)
713 {
714     return h->u.g.privdata;
715 }