/*
 * Server signal handling
 *
 * Copyright (C) 2003 Alexandre Julliard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <signal.h>
#include <stdio.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#include <unistd.h>

#include "file.h"
#include "object.h"
#include "process.h"
#include "thread.h"

#if defined(linux) && defined(__SIGRTMIN)
/* the signal used by linuxthreads as exit signal for clone() threads */
# define SIG_PTHREAD_CANCEL (__SIGRTMIN+1)
#endif

typedef void (*signal_callback)(void);

struct handler
{
    struct object    obj;         /* object header */
    struct fd       *fd;          /* file descriptor for the pipe side */
    int              pipe_write;  /* unix fd for the pipe write side */
    volatile int     pending;     /* is signal pending? */
    signal_callback  callback;    /* callback function */
};

static void handler_dump( struct object *obj, int verbose );
static void handler_destroy( struct object *obj );

static const struct object_ops handler_ops =
{
    sizeof(struct handler),   /* size */
    handler_dump,             /* dump */
    no_add_queue,             /* add_queue */
    NULL,                     /* remove_queue */
    NULL,                     /* signaled */
    NULL,                     /* satisfied */
    no_signal,                /* signal */
    no_get_fd,                /* get_fd */
    no_map_access,            /* map_access */
    no_lookup_name,           /* lookup_name */
    no_close_handle,          /* close_handle */
    handler_destroy           /* destroy */
};

static void handler_poll_event( struct fd *fd, int event );

static const struct fd_ops handler_fd_ops =
{
    NULL,                     /* get_poll_events */
    handler_poll_event,       /* poll_event */
    no_flush,                 /* flush */
    no_get_file_info,         /* get_file_info */
    no_queue_async,           /* queue_async */
    no_cancel_async           /* cancel_async */
};

static struct handler *handler_sighup;
static struct handler *handler_sigterm;
static struct handler *handler_sigint;
static struct handler *handler_sigchld;
static struct handler *handler_sigio;

static sigset_t blocked_sigset;

static int watchdog;

/* create a signal handler */
static struct handler *create_handler( signal_callback callback )
{
    struct handler *handler;
    int fd[2];

    if (pipe( fd ) == -1) return NULL;
    if (!(handler = alloc_object( &handler_ops )))
    {
        close( fd[0] );
        close( fd[1] );
        return NULL;
    }
    handler->pipe_write = fd[1];
    handler->pending    = 0;
    handler->callback   = callback;

    if (!(handler->fd = create_anonymous_fd( &handler_fd_ops, fd[0], &handler->obj )))
    {
        release_object( handler );
        return NULL;
    }
    set_fd_events( handler->fd, POLLIN );
    return handler;
}

/* handle a signal received for a given handler */
static void do_signal( struct handler *handler )
{
    if (!handler->pending)
    {
        char dummy = 0;
        handler->pending = 1;
        write( handler->pipe_write, &dummy, 1 );
    }
}

static void handler_dump( struct object *obj, int verbose )
{
    struct handler *handler = (struct handler *)obj;
    fprintf( stderr, "Signal handler fd=%p\n", handler->fd );
}

static void handler_destroy( struct object *obj )
{
    struct handler *handler = (struct handler *)obj;
    if (handler->fd) release_object( handler->fd );
    close( handler->pipe_write );
}

static void handler_poll_event( struct fd *fd, int event )
{
    struct handler *handler = get_fd_user( fd );

    if (event & (POLLERR | POLLHUP))
    {
        /* this is not supposed to happen */
        fprintf( stderr, "wineserver: Error on signal handler pipe\n" );
        release_object( handler );
    }
    else if (event & POLLIN)
    {
        char dummy;

        handler->pending = 0;
        read( get_unix_fd( handler->fd ), &dummy, 1 );
        handler->callback();
    }
}

/* SIGHUP callback */
static void sighup_callback(void)
{
#ifdef DEBUG_OBJECTS
    dump_objects();
#endif
}

