Here is my manual implementation of socketpair system call that can create AF_INET sockets needed to implement some temporary workaround; don't know is it completely safe and robust, but it is okay for testing purposes.
int inet_socketpair(int type, int protocol, int sv[2])
{
int lfd;
int sfd;
int cfd;
struct sockaddr_in saddr;
struct sockaddr_in caddr;
socklen_t saddrlen;
/* initialize all fds with -1 to simplify cleanup */
lfd = -1;
sfd = -1;
cfd = -1;
/* create listening socket and client socket */
lfd = socket(AF_INET, type, protocol);
cfd = socket(AF_INET, type, protocol);
if ((lfd == -1) || (cfd == -1)) {
goto err;
}
/* start listen */
if (listen(lfd, 1) == -1) {
goto err;
}
/* get ephemeral port number allocated to listening socket */
memset(&saddr, 0, sizeof(saddr));
saddrlen = sizeof(saddr);
if (getsockname(lfd, (struct sockaddr*)&saddr, &saddrlen) == -1) {
goto err;
}
/* prepare server address needed to connect client socket */
memset(&caddr, 0, sizeof(caddr));
caddr.sin_family = AF_INET;
caddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
caddr.sin_port = saddr.sin_port;
/* connect client socket */
if (connect(cfd, (struct sockaddr*)&caddr, sizeof(caddr)) == -1) {
goto err;
}
/* accept server socket */
sfd = accept(lfd, NULL, NULL);
if (sfd == -1) {
goto err;
}
close(lfd);
sv[0] = sfd;
sv[1] = cfd;
return 0;
err:
close(lfd);
close(sfd);
close(cfd);
return -1;
}
int inet_socketpair(int type, int protocol, int sv[2])
{
int lfd;
int sfd;
int cfd;
struct sockaddr_in saddr;
struct sockaddr_in caddr;
socklen_t saddrlen;
/* initialize all fds with -1 to simplify cleanup */
lfd = -1;
sfd = -1;
cfd = -1;
/* create listening socket and client socket */
lfd = socket(AF_INET, type, protocol);
cfd = socket(AF_INET, type, protocol);
if ((lfd == -1) || (cfd == -1)) {
goto err;
}
/* start listen */
if (listen(lfd, 1) == -1) {
goto err;
}
/* get ephemeral port number allocated to listening socket */
memset(&saddr, 0, sizeof(saddr));
saddrlen = sizeof(saddr);
if (getsockname(lfd, (struct sockaddr*)&saddr, &saddrlen) == -1) {
goto err;
}
/* prepare server address needed to connect client socket */
memset(&caddr, 0, sizeof(caddr));
caddr.sin_family = AF_INET;
caddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
caddr.sin_port = saddr.sin_port;
/* connect client socket */
if (connect(cfd, (struct sockaddr*)&caddr, sizeof(caddr)) == -1) {
goto err;
}
/* accept server socket */
sfd = accept(lfd, NULL, NULL);
if (sfd == -1) {
goto err;
}
close(lfd);
sv[0] = sfd;
sv[1] = cfd;
return 0;
err:
close(lfd);
close(sfd);
close(cfd);
return -1;
}
Комментариев нет:
Отправить комментарий