From a5bfc6871275ec3962208e23756f051f2d38350d Mon Sep 17 00:00:00 2001
From: Corinna Vinschen <corinna@vinschen.de>
Date: Wed, 6 Apr 2005 18:50:13 +0000
Subject: [PATCH] 	* fhandler_socket.cc (get_inet_addr): Add type
 parameter to return 	unix socket type.  Read socket type from unix socket
 file. 	(fhandler_socket::bind): Write socket type to unix socket file. 
 (fhandler_socket::connect): Return with errno EPROTOTYPE if 	socket type of
 socket doesn't match socket type of unix socket 	trying to connect to.

---
 winsup/cygwin/ChangeLog          |  9 +++++++++
 winsup/cygwin/fhandler_socket.cc | 23 +++++++++++++++++++----
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index bc1069a08..fbfff6aa2 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,12 @@
+2005-04-06  Corinna Vinschen  <corinna@vinschen.de>
+
+	* fhandler_socket.cc (get_inet_addr): Add type parameter to return
+	unix socket type.  Read socket type from unix socket file.
+	(fhandler_socket::bind): Write socket type to unix socket file.
+	(fhandler_socket::connect): Return with errno EPROTOTYPE if
+	socket type of socket doesn't match socket type of unix socket
+	trying to connect to.
+
 2005-04-06  Pierre Humblet <pierre.humblet@ieee.org>
 
 	* security.h (cygsidlist::addfromgr): Avoid duplicate entries.
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 8e7443e1d..150fb0f1c 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -48,7 +48,8 @@ fhandler_dev_random* entropy_source;
 /* cygwin internal: map sockaddr into internet domain address */
 static int
 get_inet_addr (const struct sockaddr *in, int inlen,
-	       struct sockaddr_in *out, int *outlen, int* secret = 0)
+	       struct sockaddr_in *out, int *outlen,
+	       int *type = NULL, int *secret = NULL)
 {
   int secret_buf [4];
   int* secret_ptr = (secret ? : secret_buf);
@@ -91,14 +92,20 @@ get_inet_addr (const struct sockaddr *in, int inlen,
       if (ReadFile (fh, buf, 128, &len, 0))
 	{
 	  struct sockaddr_in sin;
+	  char ctype;
 	  sin.sin_family = AF_INET;
-	  sscanf (buf + strlen (SOCKET_COOKIE), "%hu %08x-%08x-%08x-%08x",
+	  sscanf (buf + strlen (SOCKET_COOKIE), "%hu %c %08x-%08x-%08x-%08x",
 		  &sin.sin_port,
+		  &ctype,
 		  secret_ptr, secret_ptr + 1, secret_ptr + 2, secret_ptr + 3);
 	  sin.sin_port = htons (sin.sin_port);
 	  sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
 	  *out = sin;
 	  *outlen = sizeof sin;
+	  if (type)
+	    *type = (ctype == 's' ? SOCK_STREAM :
+	             ctype == 'd' ? SOCK_DGRAM
+		                  : 0);
 	  ret = 1;
 	}
       CloseHandle (fh);
@@ -656,7 +663,7 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
 	}
 
       char buf[sizeof (SOCKET_COOKIE) + 80];
-      __small_sprintf (buf, "%s%u ", SOCKET_COOKIE, sin.sin_port);
+      __small_sprintf (buf, "%s%u %c ", SOCKET_COOKIE, sin.sin_port, get_socket_type () == SOCK_STREAM ? 's' : get_socket_type () == SOCK_DGRAM ? 'd' : '-');
       af_local_set_secret (strchr (buf, '\0'));
       DWORD blen = strlen (buf) + 1;
       if (!WriteFile (fh, buf, blen, &blen, 0))
@@ -689,10 +696,18 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
   bool in_progress = false;
   struct sockaddr_in sin;
   DWORD err;
+  int type;
 
-  if (!get_inet_addr (name, namelen, &sin, &namelen, connect_secret))
+  if (!get_inet_addr (name, namelen, &sin, &namelen, &type, connect_secret))
     return -1;
 
+  if (get_addr_family () == AF_LOCAL && get_socket_type () != type)
+    {
+      WSASetLastError (WSAEPROTOTYPE);
+      set_winsock_errno ();
+      return -1;
+    }
+
   res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
 
   if (!res)