* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: main.c,v 1.129 2003/09/23 15:11:58 kad Exp $"
+#define RCSID "$Id: main.c,v 1.134 2004/04/12 04:53:00 kad Exp $"
#include <stdio.h>
#include <ctype.h>
*/
disconnect:
new_phase(PHASE_DISCONNECT);
- the_channel->disconnect();
+ if (the_channel->disconnect)
+ the_channel->disconnect();
fail:
if (the_channel->cleanup)
info("Connect time %d.%d minutes.", t/10, t%10);
info("Sent %u bytes, received %u bytes.",
link_stats.bytes_out, link_stats.bytes_in);
+ link_stats_valid = 0;
}
}
/*
* kill_my_pg - send a signal to our process group, and ignore it ourselves.
+ * We assume that sig is currently blocked.
*/
static void
kill_my_pg(sig)
{
struct sigaction act, oldact;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, sig);
+
act.sa_handler = SIG_IGN;
act.sa_flags = 0;
kill(0, sig);
+ /*
+ * The kill() above made the signal pending for us, as well as
+ * the rest of our process group, but we don't want it delivered
+ * to us. It is blocked at the moment. Setting it to be ignored
+ * will cause the pending signal to be discarded. If we did the
+ * kill() after setting the signal to be ignored, it is unspecified
+ * (by POSIX) whether the signal is immediately discarded or left
+ * pending, and in fact Linux would leave it pending, and so it
+ * would be delivered after the current signal handler exits,
+ * leading to an infinite loop.
+ */
sigaction(sig, &act, &oldact);
sigaction(sig, &oldact, NULL);
}