X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=unix%2Fuxproxy.c;h=f808a67796c66cf3f6c37e99fdd241b788eac582;hb=0cc6fb8bfea07360afeac83ba67aceffb56499c8;hp=b441b8022d8ce3b5a19a4e9cef79016c18b2991e;hpb=a1f3b7a358adaa7c2a98359cd0373aa823eeb14b;p=PuTTY.git diff --git a/unix/uxproxy.c b/unix/uxproxy.c index b441b802..f808a677 100644 --- a/unix/uxproxy.c +++ b/unix/uxproxy.c @@ -29,6 +29,7 @@ struct Socket_localproxy_tag { bufchain pending_output_data; bufchain pending_input_data; + enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof; void *privptr; }; @@ -95,12 +96,14 @@ static void sk_localproxy_close (Socket s) { Local_Proxy_Socket ps = (Local_Proxy_Socket) s; - del234(localproxy_by_fromfd, ps); - del234(localproxy_by_tofd, ps); + if (ps->to_cmd >= 0) { + del234(localproxy_by_tofd, ps); + uxsel_del(ps->to_cmd); + close(ps->to_cmd); + } - uxsel_del(ps->to_cmd); + del234(localproxy_by_fromfd, ps); uxsel_del(ps->from_cmd); - close(ps->to_cmd); close(ps->from_cmd); sfree(ps); @@ -129,6 +132,14 @@ static int localproxy_try_send(Local_Proxy_Socket ps) } } + if (ps->outgoingeof == EOF_PENDING) { + del234(localproxy_by_tofd, ps); + close(ps->to_cmd); + uxsel_del(ps->to_cmd); + ps->to_cmd = -1; + ps->outgoingeof = EOF_SENT; + } + if (bufchain_size(&ps->pending_output_data) == 0) uxsel_del(ps->to_cmd); else @@ -141,6 +152,8 @@ static int sk_localproxy_write (Socket s, const char *data, int len) { Local_Proxy_Socket ps = (Local_Proxy_Socket) s; + assert(ps->outgoingeof == EOF_NO); + bufchain_add(&ps->pending_output_data, data, len); localproxy_try_send(ps); @@ -157,6 +170,16 @@ static int sk_localproxy_write_oob (Socket s, const char *data, int len) return sk_localproxy_write(s, data, len); } +static void sk_localproxy_write_eof (Socket s) +{ + Local_Proxy_Socket ps = (Local_Proxy_Socket) s; + + assert(ps->outgoingeof == EOF_NO); + ps->outgoingeof = EOF_PENDING; + + localproxy_try_send(ps); +} + static void sk_localproxy_flush (Socket s) { /* Local_Proxy_Socket ps = (Local_Proxy_Socket) s; */ @@ -233,6 +256,7 @@ Socket platform_new_connection(SockAddr addr, char *hostname, sk_localproxy_close, sk_localproxy_write, sk_localproxy_write_oob, + sk_localproxy_write_eof, sk_localproxy_flush, sk_localproxy_set_private_ptr, sk_localproxy_get_private_ptr, @@ -252,6 +276,7 @@ Socket platform_new_connection(SockAddr addr, char *hostname, ret->fn = &socket_fn_table; ret->plug = plug; ret->error = NULL; + ret->outgoingeof = EOF_NO; bufchain_init(&ret->pending_input_data); bufchain_init(&ret->pending_output_data); @@ -263,6 +288,7 @@ Socket platform_new_connection(SockAddr addr, char *hostname, if (pipe(to_cmd_pipe) < 0 || pipe(from_cmd_pipe) < 0) { ret->error = dupprintf("pipe: %s", strerror(errno)); + sfree(cmd); return (Socket)ret; } cloexec(to_cmd_pipe[1]); @@ -272,6 +298,7 @@ Socket platform_new_connection(SockAddr addr, char *hostname, if (pid < 0) { ret->error = dupprintf("fork: %s", strerror(errno)); + sfree(cmd); return (Socket)ret; } else if (pid == 0) { close(0); @@ -280,8 +307,8 @@ Socket platform_new_connection(SockAddr addr, char *hostname, dup2(from_cmd_pipe[1], 1); close(to_cmd_pipe[0]); close(from_cmd_pipe[1]); - fcntl(0, F_SETFD, 0); - fcntl(1, F_SETFD, 0); + noncloexec(0); + noncloexec(1); execl("/bin/sh", "sh", "-c", cmd, (void *)NULL); _exit(255); }