/*
- * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005-2013 Andre Noll <maan@systemlinux.org>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
-/** \file audiod_command.c commands for para_audiod */
+/** \file audiod_command.c Commands for para_audiod. */
#include <regex.h>
#include <sys/types.h>
-#include <stdbool.h>
#include "para.h"
#include "audiod.cmdline.h"
#include "fd.h"
#include "audiod_command_list.h"
+extern struct sched sched;
extern char *stat_item_values[NUM_STAT_ITEMS];
+
+static struct audiod_command audiod_cmds[] = {DEFINE_AUDIOD_CMD_ARRAY};
+
/** Iterate over the array of all audiod commands. */
#define FOR_EACH_COMMAND(c) for (c = 0; audiod_cmds[c].name; c++)
num_clients++;
return 1;
}
+
+static void close_stat_client(struct stat_client *sc)
+{
+ PARA_INFO_LOG("closing client fd %d\n", sc->fd);
+ close(sc->fd);
+ list_del(&sc->node);
+ free(sc);
+ num_clients--;
+}
+
+/**
+ * Empty the status clients list.
+ *
+ * This iterates over the list of connected status clients, closes each client
+ * file descriptor and frees the resources.
+ */
+void close_stat_clients(void)
+{
+ struct stat_client *sc, *tmp;
+
+ list_for_each_entry_safe(sc, tmp, &client_list, node)
+ close_stat_client(sc);
+ assert(num_clients == 0);
+}
+
/**
* Write a message to all connected status clients.
*
struct para_buffer *b;
list_for_each_entry_safe(sc, tmp, &client_list, node) {
- int fd = sc->fd, ret;
+ int ret;
if (!((one << item_num) & sc->item_mask))
continue;
if (!b->buf)
(void)WRITE_STATUS_ITEM(b, item_num, "%s\n",
msg? msg : "");
- ret = write(fd, b->buf, b->offset);
+ ret = write(sc->fd, b->buf, b->offset);
if (ret == b->offset)
continue;
/* write error or short write */
- close(fd);
- num_clients--;
- PARA_INFO_LOG("deleting client on fd %d\n", fd);
- list_del(&sc->node);
- free(sc);
+ close_stat_client(sc);
dump_stat_client_list();
}
free(pb.buf);
* to each individual command to close the fd if necessary.
*/
-int com_help(int fd, int argc, char **argv)
+static int com_help(int fd, int argc, char **argv)
{
int i, ret;
char *buf;
return ret;
}
-int com_tasks(int fd, __a_unused int argc, __a_unused char **argv)
+static int com_tasks(int fd, __a_unused int argc, __a_unused char **argv)
{
- char *tl = get_task_list();
+ char *tl = get_task_list(&sched);
int ret = 1;
if (tl)
ret = client_write(fd, tl);
return ret;
}
-int com_stat(int fd, int argc, char **argv)
+static int com_stat(int fd, int argc, char **argv)
{
int i, ret, parser_friendly = 0;
uint64_t mask = 0;
if (!strncmp(arg, "-p", 2)) {
parser_friendly = 1;
b.flags = PBF_SIZE_PREFIX;
- continue;
}
}
if (i >= argc)
return ret;
}
-int com_grab(int fd, int argc, char **argv)
+static int com_grab(int fd, int argc, char **argv)
{
- return grab_client_new(fd, argc, argv);
+ return grab_client_new(fd, argc, argv, &sched);
}
-__noreturn int com_term(int fd, __a_unused int argc, __a_unused char **argv)
+__noreturn static int com_term(int fd, __a_unused int argc, __a_unused char **argv)
{
close(fd);
clean_exit(EXIT_SUCCESS, "terminating on user request");
}
-int com_on(int fd, __a_unused int argc, __a_unused char **argv)
+static int com_on(int fd, __a_unused int argc, __a_unused char **argv)
{
audiod_status = AUDIOD_ON;
close(fd);
return 1;
}
-int com_off(int fd, __a_unused int argc, __a_unused char **argv)
+static int com_off(int fd, __a_unused int argc, __a_unused char **argv)
{
audiod_status = AUDIOD_OFF;
close(fd);
return 1;
}
-int com_sb(int fd, __a_unused int argc, __a_unused char **argv)
+static int com_sb(int fd, __a_unused int argc, __a_unused char **argv)
{
audiod_status = AUDIOD_STANDBY;
close(fd);
return 1;
}
-int com_cycle(int fd, int argc, char **argv)
+static int com_cycle(int fd, int argc, char **argv)
{
switch (audiod_status) {
case AUDIOD_ON:
if (ret < 0)
goto out;
ret = create_argv(buf, "\n", &argv);
- if (ret < 0)
+ if (ret <= 0)
goto out;
argc = ret;
//PARA_INFO_LOG("argv[0]: %s, argc = %d\n", argv[0], argc);
/**
* Send the current audiod status to all connected stat clients.
+ *
+ * \param force Whether to write unchanged items.
*/
-void audiod_status_dump(void)
+void audiod_status_dump(bool force)
{
int slot_num = get_play_time_slot_num();
char *old, *new;
old = stat_item_values[SI_PLAY_TIME];
new = get_time_string(slot_num);
if (new) {
- if (!old || strcmp(old, new)) {
+ if (force || !old || strcmp(old, new)) {
free(old);
stat_item_values[SI_PLAY_TIME] = new;
stat_client_write_item(SI_PLAY_TIME);
new = get_server_uptime_str(now);
old = stat_item_values[SI_AUDIOD_UPTIME];
- if (!old || strcmp(old, new)) {
+ if (force || !old || strcmp(old, new)) {
free(old);
stat_item_values[SI_AUDIOD_UPTIME] = new;
stat_client_write_item(SI_AUDIOD_UPTIME);
old = stat_item_values[SI_AUDIOD_STATUS];
new = audiod_status_string();
- if (!old || strcmp(old, new)) {
+ if (force || !old || strcmp(old, new)) {
free(old);
stat_item_values[SI_AUDIOD_STATUS] = new;
stat_client_write_item(SI_AUDIOD_STATUS);
old = stat_item_values[SI_DECODER_FLAGS];
new = decoder_flags();
- if (!old || strcmp(old, new)) {
+ if (force || !old || strcmp(old, new)) {
free(old);
stat_item_values[SI_DECODER_FLAGS] = new;
stat_client_write_item(SI_DECODER_FLAGS);