return (rc);
}
+/* Convert the IP address SA to a Unix-domain address SUN. Fail if the
+ * address seems already taken. If DESPARATEP then try cleaning up stale old
+ * sockets.
+ */
+static int encode_unused_inet_addr(struct sockaddr *sa,
+ struct sockaddr_un *sun,
+ int desperatep)
+{
+ address waddr;
+ struct sockaddr_un wsun;
+ int rc;
+ char buf[ADDRBUFSZ];
+
+ snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir,
+ present_sockaddr(sa, 0, buf, sizeof(buf)));
+ if ((rc = unix_socket_status(sun, !desperatep)) == USED) return (-1);
+ else if (rc == STALE) unlink(sun->sun_path);
+
+ wildcard_address(sa->sa_family, &waddr.sa);
+ port_to_sockaddr(&waddr.sa, port_from_sockaddr(sa));
+ snprintf(wsun.sun_path, sizeof(wsun.sun_path), "%s/%s", sockdir,
+ present_sockaddr(&waddr.sa, 0, buf, sizeof(buf)));
+ if ((rc = unix_socket_status(&wsun, !desperatep)) == USED) return (-1);
+ else if (rc == STALE) unlink(wsun.sun_path);
+
+ return (0);
+}
+
/* Encode the Internet address SA as a Unix-domain address SUN. If WANT is
* WANT_FRESH, and SA's port number is zero, then we pick an arbitrary local
* port. Otherwise we pick the port given. There's an unpleasant hack to
copy_sockaddr(&addr.sa, sa);
for (i = 0; i < 10; i++) {
port_to_sockaddr(&addr.sa, randrange(minautoport, maxautoport));
- snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir,
- present_sockaddr(&addr.sa, 0, buf, sizeof(buf)));
- if (unix_socket_status(sun, 1) == UNUSED) goto found;
+ if (!encode_unused_inet_addr(&addr.sa, sun, 0)) goto found;
}
for (desperatep = 0; desperatep < 2; desperatep++) {
for (i = minautoport; i <= maxautoport; i++) {
port_to_sockaddr(&addr.sa, i);
- snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir,
- present_sockaddr(&addr.sa, 0, buf, sizeof(buf)));
- rc = unix_socket_status(sun, !desperatep);
- switch (rc) {
- case STALE: unlink(sun->sun_path);
- case UNUSED: goto found;
- }
+ if (!encode_unused_inet_addr(&addr.sa, sun, 0)) goto found;
}
}
errno = EADDRINUSE;