+void setup_external_log() noexcept
+{
+ if (! external_log_open) {
+
+ const char * saddrname = log_socket_path;
+ uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + strlen(saddrname) + 1;
+
+ struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
+ if (name == nullptr) {
+ log(LogLevel::ERROR, "Connecting to log socket: out of memory");
+ return;
+ }
+
+ name->sun_family = AF_UNIX;
+ strcpy(name->sun_path, saddrname);
+
+ int sockfd = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+ if (sockfd == -1) {
+ log(LogLevel::ERROR, "Error creating log socket: ", strerror(errno));
+ free(name);
+ return;
+ }
+
+ if (connect(sockfd, (struct sockaddr *) name, sockaddr_size) == 0 || errno == EINPROGRESS) {
+ // TODO for EINPROGRESS, set up a watcher so we can properly wait until
+ // connection is established (or fails) before we pass it to the logging subsystem.
+ try {
+ setup_main_log(sockfd);
+ }
+ catch (std::exception &e) {
+ log(LogLevel::ERROR, "Setting up log failed: ", e.what());
+ close(sockfd);
+ }
+ }
+ else {
+ // Note if connect fails, we haven't warned at all, because the syslog server might not
+ // have started yet. TODO, have a special startup flag to indicate when syslog should
+ // be available.
+ close(sockfd);
+ }
+
+ free(name);
+ }
+}
+