]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge commit 'athcx/next' into next
authorAndre Noll <maan@systemlinux.org>
Sun, 19 Apr 2009 21:17:38 +0000 (23:17 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 19 Apr 2009 21:17:38 +0000 (23:17 +0200)
afs.c
audiod.c
command.c
error.h
fecdec_filter.c
gui.c
server.c
signal.c
signal.h

diff --git a/afs.c b/afs.c
index f4a44bbbe0af852a61d81488bfe2274e0879a52d..2ebc0089cdeb15dda9dbd7bd0e0cc7d592c7d824 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -805,10 +805,7 @@ static void register_signal_task(void)
 {
        struct signal_task *st = &signal_task_struct;
 
-       if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
-               PARA_EMERG_LOG("failed to ignore SIGPIPE\n");
-               exit(EXIT_FAILURE);
-       }
+       para_sigaction(SIGPIPE, SIG_IGN);
        st->fd = para_signal_init();
        PARA_INFO_LOG("signal pipe: fd %d\n", st->fd);
        para_install_sighandler(SIGINT);
index 3a2607defc2576b476628524102b5d8367985b89..6d7cce5efdf109f251dfa112fb5ed6593d2c0d02 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -286,7 +286,7 @@ static void setup_signal_handling(void)
        para_install_sighandler(SIGINT);
        para_install_sighandler(SIGTERM);
        para_install_sighandler(SIGHUP);
-       signal(SIGPIPE, SIG_IGN);
+       para_sigaction(SIGPIPE, SIG_IGN);
 }
 
 static void clear_slot(int slot_num)
index d08a71818cfb437c5cd6c02a13d6a7c2f3e56893..229ec5c6fcbdfcc6c015ef41e082db2ff3a90f23 100644 (file)
--- a/command.c
+++ b/command.c
@@ -30,6 +30,8 @@
 #include "user_list.h"
 #include "server_command_list.h"
 #include "afs_command_list.h"
+#include "sched.h"
+#include "signal.h"
 
 /** Commands including options must be shorter than this. */
 #define MAX_COMMAND_LEN 32768
@@ -42,15 +44,8 @@ extern int mmd_mutex;
 extern struct misc_meta_data *mmd;
 extern struct sender senders[];
 
-static void dummy(int s)
+static void dummy(__a_unused int s)
 {
-       /*
-        * At least on Solaris, SIGUSR1 is one-shot, i.e. the signal action is
-        * restored to the default state once the signal handler has been
-        * called.
-        */
-       if (s == SIGUSR1)
-               signal(SIGUSR1, dummy);
 }
 
 static void mmd_dup(struct misc_meta_data *new_mmd)
@@ -113,7 +108,7 @@ static char *get_status(struct misc_meta_data *nmmd)
        char *status, *flags; /* vss status info */
        char *ut = uptime_str();
        long offset = (nmmd->offset + 500) / 1000;
-       struct timeval now;
+       struct timeval current_time;
        struct tm mtime_tm;
 
        /* report real status */
@@ -123,7 +118,7 @@ static char *get_status(struct misc_meta_data *nmmd)
                localtime_r(&nmmd->mtime, &mtime_tm);
                strftime(mtime, 29, "%b %d %Y", &mtime_tm);
        }
-       gettimeofday(&now, NULL);
+       gettimeofday(&current_time, NULL);
        ret = make_message(
                "%s: %zu\n" /* file size */
                "%s: %s\n" /* mtime */
@@ -146,8 +141,8 @@ static char *get_status(struct misc_meta_data *nmmd)
                        (long unsigned)nmmd->stream_start.tv_sec,
                        (long unsigned)nmmd->stream_start.tv_usec,
                status_item_list[SI_CURRENT_TIME],
-                       (long unsigned)now.tv_sec,
-                       (long unsigned)now.tv_usec,
+                       (long unsigned)current_time.tv_sec,
+                       (long unsigned)current_time.tv_usec,
 
                nmmd->afd.verbose_ls_output
 
@@ -318,7 +313,7 @@ int com_stat(int fd, int argc, char * const * argv)
        struct misc_meta_data tmp, *nmmd = &tmp;
        char *s;
 
-       signal(SIGUSR1, dummy);
+       para_sigaction(SIGUSR1, dummy);
 
        if (argc > 1)
                num = atoi(argv[1]);
@@ -655,6 +650,14 @@ out:
 
 }
 
