read stdout from the on-start command to choose ALSA output device
refs GH-452
This commit is contained in:
@@ -109,6 +109,10 @@ static void help(void) {
|
||||
" *) default option\n");
|
||||
}
|
||||
|
||||
void set_alsa_out_dev(char *dev) {
|
||||
alsa_out_dev = dev;
|
||||
}
|
||||
|
||||
int open_mixer() {
|
||||
if (hardware_mixer) {
|
||||
debug(2, "Open Mixer");
|
||||
|
||||
@@ -80,6 +80,10 @@
|
||||
|
||||
#include <libdaemon/dlog.h>
|
||||
|
||||
#ifdef CONFIG_ALSA
|
||||
void set_alsa_out_dev(char *);
|
||||
#endif
|
||||
|
||||
// true if Shairport Sync is supposed to be sending output to the output device, false otherwise
|
||||
|
||||
static volatile int requested_connection_state_to_output = 1;
|
||||
@@ -504,11 +508,30 @@ void command_set_volume(double volume) {
|
||||
|
||||
void command_start(void) {
|
||||
if (config.cmd_start) {
|
||||
pid_t pid;
|
||||
int pipes[2];
|
||||
|
||||
if (config.cmd_start_returns_output && pipe(pipes) != 0) {
|
||||
warn("Unable to allocate pipe for popen of start command.");
|
||||
debug(1, "pipe finished with error %d", errno);
|
||||
return;
|
||||
}
|
||||
/*Spawn a child to run the program.*/
|
||||
pid_t pid = fork();
|
||||
pid = fork();
|
||||
if (pid == 0) { /* child process */
|
||||
int argC;
|
||||
char **argV;
|
||||
|
||||
if (config.cmd_start_returns_output) {
|
||||
close(pipes[0]);
|
||||
if (dup2(pipes[1], 1) < 0) {
|
||||
warn("Unable to reopen pipe as stdout for popen of start command");
|
||||
debug(1, "dup2 finished with error %d", errno);
|
||||
close(pipes[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// debug(1,"on-start command found.");
|
||||
if (poptParseArgvString(config.cmd_start, &argC, (const char ***)&argV) !=
|
||||
0) // note that argV should be free()'d after use, but we expect this fork to exit
|
||||
@@ -522,13 +545,27 @@ void command_start(void) {
|
||||
exit(127); /* only if execv fails */
|
||||
}
|
||||
} else {
|
||||
if (config.cmd_blocking) { /* pid!=0 means parent process and if blocking is true, wait for
|
||||
if (config.cmd_blocking || config.cmd_start_returns_output) { /* pid!=0 means parent process and if blocking is true, wait for
|
||||
process to finish */
|
||||
pid_t rc = waitpid(pid, 0, 0); /* wait for child to exit */
|
||||
if (rc != pid) {
|
||||
warn("Execution of on-start command returned an error.");
|
||||
debug(1, "on-start command %s finished with error %d", config.cmd_start, errno);
|
||||
}
|
||||
if (config.cmd_start_returns_output) {
|
||||
static char buffer[256];
|
||||
int len;
|
||||
close(pipes[1]);
|
||||
len = read(pipes[0], buffer, 255);
|
||||
close(pipes[0]);
|
||||
buffer[len] = '\0';
|
||||
if (buffer[len - 1] == '\n')
|
||||
buffer[len - 1] = '\0'; // strip trailing newlines
|
||||
debug(1, "received '%s' as the device to use from the on-start command", buffer);
|
||||
#ifdef CONFIG_ALSA
|
||||
set_alsa_out_dev(buffer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// debug(1,"Continue after on-start command");
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ typedef struct {
|
||||
int statistics_requested, use_negotiated_latencies;
|
||||
enum playback_mode_type playback_mode;
|
||||
char *cmd_start, *cmd_stop, *cmd_set_volume;
|
||||
int cmd_blocking;
|
||||
int cmd_blocking, cmd_start_returns_output;
|
||||
double tolerance; // allow this much drift before attempting to correct it
|
||||
enum stuffing_type packet_stuffing;
|
||||
int decoders_supported;
|
||||
|
||||
+11
@@ -694,6 +694,16 @@ int parse_options(int argc, char **argv) {
|
||||
"\"yes\" or \"no\"");
|
||||
}
|
||||
|
||||
if (config_lookup_string(config.cfg, "sessioncontrol.before_play_begins_returns_output", &str)) {
|
||||
if (strcasecmp(str, "no") == 0)
|
||||
config.cmd_start_returns_output = 0;
|
||||
else if (strcasecmp(str, "yes") == 0)
|
||||
config.cmd_start_returns_output = 1;
|
||||
else
|
||||
die("Invalid session control before_play_begins_returns_output option choice \"%s\". It should be "
|
||||
"\"yes\" or \"no\"");
|
||||
}
|
||||
|
||||
if (config_lookup_string(config.cfg, "sessioncontrol.allow_session_interruption", &str)) {
|
||||
config.dont_check_timeout = 0; // this is for legacy -- only set by -t 0
|
||||
if (strcasecmp(str, "no") == 0)
|
||||
@@ -1276,6 +1286,7 @@ int main(int argc, char **argv) {
|
||||
debug(1, "on-start action is \"%s\".", config.cmd_start);
|
||||
debug(1, "on-stop action is \"%s\".", config.cmd_stop);
|
||||
debug(1, "wait-cmd status is %d.", config.cmd_blocking);
|
||||
debug(1, "on-start returns output is %d.", config.cmd_start_returns_output);
|
||||
debug(1, "mdns backend \"%s\".", config.mdns_name);
|
||||
debug(2, "userSuppliedLatency is %d.", config.userSuppliedLatency);
|
||||
debug(2, "AirPlayLatency is %d.", config.AirPlayLatency);
|
||||
|
||||
Reference in New Issue
Block a user