X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/84aa9f9339ef6fa104588dd510c433ef20a96fe1..3149c1e2b844685497d87db1a031197527101766:/server/play.c diff --git a/server/play.c b/server/play.c index 1530fe8..04d7d01 100644 --- a/server/play.c +++ b/server/play.c @@ -43,6 +43,7 @@ #include "mem.h" #include "configuration.h" #include "queue.h" +#include "server-queue.h" #include "trackdb.h" #include "play.h" #include "plugin.h" @@ -128,6 +129,7 @@ static int speaker_readable(ev_source *ev, int fd, void speaker_setup(ev_source *ev) { int sp[2], lfd; pid_t pid; + struct speaker_message sm; if(socketpair(PF_UNIX, SOCK_DGRAM, 0, sp) < 0) fatal(errno, "error calling socketpair"); @@ -160,9 +162,10 @@ void speaker_setup(ev_source *ev) { speaker_fd = sp[1]; xclose(sp[0]); cloexec(speaker_fd); - /* Don't need to make speaker_fd nonblocking because speaker_recv() uses - * MSG_DONTWAIT. */ - ev_fd(ev, ev_read, speaker_fd, speaker_readable, 0); + /* Wait for the speaker to be ready */ + speaker_recv(speaker_fd, &sm); + nonblock(speaker_fd); + ev_fd(ev, ev_read, speaker_fd, speaker_readable, 0, "speaker read"); } void speaker_reload(void) { @@ -282,15 +285,15 @@ static int find_player(const struct queue_entry *q) { } /* Return values from start() */ -#define START_OK 0 /* Succeeded. */ -#define START_HARDFAIL 1 /* Track is broken. */ -#define START_SOFTFAIL 2 /* Track OK, system (temporarily?) broken */ +#define START_OK 0 /**< @brief Succeeded. */ +#define START_HARDFAIL 1 /**< @brief Track is broken. */ +#define START_SOFTFAIL 2 /**< @brief Track OK, system (temporarily?) broken */ /** @brief Play or prepare @p q * @param ev Event loop * @param q Track to play/prepare * @param prepare_only If true, only prepares track - * @return @ref START_OK, @ref START_HARDFAIL or @ref START_SOFTFTAIL + * @return @ref START_OK, @ref START_HARDFAIL or @ref START_SOFTFAIL */ static int start(ev_source *ev, struct queue_entry *q, @@ -341,8 +344,11 @@ static int start(ev_source *ev, } /* Use the second arg as the tag if available (it's probably a command name), * otherwise the module name. */ - lfd = logfd(ev, (config->player.s[n].s[2] - ? config->player.s[n].s[2] : config->player.s[n].s[1])); + if(!isatty(2)) + lfd = logfd(ev, (config->player.s[n].s[2] + ? config->player.s[n].s[2] : config->player.s[n].s[1])); + else + lfd = -1; optc = config->player.s[n].n - 2; optv = (void *)&config->player.s[n].s[2]; while(optc > 0 && optv[0][0] == '-') { @@ -369,9 +375,11 @@ static int start(ev_source *ev, exitfn = _exit; ev_signal_atfork(ev); signal(SIGPIPE, SIG_DFL); - xdup2(lfd, 1); - xdup2(lfd, 2); - xclose(lfd); /* tidy up */ + if(lfd != -1) { + xdup2(lfd, 1); + xdup2(lfd, 2); + xclose(lfd); /* tidy up */ + } setpgid(0, 0); if((q->type & DISORDER_PLAYER_TYPEMASK) == DISORDER_PLAYER_RAW) { /* "Raw" format players always have their output send down a pipe @@ -383,6 +391,8 @@ static int start(ev_source *ev, fatal(errno, "error calling socketpair"); xshutdown(np[0], SHUT_WR); /* normalize reads from np[0] */ xshutdown(np[1], SHUT_RD); /* decoder writes to np[1] */ + blocking(np[0]); + blocking(np[1]); /* Start disorder-normalize */ if(!(npid = xfork())) { if(!xfork()) { @@ -392,7 +402,7 @@ static int start(ev_source *ev, snprintf(addr.sun_path, sizeof addr.sun_path, "%s/speaker", config->home); sfd = xsocket(PF_UNIX, SOCK_STREAM, 0); - if(connect(sfd, &addr, sizeof addr) < 0) + if(connect(sfd, (const struct sockaddr *)&addr, sizeof addr) < 0) fatal(errno, "connecting to %s", addr.sun_path); l = strlen(q->id); if(write(sfd, &l, sizeof l) < 0 @@ -463,11 +473,13 @@ static int start(ev_source *ev, error(errno, "error calling fork"); if(q->type & DISORDER_PLAYER_PREFORK) play_cleanup(q->pl, q->data); /* else would leak */ - xclose(lfd); + if(lfd != -1) + xclose(lfd); return START_SOFTFAIL; } store_player_pid(q->id, pid); - xclose(lfd); + if(lfd != -1) + xclose(lfd); setpgid(pid, pid); ev_child(ev, pid, 0, player_finished, q); D(("player subprocess ID %lu", (unsigned long)pid));