+ if (!(access(lock_file_name, 0) == -1 && errno == ENOENT))
+ continue;
+
+ // Attempt to create TCP socket(s) and bind them to the
+ // appropriate port number. We won't set the X server to
+ // listen on a TCP socket but this does ensure that ssh
+ // isn't using and won't use this display number. This is
+ // roughly based on the x11_create_display_inet function
+ // in OpenSSH.
+
+ auto_addrinfo addr_list;
+
+ {
+ addrinfo hints = {};
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ char port_str[5 + 1];
+ std::sprintf(port_str, "%d", 6000 + display_num);
+ addrinfo * addr_list_temp;
+ int error = getaddrinfo(NULL, port_str, &hints,
+ &addr_list_temp);
+ if (error != 0)
+ throw std::runtime_error(
+ std::string("getaddrinfo: ")
+ .append(gai_strerror(error)));
+ addr_list.reset(addr_list_temp);
+ }
+
+ const addrinfo * addr;
+
+ for (addr = addr_list.get(); addr != NULL; addr = addr->ai_next)
+ {
+ // We're only interested in TCPv4 and TCPv6.
+ if (addr->ai_family != AF_INET && addr->ai_family != AF_INET6)
+ continue;
+ auto_fd & tcp_socket =
+ (addr->ai_family == AF_INET) ? tcp4_socket : tcp6_socket;
+
+ tcp_socket.reset(socket(addr->ai_family,
+ SOCK_STREAM,
+ addr->ai_protocol));
+ if (tcp_socket.get() < 0)
+ {
+ // If the family is unsupported, no-one can bind
+ // to this address, so this is not a problem.
+ if (errno == EAFNOSUPPORT
+# ifdef EPFNOSUPPORT
+ || errno == EPFNOSUPPORT
+# endif
+ )
+ continue;
+ throw std::runtime_error(
+ std::string("socket: ").append(strerror(errno)));
+ }
+
+ // Don't let TCPv6 sockets interfere with TCPv4 sockets.
+# ifdef IPV6_V6ONLY
+ if (addr->ai_family == AF_INET6)
+ {
+ int on = 1;
+ if (setsockopt(tcp_socket.get(), IPPROTO_IPV6, IPV6_V6ONLY,
+ &on, sizeof(on)) != 0)
+ {
+ throw std::runtime_error(
+ std::string("setsockopt IPV6_V6ONLY: ")
+ .append(strerror(errno)));
+ }
+ }
+# endif
+
+ if (bind(tcp_socket.get(), addr->ai_addr, addr->ai_addrlen)
+ != 0)
+ break;
+ }
+
+ // If we reached the end of the address list, we've
+ // successfully bound to all appropriate addresses for
+ // this display number, so we can use it.
+ if (addr == NULL)