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