X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=command.c;h=5b17f116d53c93956faf60f88d903b233b7e9b69;hp=bb276a89b4acebf391a0875d8f81e1033d2130de;hb=HEAD;hpb=15fde2fd9f9e668b267ab4cfd9fc10db37804dcf diff --git a/command.c b/command.c index bb276a89..60c2aeba 100644 --- a/command.c +++ b/command.c @@ -21,8 +21,8 @@ #include "net.h" #include "server.h" #include "list.h" -#include "send.h" #include "sched.h" +#include "send.h" #include "vss.h" #include "daemon.h" #include "fd.h" @@ -47,12 +47,14 @@ extern struct misc_meta_data *mmd; int send_afs_status(struct command_context *cc, int parser_friendly); static bool subcmd_should_die; +/* + * Don't call PARA_XXX_LOG() here as we might already hold the log mutex. See + * generic_signal_handler() for details. + */ static void command_handler_sighandler(int s) { - if (s != SIGTERM) - return; - PARA_EMERG_LOG("terminating on signal %d\n", SIGTERM); - subcmd_should_die = true; + if (s == SIGTERM) + subcmd_should_die = true; } /* @@ -78,7 +80,7 @@ static char *vss_status_tohuman(unsigned int flags) */ static char *vss_get_status_flags(unsigned int flags) { - char *msg = para_malloc(5 * sizeof(char)); + char *msg = alloc(5 * sizeof(char)); msg[0] = (flags & VSS_PLAYING)? 'P' : '_'; msg[1] = (flags & VSS_NOMORE)? 'O' : '_'; @@ -505,6 +507,7 @@ static int com_stat(struct command_context *cc, struct lls_parse_result *lpr) * while we sleep. */ para_block_signal(SIGTERM); + para_block_signal(SIGUSR1); for (;;) { sigset_t set; /* @@ -536,8 +539,10 @@ static int com_stat(struct command_context *cc, struct lls_parse_result *lpr) * open a race window similar to the one described above. */ pselect(1, NULL, NULL, NULL, &ts, &set); - if (subcmd_should_die) + if (subcmd_should_die) { + PARA_EMERG_LOG("terminating on SIGTERM\n"); goto out; + } ret = -E_SERVER_CRASH; if (getppid() == 1) goto out; @@ -630,6 +635,13 @@ EXPORT_SERVER_CMD_HANDLER(ll); static int com_term(__a_unused struct command_context *cc, __a_unused struct lls_parse_result *lpr) { + /* + * The server catches SIGTERM and propagates this signal to all its + * children. We are about to exit anyway, but we'd leak tons of memory + * if being terminated by the signal. So we ignore the signal here and + * terminate via the normal exit path, deallocating all memory. + */ + para_sigaction(SIGTERM, SIG_IGN); kill(getppid(), SIGTERM); return 1; } @@ -698,7 +710,7 @@ static int com_ff(struct command_context *cc, struct lls_parse_result *lpr) { long promille; int i, ret; - char c, *errctx; + char *errctx; ret = lls(lls_check_arg_count(lpr, 1, 1, &errctx)); if (ret < 0) { @@ -706,21 +718,8 @@ static int com_ff(struct command_context *cc, struct lls_parse_result *lpr) return ret; } ret = para_atoi32(lls_input(0, lpr), &i); - if (ret < 0) { - if (ret != -E_ATOI_JUNK_AT_END) - return ret; - /* - * Compatibility code to keep the historic syntax (ff 30-) - * working. This can be removed after 0.7.0. - */ - ret = sscanf(lls_input(0, lpr), "%i%c", &i, &c); - if (ret <= 0) - return -E_COMMAND_SYNTAX; - if (ret > 1 && c == '-') { - PARA_WARNING_LOG("use of obsolete syntax\n"); - i = -i; - } - } + if (ret < 0) + return ret; mutex_lock(mmd_mutex); ret = -E_NO_AUDIO_FILE; if (!mmd->afd.afhi.chunks_total || !mmd->afd.afhi.seconds_total) @@ -812,19 +811,11 @@ static int parse_auth_request(char *buf, int len, const struct user **u, *p = '\0'; p++; create_argv(p, ",", &features); - /* - * Still accept sideband and AES feature requests (as a no-op) - * because some 0.6.x clients request them. The two checks - * below may be removed after 0.7.1. - */ for (i = 0; features[i]; i++) { - if (strcmp(features[i], "sideband") == 0) - continue; - if (strcmp(features[i], "aes_ctr128") == 0) - continue; /* - * ->sha256_requested can go away after 0.7.0 but the - * check has to stay until 0.9.0. + * ->sha256_requested can go away after 0.7.0 so that + * sha256 is used unconditionally, but we need to + * accept the feature request until 0.9.0. */ if (strcmp(features[i], "sha256") == 0) cf->sha256_requested = true; @@ -871,7 +862,7 @@ static int run_command(struct command_context *cc, struct iovec *iov) for (i = 0; p < end; i++) p += strlen(p) + 1; argc = i; - argv = para_malloc((argc + 1) * sizeof(char *)); + argv = arr_alloc(argc + 1, sizeof(char *)); for (i = 0, p = iov->iov_base; p < end; i++) { argv[i] = para_strdup(p); p += strlen(p) + 1; @@ -926,7 +917,7 @@ int handle_connect(int fd) int ret; unsigned char rand_buf[APC_CHALLENGE_SIZE + 2 * SESSION_KEY_LEN]; unsigned char challenge_hash[HASH2_SIZE]; - char *command = NULL, *buf = para_malloc(HANDSHAKE_BUFSIZE) /* must be on the heap */; + char *command = NULL, *buf = alloc(HANDSHAKE_BUFSIZE) /* must be on the heap */; size_t numbytes; struct command_context cc_struct = {.u = NULL}, *cc = &cc_struct; struct iovec iov;