Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2002-01-04 19:56:53 +0300
committerCorinna Vinschen <corinna@vinschen.de>2002-01-04 19:56:53 +0300
commitdc63cea5ed3a6f42d91d211c275bb67cb127539d (patch)
treee786d79ccfd2038a6e942a3e4ee8343ea655f176 /winsup/cygwin/net.cc
parentd48d56d07b65449524cdb30b38929cbcda22140e (diff)
* net.cc: Replace usage of AF_UNIX by Posix compliant AF_LOCAL
throughout. (socketpair): Explicitly allow SOCK_STREAM and SOCK_DGRAM socket types in families AF_UNIX and AF_LOCAL. Explicitly allow PF_UNSPEC, PF_LOCAL and PF_INET protocols. Return error otherwise. Implement datagram socketpairs.
Diffstat (limited to 'winsup/cygwin/net.cc')
-rw-r--r--winsup/cygwin/net.cc143
1 files changed, 114 insertions, 29 deletions
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index 9e02085e1..7ae505f39 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -541,7 +541,7 @@ cygwin_socket (int af, int type, int protocol)
{
debug_printf ("socket (%d, %d, %d)", af, type, protocol);
- soc = socket (AF_INET, type, af == AF_UNIX ? 0 : protocol);
+ soc = socket (AF_INET, type, af == AF_LOCAL ? 0 : protocol);
if (soc == INVALID_SOCKET)
{
@@ -578,7 +578,7 @@ static int get_inet_addr (const struct sockaddr *in, int inlen,
*outlen = inlen;
return 1;
}
- else if (in->sa_family == AF_UNIX)
+ else if (in->sa_family == AF_LOCAL)
{
int fd = _open (in->sa_data, O_RDONLY);
if (fd == -1)
@@ -897,7 +897,7 @@ cygwin_connect (int fd,
}
set_winsock_errno ();
}
- if (sock->get_addr_family () == AF_UNIX)
+ if (sock->get_addr_family () == AF_LOCAL)
{
if (!res || in_progress)
{
@@ -1215,7 +1215,7 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len)
WSAGetLastError () == WSAEWOULDBLOCK)
in_progress = TRUE;
- if (sock->get_addr_family () == AF_UNIX)
+ if (sock->get_addr_family () == AF_LOCAL)
{
if ((SOCKET) res != (SOCKET) INVALID_SOCKET || in_progress)
{
@@ -1276,7 +1276,7 @@ cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen)
fhandler_socket *sock = get (fd);
if (sock)
{
- if (my_addr->sa_family == AF_UNIX)
+ if (my_addr->sa_family == AF_LOCAL)
{
#define un_addr ((struct sockaddr_un *) my_addr)
struct sockaddr_in sin;
@@ -1293,19 +1293,19 @@ cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen)
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
if (bind (sock->get_socket (), (sockaddr *) &sin, len))
{
- syscall_printf ("AF_UNIX: bind failed %d", get_errno ());
+ syscall_printf ("AF_LOCAL: bind failed %d", get_errno ());
set_winsock_errno ();
goto out;
}
if (getsockname (sock->get_socket (), (sockaddr *) &sin, &len))
{
- syscall_printf ("AF_UNIX: getsockname failed %d", get_errno ());
+ syscall_printf ("AF_LOCAL: getsockname failed %d", get_errno ());
set_winsock_errno ();
goto out;
}
sin.sin_port = ntohs (sin.sin_port);
- debug_printf ("AF_UNIX: socket bound to port %u", sin.sin_port);
+ debug_printf ("AF_LOCAL: socket bound to port %u", sin.sin_port);
/* bind must fail if file system socket object already exists
so _open () is called with O_EXCL flag. */
@@ -1367,11 +1367,11 @@ cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen)
fhandler_socket *sock = get (fd);
if (sock)
{
- if (sock->get_addr_family () == AF_UNIX)
+ if (sock->get_addr_family () == AF_LOCAL)
{
struct sockaddr_un *sun = (struct sockaddr_un *) addr;
memset (sun, 0, *namelen);
- sun->sun_family = AF_UNIX;
+ sun->sun_family = AF_LOCAL;
/* According to SUSv2 "If the actual length of the address is greater
than the length of the supplied sockaddr structure, the stored
address will be truncated." We play it save here so that the
@@ -2322,17 +2322,34 @@ done:
/* socketpair: standards? */
/* Win32 supports AF_INET only, so ignore domain and protocol arguments */
extern "C" int
-socketpair (int, int type, int, int *sb)
+socketpair (int family, int type, int protocol, int *sb)
{
int res = -1;
SOCKET insock, outsock, newsock;
- struct sockaddr_in sock_in;
- int len = sizeof (sock_in);
+ struct sockaddr_in sock_in, sock_out;
+ int len;
+ cygheap_fdnew sb0;
if (__check_null_invalid_struct_errno (sb, 2 * sizeof(int)))
return -1;
- cygheap_fdnew sb0;
+ if (family != AF_LOCAL && family != AF_INET)
+ {
+ set_errno (EAFNOSUPPORT);
+ goto done;
+ }
+ if (type != SOCK_STREAM && type != SOCK_DGRAM)
+ {
+ set_errno (EPROTOTYPE);
+ goto done;
+ }
+ if ((family == AF_LOCAL && protocol != PF_UNSPEC && protocol != PF_LOCAL)
+ || (family == AF_INET && protocol != PF_UNSPEC && protocol != PF_INET))
+ {
+ set_errno (EPROTONOSUPPORT);
+ goto done;
+ }
+
if (sb0 < 0)
goto done;
else
@@ -2344,7 +2361,8 @@ socketpair (int, int type, int, int *sb)
sb[1] = sb1;
}
- /* create a listening socket */
+
+ /* create the first socket */
newsock = socket (AF_INET, type, 0);
if (newsock == INVALID_SOCKET)
{
@@ -2357,7 +2375,6 @@ socketpair (int, int type, int, int *sb)
sock_in.sin_family = AF_INET;
sock_in.sin_port = 0;
sock_in.sin_addr.s_addr = INADDR_ANY;
-
if (bind (newsock, (struct sockaddr *) &sock_in, sizeof (sock_in)) < 0)
{
debug_printf ("bind failed");
@@ -2365,7 +2382,7 @@ socketpair (int, int type, int, int *sb)
closesocket (newsock);
goto done;
}
-
+ len = sizeof (sock_in);
if (getsockname (newsock, (struct sockaddr *) &sock_in, &len) < 0)
{
debug_printf ("getsockname error");
@@ -2374,7 +2391,9 @@ socketpair (int, int type, int, int *sb)
goto done;
}
- listen (newsock, 2);
+ /* For stream sockets, create a listener */
+ if (type == SOCK_STREAM)
+ listen (newsock, 2);
/* create a connecting socket */
outsock = socket (AF_INET, type, 0);
@@ -2386,9 +2405,37 @@ socketpair (int, int type, int, int *sb)
goto done;
}
+ /* For datagram sockets, bind the 2nd socket to an unused address, too */
+ if (type == SOCK_DGRAM)
+ {
+ sock_out.sin_family = AF_INET;
+ sock_out.sin_port = 0;
+ sock_out.sin_addr.s_addr = INADDR_ANY;
+ if (bind (outsock, (struct sockaddr *) &sock_out, sizeof (sock_out)) < 0)
+ {
+ debug_printf ("bind failed");
+ set_winsock_errno ();
+ closesocket (newsock);
+ closesocket (outsock);
+ goto done;
+ }
+ len = sizeof (sock_out);
+ if (getsockname (outsock, (struct sockaddr *) &sock_out, &len) < 0)
+ {
+ debug_printf ("getsockname error");
+ set_winsock_errno ();
+ closesocket (newsock);
+ closesocket (outsock);
+ goto done;
+ }
+ }
+
+ /* Force IP address to loopback */
sock_in.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if (type == SOCK_DGRAM)
+ sock_out.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- /* Do a connect and accept the connection */
+ /* Do a connect */
if (connect (outsock, (struct sockaddr *) &sock_in,
sizeof (sock_in)) < 0)
{
@@ -2399,22 +2446,60 @@ socketpair (int, int type, int, int *sb)
goto done;
}
- insock = accept (newsock, (struct sockaddr *) &sock_in, &len);
- if (insock == INVALID_SOCKET)
+ if (type == SOCK_STREAM)
{
- debug_printf ("accept error");
- set_winsock_errno ();
+ /* For stream sockets, accept the connection and close the listener */
+ len = sizeof (sock_in);
+ insock = accept (newsock, (struct sockaddr *) &sock_in, &len);
+ if (insock == INVALID_SOCKET)
+ {
+ debug_printf ("accept error");
+ set_winsock_errno ();
+ closesocket (newsock);
+ closesocket (outsock);
+ goto done;
+ }
closesocket (newsock);
- closesocket (outsock);
- goto done;
+ }
+ else
+ {
+ /* For datagram sockets, connect the 2nd socket */
+ if (connect (newsock, (struct sockaddr *) &sock_out,
+ sizeof (sock_out)) < 0)
+ {
+ debug_printf ("connect error");
+ set_winsock_errno ();
+ closesocket (newsock);
+ closesocket (outsock);
+ goto done;
+ }
+ insock = newsock;
}
- closesocket (newsock);
res = 0;
- fdsock (sb[0], "/dev/tcp", insock);
-
- fdsock (sb[1], "/dev/tcp", outsock);
+ if (family == AF_LOCAL)
+ {
+ fhandler_socket *fh;
+
+ fh = fdsock (sb[0],
+ type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket",
+ insock);
+ fh->set_sun_path ("");
+ fh->set_addr_family (AF_LOCAL);
+ fh = fdsock (sb[1],
+ type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket",
+ outsock);
+ fh->set_sun_path ("");
+ fh->set_addr_family (AF_LOCAL);
+ }
+ else
+ {
+ fdsock (sb[0], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
+ insock)->set_addr_family (AF_INET);
+ fdsock (sb[1], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
+ outsock)->set_addr_family (AF_INET);
+ }
done:
syscall_printf ("%d = socketpair (...)", res);