int main()

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);
}