in fakeaudispd.cpp [148:296]
int main(int argc, char**argv) {
std::string bin_path;
std::string config_path;
std::string socket_path;
int opt;
while ((opt = getopt(argc, argv, "b:c:s:")) != -1) {
switch (opt) {
case 'b':
bin_path = optarg;
break;
case 'c':
config_path = optarg;
break;
case 's':
socket_path = optarg;
break;
default:
usage();
}
}
signal(SIGHUP, handle_sighup);
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, handle_sigchld);
int lfd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
if (-1 == lfd)
{
throw std::system_error(errno, std::system_category(), "socket(AF_UNIX, SOCK_STREAM)");
}
unlink(socket_path.c_str());
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
socket_path.copy(addr.sun_path, sizeof(addr.sun_path));
if (bind(lfd, (struct sockaddr *)&addr, sizeof(addr)))
{
close(lfd);
throw std::system_error(errno, std::system_category(), std::string("bind(AF_UNIX, ") + socket_path + ")");
}
chmod(socket_path.c_str(), 0666);
if (listen(lfd, 1) != 0) {
throw std::system_error(errno, std::system_category(), "listen()");
}
Plugin plugin(bin_path, config_path);
plugin.Start();
while (!stop) {
struct pollfd fds;
fds.fd = lfd;
fds.events = POLLIN;
fds.revents = 0;
if (hup) {
hup = false;
if (plugin.HasBinChanged()) {
plugin.Stop(true);
plugin.Start();
} else {
plugin.Hup();
}
}
auto ret = poll(&fds, 1, -1);
if (ret < 0) {
if (errno != EINTR) {
throw std::system_error(errno, std::system_category());
}
continue;
}
if ((fds.revents & POLLIN) == 0) {
continue;
}
std::cerr << "Waiting for connection" << std::endl;
socklen_t x = 0;
int fd = accept(lfd, NULL, &x);
if (-1 == fd) {
if (errno != EINTR) {
throw std::system_error(errno, std::system_category());
}
continue;
}
int flags;
if (-1 == (flags = fcntl(fd, F_GETFL, 0))) {
flags = 0;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
throw std::system_error(errno, std::system_category());
}
std::cerr << "Connected" << std::endl;
char data[1024];
size_t idx = 0;
while (!stop) {
struct pollfd fds;
fds.fd = fd;
fds.events = POLLIN;
fds.revents = 0;
if (hup) {
hup = false;
if (plugin.HasBinChanged()) {
plugin.Stop(true);
plugin.Start();
} else {
plugin.Hup();
}
}
auto ret = poll(&fds, 1, -1);
if (ret < 0) {
if (errno != EINTR) {
throw std::system_error(errno, std::system_category());
}
continue;
}
if ((fds.revents & POLLIN) != 0) {
auto ret = read(fd, data, sizeof(data));
if (ret == 0) {
close(fd);
break;
} else if (ret < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
exit(0);
}
throw std::system_error(errno, std::system_category());
}
ssize_t nw = write(plugin.GetFd(), data, ret);
if (nw < 0 || nw != ret) {
throw std::system_error(errno, std::system_category(), "write()");
}
}
}
}
plugin.Stop(false);
}