Use getaddrinfo() to fill struct sockaddr_un. It now supports

SOCK_DGRAM and SOCK_SEQPACKET in addition to SOCK_STREAM.
This commit is contained in:
Hiroki Sato 2015-10-03 12:49:05 +00:00
parent 4c60a05d25
commit 1c9fbb5a26

View File

@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <netdb.h>
#endif
#include <ctype.h>
@ -302,31 +303,39 @@ raw_cat(int rfd)
static int
udom_open(const char *path, int flags)
{
struct sockaddr_un sou;
int fd;
unsigned int len;
bzero(&sou, sizeof(sou));
struct addrinfo hints, *res, *res0;
char rpath[PATH_MAX];
int fd, error;
/*
* Construct the unix domain socket address and attempt to connect
* Construct the unix domain socket address and attempt to connect.
*/
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd >= 0) {
sou.sun_family = AF_UNIX;
if ((len = strlcpy(sou.sun_path, path,
sizeof(sou.sun_path))) >= sizeof(sou.sun_path)) {
close(fd);
errno = ENAMETOOLONG;
bzero(&hints, sizeof(hints));
hints.ai_family = AF_LOCAL;
if (realpath(path, rpath) == NULL)
return (-1);
error = getaddrinfo(rpath, NULL, &hints, &res0);
if (error) {
warn("%s", gai_strerror(error));
errno = EINVAL;
return (-1);
}
len = offsetof(struct sockaddr_un, sun_path[len+1]);
if (connect(fd, (void *)&sou, len) < 0) {
for (res = res0; res != NULL; res = res->ai_next) {
fd = socket(res->ai_family, res->ai_socktype,
res->ai_protocol);
if (fd < 0) {
freeaddrinfo(res0);
return (-1);
}
error = connect(fd, res->ai_addr, res->ai_addrlen);
if (error == 0)
break;
else {
close(fd);
fd = -1;
}
}
freeaddrinfo(res0);
/*
* handle the open flags by shutting down appropriate directions