#include "signal.h"
#include "version.h"
+/** \cond server_cmd_aux_info */
#define SERVER_CMD_AUX_INFO(_arg) _arg,
static const unsigned server_command_perms[] = {LSG_SERVER_CMD_AUX_INFOS};
#undef SERVER_CMD_AUX_INFO
#define SERVER_CMD_AUX_INFO(_arg) #_arg,
static const char * const server_command_perms_txt[] = {LSG_SERVER_CMD_AUX_INFOS};
#undef SERVER_CMD_AUX_INFO
+/** \endcond server_cmd_aux_info */
/** Commands including options must be shorter than this. */
#define MAX_COMMAND_LEN 32768
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;
}
/*
*/
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' : '_';
}
EXPORT_SERVER_CMD_HANDLER(version);
-/** These status items are cleared if no audio file is currently open. */
+/** \cond empty_status_items */
+/* These status items are cleared if no audio file is currently open. */
#define EMPTY_STATUS_ITEMS \
ITEM(path) \
ITEM(directory) \
ITEM(amplification) \
ITEM(play_time) \
+/** \endcond empty_status_items */
+
/*
* Create a set of audio-file related status items with empty values. These are
* written to stat clients when no audio file is open.
* while we sleep.
*/
para_block_signal(SIGTERM);
+ para_block_signal(SIGUSR1);
for (;;) {
sigset_t set;
/*
* 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;
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;
}
{
long promille;
int i, ret;
- char c, *errctx;
+ char *errctx;
ret = lls(lls_check_arg_count(lpr, 1, 1, &errctx));
if (ret < 0) {
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)
*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;
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;
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;