The while loop should be repeated, if the last write attempt was a partial write only. In this case, however, rc is greater than 0 (should be 1), not equal to 0.
The C library function initstate(), at least in macOS El Capitan, not only sets the state array given to it as the second argument, but also accesses the state array given to it in a previous call! (I don't know why, or if that behaviour is correct, but macOS seems to do that anyhow).
Therefore, we cannot pass a local variable to it. As soon as the player thread stops, it will be a dangling pointer, and when a new player thread is started afterwards, initstate() will dereference that dangling pointer with unforeseeable consequences.
- If playing_conn is already stopping, handle_announce() waits one second for it to stop. This gives the current RTSP connection a better chance to get the player, if it has been started very quickly after the previous RTSP connection had decided to stop. iTunes can sometimes be very quick in starting a new RTSP connection after tearing down the previous one, but shairport_sync unfortunately needs at least 100ms to shut down the old connection.
- cleanup_threads() sets playing_conn to NULL if it points to the removed thread, otherwise playing_conn would be a dangling pointer, which is bad, because handle_announce() dereferences it unless it is NULL.
die(), warn(), debug() and inform() write the string into a limited internal buffer first. They now use vsnprintf() instead of vsprintf() to prevent an overflow of that buffer.
Fix volume bug.
Many thanks for this. I think that in the past the program used to terminate in this case and I changed it to simply continuing and, inadvertently, to failing silently!
README.md previously did not include instructions for compiling the convolution filter. I’ve updated them to include the `--with-convolution` flag in `./configure`, and to include the requirement for libsndfile.