+static void reset_signals(void)
+{
+       para_sigaction(SIGCHLD, SIG_IGN);
+       para_sigaction(SIGINT, SIG_DFL);
+       para_sigaction(SIGTERM, SIG_DFL);
+       para_sigaction(SIGHUP, SIG_DFL);
+}
+
 /**
  * Perform user authentication and execute a command.
  *
@@ -694,11 +697,7 @@ __noreturn void handle_connect(int fd, const char *peername)
        char *p, *command = NULL;
        size_t numbytes;
 
-       signal(SIGCHLD, SIG_IGN);
-       signal(SIGINT, SIG_DFL);
-       signal(SIGTERM, SIG_DFL);
-       signal(SIGHUP, SIG_DFL);
-
+       reset_signals();
        /* we need a blocking fd here as recv() might return EAGAIN otherwise. */
        ret = mark_fd_blocking(fd);
        if (ret < 0)
diff --git a/error.h b/error.h
index 7de3f436510fa42833933aac0e333a3f56b3d0f9..81910e2d08f4cf8515c9fea2a87141da0e8eae4f 100644 (file)
--- a/error.h
+++ b/error.h
@@ -29,6 +29,8 @@ DEFINE_ERRLIST_OBJECT_ENUM;
 #define HTTP_SEND_ERRORS
 #define GGO_ERRORS
 #define COLOR_ERRORS
+#define SIGNAL_ERRORS
+
 
 extern const char **para_errlist[];
 
@@ -49,7 +51,7 @@ extern const char **para_errlist[];
 
 #define FECDEC_FILTER_ERRORS \
        PARA_ERROR(BAD_FEC_HEADER, "invalid fec header"), \
-       PARA_ERROR(BAD_SLICE_SIZE, "slice size too large"), \
+       PARA_ERROR(BAD_SLICE_SIZE, "slice size zero or too large"), \
        PARA_ERROR(BAD_SLICE_NUM, "invalid slice number"), \
        PARA_ERROR(FECDEC_OVERRUN, "fecdec output buffer overrun"), \
        PARA_ERROR(FECDEC_EOF, "received eof packet"), \
@@ -299,10 +301,6 @@ extern const char **para_errlist[];
        PARA_ERROR(FILTER_SYNTAX, "syntax error"), \
 
 
-#define SIGNAL_ERRORS \
-       PARA_ERROR(SIGNAL_SIG_ERR, "signal() returned SIG_ERR"), \
-
-
 #define STRING_ERRORS \
        PARA_ERROR(ATOI_OVERFLOW, "value too large"), \
        PARA_ERROR(STRTOLL, "unknown strtoll error"), \
index 794add49ec42d07c04ea826e36f8f77b80a9dad6..30ac818c360873f6aedadd19e55ca7e0f6209550 100644 (file)
  */
 #define NUM_FEC_GROUPS 3
 
