signals.c
author viric@llimona
Mon, 08 Oct 2007 12:59:27 +0200
changeset 79 7d316733d4b1
parent 74 cb3184566c6e
child 82 5cbe47923060
permissions -rw-r--r--
Added filterdes.

/*
    Terminal Mixer - multi-point multi-user access to terminal applications
    Copyright (C) 2007  LluĂ­s Batlle i Rossell

    Please find the license in the provided COPYING file.
*/
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#include "main.h"
#include "handlers.h"

static int child;
static char old_alarm_handler_set;
static struct sigaction old_alarm_handler;

static int timeout_timed_out; 

static void forward_signals_to_child_handler(int val)
{
    kill(child, val);
}

static void update_window_size(int val)
{
    char *xterm_str;
    int len;

    pass_winsize_to_slave();

    kill(child, val);

    /* Resend the xterm string */
    xterm_str = get_xterm_resize_string();
    len = strlen(xterm_str);
    if (command_line.s_param.serve_unix)
        s_unix_send_to_connected(xterm_str, len);
    if (command_line.s_param.serve_tcp)
        s_tcp_send_to_connected(xterm_str, len);
#ifdef linux
    if (command_line.s_param.serve_eth)
        s_eth_send_to_connected(xterm_str, len);
#endif /* linux */
}

void install_signal_forwarders(int _child)
{
    struct sigaction act;

    child = _child;

    act.sa_handler = forward_signals_to_child_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    sigaction(SIGTERM, &act, 0);
    sigaction(SIGINT, &act, 0);

    act.sa_handler = update_window_size;
    sigaction(SIGWINCH, &act, 0);
}

static void alarm_handler(int x)
{
    timeout_timed_out = 1;
}

void program_timeout(int secs)
{
    struct sigaction act;
    struct sigaction *old;

    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    act.sa_handler = alarm_handler;

    if (old_alarm_handler_set)
        old = 0;
    else
        old = &old_alarm_handler;

    sigaction(SIGALRM, &act, old);

    old_alarm_handler_set = 1;
    timeout_timed_out = 0;

    alarm(secs);
}

int did_timeout_happen()
{
    return timeout_timed_out;
}

void unprogram_timeout()
{
    alarm(0);

    timeout_timed_out = 0;

    if (old_alarm_handler_set)
    {
        sigaction(SIGALRM, &old_alarm_handler, 0);
        old_alarm_handler_set = 0;
    }
}

void ignore_sighup()
{
    struct sigaction act;

    act.sa_handler = SIG_IGN;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    sigaction(SIGHUP, &act, 0);
}