/* SIGTERM callback */
static void sigterm_callback(void)
{
    flush_registry();
    exit(1);
}

/* SIGINT callback */
static void sigint_callback(void)
{
    kill_all_processes( NULL, 1 );
    flush_registry();
    exit(1);
}

/* SIGHUP handler */
static void do_sighup( int signum )
{
    do_signal( handler_sighup );
}

/* SIGTERM handler */
static void do_sigterm( int signum )
{
    do_signal( handler_sigterm );
}

/* SIGINT handler */
static void do_sigint( int signum )
{
    do_signal( handler_sigint );
}

/* SIGALRM handler */
static void do_sigalrm( int signum )
{
    watchdog = 1;
}

/* SIGCHLD handler */
static void do_sigchld( int signum )
{
    do_signal( handler_sigchld );
}

/* SIGIO handler */
#ifdef HAVE_SIGINFO_T_SI_FD
static void do_sigio( int signum, siginfo_t *si, void *x )
{
    do_signal( handler_sigio );
    do_change_notify( si->si_fd );
}
#endif

void start_watchdog(void)
{
    alarm( 3 );
    watchdog = 0;
}

void stop_watchdog(void)
{
    alarm( 0 );
    watchdog = 0;
}

int watchdog_triggered(void)
{
    return watchdog != 0;
}

void init_signals(void)
{
    struct sigaction action;

    if (!(handler_sighup  = create_handler( sighup_callback ))) goto error;
    if (!(handler_sigterm = create_handler( sigterm_callback ))) goto error;
    if (!(handler_sigint  = create_handler( sigint_callback ))) goto error;
    if (!(handler_sigchld = create_handler( sigchld_callback ))) goto error;
    if (!(handler_sigio   = create_handler( sigio_callback ))) goto error;

    sigemptyset( &blocked_sigset );
    sigaddset( &blocked_sigset, SIGCHLD );
    sigaddset( &blocked_sigset, SIGHUP );
    sigaddset( &blocked_sigset, SIGINT );
    sigaddset( &blocked_sigset, SIGALRM );
    sigaddset( &blocked_sigset, SIGIO );
    sigaddset( &blocked_sigset, SIGQUIT );
    sigaddset( &blocked_sigset, SIGTERM );
#ifdef SIG_PTHREAD_CANCEL
    sigaddset( &blocked_sigset, SIG_PTHREAD_CANCEL );
#endif

    action.sa_mask = blocked_sigset;
    action.sa_flags = 0;
    action.sa_handler = do_sigchld;
    sigaction( SIGCHLD, &action, NULL );
#ifdef SIG_PTHREAD_CANCEL
    sigaction( SIG_PTHREAD_CANCEL, &action, NULL );
#endif
    action.sa_handler = do_sighup;
    sigaction( SIGHUP, &action, NULL );
    action.sa_handler = do_sigint;
    sigaction( SIGINT, &action, NULL );
    action.sa_handler = do_sigalrm;
    sigaction( SIGALRM, &action, NULL );
    action.sa_handler = do_sigterm;
    sigaction( SIGQUIT, &action, NULL );
    sigaction( SIGTERM, &action, NULL );
    action.sa_handler = SIG_IGN;
    sigaction( SIGXFSZ, &action, NULL );
#ifdef HAVE_SIGINFO_T_SI_FD
    action.sa_sigaction = do_sigio;
    action.sa_flags = SA_SIGINFO;
    sigaction( SIGIO, &action, NULL );
#endif
    return;

error:
    fprintf( stderr, "failed to initialize signal handlers\n" );
    exit(1);
}

void close_signals(void)
{
    sigprocmask( SIG_BLOCK, &blocked_sigset, NULL );
    release_object( handler_sighup );
    release_object( handler_sigterm );
    release_object( handler_sigint );
    release_object( handler_sigchld );
    release_object( handler_sigio );
}