-/** Size of the output buffer of the fecdec filter. */
-#define FECDEC_OUTBUF_SIZE (1024 * 1024) /* FIXME: This has to depend on the fec params */
+/** Default size of the output buffer of the fecdec filter. */
+#define FECDEC_DEFAULT_OUTBUF_SIZE (16 * 1024)
+/** Maximal size of the output buffer of the fecdec filter. */
+#define FECDEC_MAX_OUTBUF_SIZE (1024 * 1024)
 
 /** Data read from the header of a slice. */
 struct fec_header {
@@ -251,7 +253,7 @@ static enum fec_group_usability group_is_usable(struct fecdec_group *fg,
 static int decode_group(struct fecdec_group *fg, struct filter_node *fn)
 {
        int i, ret, sb = fg->h.slice_bytes;
-       size_t written = 0;
+       size_t written = 0, need;
        struct private_fecdec_data *pfd = fn->private_data;
        enum fec_group_usability u = group_is_usable(fg, pfd);
 
@@ -274,12 +276,18 @@ static int decode_group(struct fecdec_group *fg, struct filter_node *fn)
        PARA_DEBUG_LOG("writing group %d (%d/%d decoded data bytes)\n",
                fg->h.group_num, fg->h.group_bytes,
                fg->h.data_slices_per_group * sb);
+       need = fn->loaded + (fg->h.data_slices_per_group - i)* sb;
+       if (need > fn->bufsize) {
+               fn->bufsize = PARA_MAX(fn->bufsize * 2, need);
+               if (fn->bufsize > FECDEC_MAX_OUTBUF_SIZE)
+                       return -E_FECDEC_OVERRUN;
+               PARA_INFO_LOG("increasing fec buf to %zu\n", fn->bufsize);
+               fn->buf = para_realloc(fn->buf, fn->bufsize);
+       }
        for (; i < fg->h.data_slices_per_group; i++) {
                size_t n = sb;
                if (n + written > fg->h.group_bytes)
                        n = fg->h.group_bytes - written;
-               if (fn->loaded + n > fn->bufsize)
-                       return -E_FECDEC_OVERRUN;
                memcpy(fn->buf + fn->loaded, fg->data[i], n);
                fn->loaded += n;
                written += n;
@@ -358,7 +366,7 @@ static ssize_t fecdec(char *buf, size_t len, struct filter_node *fn)
        ret = read_fec_header(buf, len, &h);
        if (ret <= 0)
                return ret;
-       if (h.slice_bytes > fn->bufsize)
+       if (!h.slice_bytes || h.slice_bytes > fn->bufsize)
                return -E_BAD_SLICE_SIZE;
        if (h.slice_num > h.slices_per_group)
                return -E_BAD_SLICE_NUM;
@@ -379,13 +387,14 @@ static void fecdec_close(struct filter_node *fn)
                clear_group(fg);
        free(fn->buf);
        fn->buf = NULL;
+       fec_free(pfd->fec);
        free(fn->private_data);
        fn->private_data = NULL;
 }
 
 static void fecdec_open(struct filter_node *fn)
 {
-       fn->bufsize = FECDEC_OUTBUF_SIZE;
+       fn->bufsize = FECDEC_DEFAULT_OUTBUF_SIZE;
        fn->buf = para_malloc(fn->bufsize);
        fn->private_data = para_calloc(sizeof(struct private_fecdec_data));
        fn->loaded = 0;
diff --git a/gui.c b/gui.c
index 15422b96bc94a5c82fd29e93a11df7c4317c2e1c..fc2cd9a145d25ac5ff0197fa132a87f5492661f7 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -521,13 +521,12 @@ static void setup_signal_handling(void)
        para_install_sighandler(SIGCHLD);
        para_install_sighandler(SIGWINCH);
        para_install_sighandler(SIGUSR1);
-//     signal(SIGPIPE, SIG_IGN);
-       signal(SIGHUP, SIG_IGN);
+       para_sigaction(SIGHUP, SIG_IGN);
 }
 
 __noreturn static void do_exit(int ret)
 {
-       signal(SIGTERM, SIG_IGN);
+       para_sigaction(SIGTERM, SIG_IGN);
        kill(0, SIGTERM);
        exit(ret);
 }
index 1e4caf08c90d0e04233a987f6e520e19850c20c5..79e67818c87a1573b312c00091c8199f41c286ed 100644 (file)
--- a/server.c
+++ b/server.c
@@ -318,25 +318,15 @@ static void init_signal_task(void)
        st->task.post_select = signal_post_select;
        sprintf(st->task.status, "signal task");
 
+       PARA_NOTICE_LOG("setting up signal handling\n");
        st->fd = para_signal_init(); /* always successful */
-
-       PARA_NOTICE_LOG("setting up signal handlers\n");
-       if (para_install_sighandler(SIGINT) < 0)
-               goto err;
-       if (para_install_sighandler(SIGTERM) < 0)
-               goto err;
-       if (para_install_sighandler(SIGHUP) < 0)
-               goto err;
-       if (para_install_sighandler(SIGCHLD) < 0)
-               goto err;
-       if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
-               goto err;
+       para_install_sighandler(SIGINT);
+       para_install_sighandler(SIGTERM);
+       para_install_sighandler(SIGHUP);
+       para_install_sighandler(SIGCHLD);
+       para_sigaction(SIGPIPE, SIG_IGN);
        add_close_on_fork_list(st->fd);
        register_task(&st->task);
-       return;
-err:
-       PARA_EMERG_LOG("could not install signal handlers\n");
-       exit(EXIT_FAILURE);
 }
 
 static void command_pre_select(struct sched *s, struct task *t)
@@ -514,19 +504,13 @@ static void server_init(int argc, char **argv)
         * before the child gets a chance to ignore this signal -- only the
         * good die young.
         */
-       if (signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
-               PARA_EMERG_LOG("failed to ignore SIGUSR1\n");
-               exit(EXIT_FAILURE);
-       }
+       para_sigaction(SIGUSR1, SIG_IGN);
        /*
         * We have to install a SIGCHLD handler before the afs process is being
         * forked off. Otherwise, para_server does not notice if afs dies before
         * the SIGCHLD handler has been installed by init_signal_task() below.
         */
-       if (signal(SIGCHLD, tmp_sigchld_handler) == SIG_ERR) {
-               PARA_EMERG_LOG("failed to install temporary SIGCHLD handler\n");
-               exit(EXIT_FAILURE);
-       }
+       para_sigaction(SIGCHLD, tmp_sigchld_handler);
        PARA_NOTICE_LOG("initializing the audio file selector\n");
        afs_socket = init_afs();
        init_signal_task();
index acc87802b33a841f8f5d7f90b971ae97a3edc3b0..59a0d45aba7ad975fc287862308891435c4e9095 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -117,20 +117,49 @@ void para_reap_children(void)
 }
 
 /**
- * Wrapper around signal(2).
+ * Install the given handler for the given signal.
  *
  * \param sig The number of the signal to catch.
+ * \param handler to be installed, \p SIG_IGN, or \p SIG_DFL.
  *
- * This installs the generic signal handler for the given signal.
+ * This either succeeds or calls exit(EXIT_FAILURE).
  *
- * \return This function returns 1 on success and \p -E_SIGNAL_SIG_ERR on errors.
- *
- * \sa signal(2).
+ * \sa sigaction(2).
  */
-int para_install_sighandler(int sig)
+void para_sigaction(int sig, void (*handler)(int))
 {
+       struct sigaction act;
+
        PARA_DEBUG_LOG("catching signal %d\n", sig);
-       return signal(sig, &generic_signal_handler) == SIG_ERR?  -E_SIGNAL_SIG_ERR : 1;
+       act.sa_handler = handler;
+       sigemptyset(&act.sa_mask);
+       act.sa_flags = 0;
+       if (sig == SIGALRM) {
+               #ifdef SA_INTERRUPT /* SunOS */
+                       act.sa_flags |= SA_INTERRUPT;
+               #endif
+       } else {
+               #ifdef SA_RESTART /* BSD */
+                       act.sa_flags |= SA_RESTART;
+               #endif
+       }
+       if (sigaction(sig, &act, NULL) >= 0)
+               return;
+       PARA_EMERG_LOG("failed to install signal handler for signal %d\n",
+               sig);
+       exit(EXIT_FAILURE);
+}
+
+/**
+ * Install the generic signal handler for the given signal number.
+ *
+ * \param sig The number of the signal to catch.
+ *
+ * \sa signal(2), sigaction(2).
+ */
+void para_install_sighandler(int sig)
+{
+       para_sigaction(sig, &generic_signal_handler);
 }
 
 /**
index 962e074a5ed481b9c9de21708bdb07a42c91a3c7..685654d5aae87f64e8d02823521984d1291133f7 100644 (file)
--- a/signal.h
+++ b/signal.h
@@ -19,7 +19,8 @@ struct signal_task {
 };
 
 int para_signal_init(void);
-int para_install_sighandler(int);
+void para_sigaction(int sig, void (*handler)(int));
+void para_install_sighandler(int);
 void para_reap_children(void);
 int para_reap_child(pid_t *pid);
 int para_next_signal(void);