# # # patch "netsync.cc" # from [e422d4447dbdeadd9f8ae95565ee05e7fb4b4a87] # to [bbf01b7c90245d9e8403aa2ba4bcabf5b5edd599] # # patch "netxx_pipe.cc" # from [adc391ff54b62f4f759e3509d968d2f601b0b271] # to [f158a9bb22f2417f0ecea3375b196385f25fb7d0] # # patch "netxx_pipe_stdio_main.cc" # from [310dad2c7950f21e3ded58f6a3555d7e9ddc65bd] # to [23002052aacee92dd23aac8dd10895adabd5b1e0] # ============================================================ --- netsync.cc e422d4447dbdeadd9f8ae95565ee05e7fb4b4a87 +++ netsync.cc bbf01b7c90245d9e8403aa2ba4bcabf5b5edd599 @@ -2366,6 +2366,7 @@ build_stream_to_server(app_state & app, #endif Netxx::Address addr(address().c_str(), default_port, use_ipv6); + app.opts.use_transport_auth = app.lua.hook_use_transport_auth(u); return shared_ptr (new Netxx::Stream(addr, timeout)); } ============================================================ --- netxx_pipe.cc adc391ff54b62f4f759e3509d968d2f601b0b271 +++ netxx_pipe.cc f158a9bb22f2417f0ecea3375b196385f25fb7d0 @@ -184,7 +184,15 @@ Netxx::StdioStream::close (void) void Netxx::StdioStream::close (void) { - // nothing to do here + // close socket so client knows we disconnected +#ifdef WIN32 + // readfd, writefd are the same socket; only close it once + closesocket (readfd); +#else + // On Unix, they might be separate pipes; close both + close (readfd); + close (writefd); +#endif } Netxx::socket_type @@ -490,8 +498,10 @@ void unit_test_spawn (char *cmd) // netxx_pipe_stdio_main uses StdioStream, StdioProbe Netxx::SpawnedStream spawned (cmd, vector()); - string result; - Netxx::Probe probe; + char write_buf[1024]; + char read_buf[1024]; + int bytes; + Netxx::Probe probe; Netxx::Timeout timeout(2L), short_time(0,1000); // time out because no data is available @@ -499,6 +509,7 @@ void unit_test_spawn (char *cmd) probe.add(spawned, Netxx::Probe::ready_read); Netxx::Probe::result_type res = probe.ready(short_time); I(res.second==Netxx::Probe::ready_none); + I(res.first == -1); // write should be possible probe.clear(); @@ -510,13 +521,11 @@ void unit_test_spawn (char *cmd) // test binary transparency, lots of cycles for (int c = 0; c < 256; ++c) { - char write_buf[1024]; - char read_buf[1024]; + string result; write_buf[0] = c; write_buf[1] = 255 - c; spawned.write(write_buf, 2); - string result; while (result.size() < 2) { // wait for data to arrive probe.clear(); @@ -525,7 +534,7 @@ void unit_test_spawn (char *cmd) E(res.second & Netxx::Probe::ready_read, F("timeout reading data %d") % c); I(res.first == spawned.get_socketfd()); - int bytes = spawned.read(read_buf, sizeof(read_buf)); + bytes = spawned.read(read_buf, sizeof(read_buf)); result += string(read_buf, bytes); } I(result.size() == 2); @@ -533,6 +542,39 @@ void unit_test_spawn (char *cmd) I(static_cast(result[1]) == 255 - c); } + // Tell netxx_pipe_stdio_main to quit, closing its socket + write_buf[0] = 'q'; + write_buf[1] = 'u'; + write_buf[2] = 'i'; + write_buf[3] = 't'; + spawned.write(write_buf, 4); + + // Read ' quit' + { + string result; + + while (result.size() < 4) + { // wait for data to arrive + probe.clear(); + probe.add(spawned, Netxx::Probe::ready_read); + res = probe.ready(timeout); + E(res.second & Netxx::Probe::ready_read, F("timeout reading quit")); + I(res.first == spawned.get_socketfd()); + + bytes = spawned.read(read_buf, sizeof(read_buf)); + result += string(read_buf, bytes); + } + I(result.size() == 4); + I(result == "quit"); + } + + // Wait for socket to close; reported as timeout + probe.clear(); + probe.add(spawned, Netxx::Probe::ready_read); + res = probe.ready(timeout); + I(res.second==Netxx::Probe::ready_none); + I(res.first == -1); + spawned.close(); } ============================================================ --- netxx_pipe_stdio_main.cc 310dad2c7950f21e3ded58f6a3555d7e9ddc65bd +++ netxx_pipe_stdio_main.cc 23002052aacee92dd23aac8dd10895adabd5b1e0 @@ -57,7 +57,7 @@ int main (int argc, char *argv[]) probe.add (stream, Netxx::Probe::ready_read); stream.set_timeout (timeout); - // Exit when ready times out; socket has been closed + // Normally exit when told to, so we test client detection of closed socket for (;!quit;) try { @@ -65,7 +65,7 @@ int main (int argc, char *argv[]) if (-1 == probe_result.first) { - // timeout; assume we're running the probe:spawn_stdio unit test, and it's done (the socket closed) + fprintf (stderr, "ready timed out; socket closed\n"); quit = 1; continue; } @@ -97,6 +97,15 @@ int main (int argc, char *argv[]) else { stream.write (buffer, bytes_read); + + if (4 == bytes_read && + 'q' == buffer[0] && + 'u' == buffer[1] && + 'i' == buffer[2] && + 't' == buffer[3]) + { + quit = 1; + } } break;