X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/43cab3f4d345611264d8dc14d1910bd202d605dd..bc06669bcf2c0d331e231d18c0e14023433f9e79:/windows/winhandl.c diff --git a/windows/winhandl.c b/windows/winhandl.c index c0e8232d..286f79a6 100644 --- a/windows/winhandl.c +++ b/windows/winhandl.c @@ -250,6 +250,7 @@ struct handle_output { * Data only ever read or written by the main thread. */ bufchain queued_data; /* data still waiting to be written */ + enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof; /* * Callback function called when the backlog in the bufchain @@ -320,6 +321,11 @@ static void handle_try_output(struct handle_output *ctx) ctx->len = sendlen; SetEvent(ctx->ev_from_main); ctx->busy = TRUE; + } else if (!ctx->busy && bufchain_size(&ctx->queued_data) == 0 && + ctx->outgoingeof == EOF_PENDING) { + CloseHandle(ctx->h); + ctx->h = INVALID_HANDLE_VALUE; + ctx->outgoingeof = EOF_SENT; } } @@ -408,6 +414,7 @@ struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata, h->u.o.done = FALSE; h->u.o.privdata = privdata; bufchain_init(&h->u.o.queued_data); + h->u.o.outgoingeof = EOF_NO; h->u.o.sentdata = sentdata; h->u.o.flags = flags; @@ -424,11 +431,28 @@ struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata, int handle_write(struct handle *h, const void *data, int len) { assert(h->output); + assert(h->u.o.outgoingeof == EOF_NO); bufchain_add(&h->u.o.queued_data, data, len); handle_try_output(&h->u.o); return bufchain_size(&h->u.o.queued_data); } +void handle_write_eof(struct handle *h) +{ + /* + * This function is called when we want to proactively send an + * end-of-file notification on the handle. We can only do this by + * actually closing the handle - so never call this on a + * bidirectional handle if we're still interested in its incoming + * direction! + */ + assert(h->output); + if (!h->u.o.outgoingeof == EOF_NO) { + h->u.o.outgoingeof = EOF_PENDING; + handle_try_output(&h->u.o); + } +} + HANDLE *handle_get_events(int *nevents) { HANDLE *ret;