diff --git a/lib/modules/Protocols.pmod/TELNET.pmod b/lib/modules/Protocols.pmod/TELNET.pmod index e04e71234cc6f4e72266cb03d32eb688be4b642a..e1d4c1f548b1c077e2d3145f8d264c5c8a69d7d2 100644 --- a/lib/modules/Protocols.pmod/TELNET.pmod +++ b/lib/modules/Protocols.pmod/TELNET.pmod @@ -1,5 +1,5 @@ // -// $Id: TELNET.pmod,v 1.4 1998/04/23 22:33:51 grubba Exp $ +// $Id: TELNET.pmod,v 1.5 1998/04/30 13:53:41 grubba Exp $ // // The TELNET protocol as described by RFC 764 and others. // @@ -92,12 +92,37 @@ class protocol //. Data queued to be sent. static private string to_send = ""; + //. + nonblocking_write + //. Tells if we have set the nonblocking write callback or not. + static private int nonblocking_write; + + //. - enable_write + //. Turns on the write callback if apropriate. + static private void enable_write() + { + if (!nonblocking_write && (write_cb || sizeof(to_send))) { + fd->set_nonblocking(got_data, send_data, close_cb, got_oob); + nonblocking_write = 1; + } + } + + //. - disable_write + //. Turns off the write callback if apropriate. + static private void disable_write() + { + if (!write_cb && !sizeof(to_send) && nonblocking_write) { + fd->set_nonblocking(got_data, 0, close_cb, got_oob); + nonblocking_write = 0; + } + } + //. - write //. Queues data to be sent to the other end of the connection. //. > s - String to send. void write(string s) { to_send += replace(s, "\377", "\377\377"); + enable_write(); } //. + write_raw @@ -106,6 +131,7 @@ class protocol void write_raw(string s) { to_send += s; + enable_write(); } //. - send_data @@ -114,7 +140,9 @@ class protocol static private void send_data() { if (!sizeof(to_send)) { - to_send = write_cb(id); + if (write_cb) { + to_send = write_cb(id); + } } if (!to_send) { // Support for delayed close. @@ -130,6 +158,7 @@ class protocol to_send = to_send[n..]; } + disable_write(); } //. + default_cb @@ -141,12 +170,15 @@ class protocol }, "AYT":lambda() { to_send += "\377\361"; // NOP + enable_write(); }, "WILL":lambda(int code) { to_send += sprintf("\377\376%c", code); // DON'T xxx + enable_write(); }, "DO":lambda(int code) { to_send += sprintf("\377\374%c", code); // WON'T xxx + enable_write(); }, ]); @@ -200,6 +232,7 @@ class protocol option_states[option] &= ~option_him_opposite; break; } + enable_write(); } //. - disable_option @@ -235,6 +268,7 @@ class protocol /* Error: Already queued an disable request */ break; } + enable_write(); } //. + synch @@ -535,6 +569,7 @@ class protocol rest = line; } } + enable_write(); } //. - set_write_callback @@ -543,7 +578,11 @@ class protocol void set_write_callback(function(mixed|void:string) w_cb) { write_cb = w_cb; - fd->set_nonblocking(got_data, w_cb && send_data, close_cb, got_oob); + if (w_cb) { + enable_write(); + } else { + disable_write(); + } } //. - create @@ -569,5 +608,6 @@ class protocol id = new_id; fd->set_nonblocking(got_data, w_cb && send_data, close_cb, got_oob); + nonblocking_write = !!w_cb; } }