diff -uprN /winsup/fhandler.cc winsup/fhandler.cc
--- /winsup/fhandler.cc	Thu Jul 15 06:49:18 1999
+++ winsup/fhandler.cc	Tue Jul 27 06:01:26 1999
@@ -925,6 +925,8 @@ fhandler_disk_file::fstat (struct stat *
       buf->st_mode &= ~S_IFMT;
       if (get_symlink_p ())
 	buf->st_mode |= S_IFLNK;
+      else if (get_socket_p ())
+	buf->st_mode |= S_IFSOCK;
       else if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 	buf->st_mode |= S_IFDIR;
       else
@@ -941,6 +943,8 @@ fhandler_disk_file::fstat (struct stat *
 
       if (get_symlink_p ())
 	buf->st_mode |= S_IFLNK;
+      else if (get_socket_p ())
+	buf->st_mode |= S_IFSOCK;
       else
 	switch (GetFileType (get_handle ()))
 	  {
@@ -1195,6 +1199,7 @@ fhandler_disk_file::open (path_conv& rea
 
   set_symlink_p (real_path.issymlink ());
   set_execable_p (real_path.isexec ());
+  set_socket_p (real_path.issocket ());
 
 out:
   syscall_printf ("%d = fhandler_disk_file::open (%s, %p)", res,
diff -uprN /winsup/fhandler.h winsup/fhandler.h
--- /winsup/fhandler.h	Thu Jul 15 06:49:18 1999
+++ winsup/fhandler.h	Thu Jul 29 03:20:16 1999
@@ -62,6 +62,8 @@ enum
 				   windows_path_name_ on destruction. */
   FH_NOEINTR = 0x01000000,	/* Set if I/O should be uninterruptible. */
   FH_FFIXUP  = 0x02000000,	/* Set if need to fixup after fork. */
+  FH_LOCAL   = 0x04000000,	/* File is unix domain socket */
+  FH_FIFO    = 0x08000000,	/* File is FIFO */
   FH_HASACLS = 0x40000000,	/* True of fs of file has ACLS */
 
   /* Device flags */
@@ -195,6 +197,10 @@ public:
   void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); }
   void set_symlink_p () { FHSETF (SYMLINK); }
 
+  int get_socket_p () { return FHISSETF (LOCAL); }
+  void set_socket_p (int val) { FHCONDSETF (val, LOCAL); }
+  void set_socket_p () { FHSETF (LOCAL); }
+
   int get_execable_p () { return FHISSETF (EXECABL); }
   void set_execable_p (int val) { FHCONDSETF (val, EXECABL); }
   void set_execable_p () { FHSETF (EXECABL); }
@@ -290,6 +296,8 @@ public:
 
 class fhandler_socket: public fhandler_base
 {
+private:
+  int addr_family;
 public:
   fhandler_socket (const char *name = 0);
   fhandler_socket (unsigned int, const char *name = 0);
@@ -306,6 +314,8 @@ public:
   select_record *select_write (select_record *s);
   select_record *select_except (select_record *s);
   int ready_for_read (int fd, DWORD howlong, int ignra);
+  int get_addr_family () {return addr_family;}
+  void set_addr_family (int af) {addr_family = af;}
 };
 
 class fhandler_pipe: public fhandler_base
diff -uprN /winsup/include/sys/un.h winsup/include/sys/un.h
--- /winsup/include/sys/un.h	Thu Jan 01 04:00:00 1970
+++ winsup/include/sys/un.h	Thu Jul 29 03:32:29 1999
@@ -0,0 +1,9 @@
+#ifndef _SYS_UN_H
+#define _SYS_UN_H
+
+struct sockaddr_un {
+  unsigned short	sun_family;	/* address family, AF_xxx	*/
+  char			sun_path[108];	/* 108 bytes of socket address	*/
+};
+
+#endif
diff -uprN /winsup/net.cc winsup/net.cc
--- /winsup/net.cc	Fri Jul 02 07:19:24 1999
+++ winsup/net.cc	Sat Jul 31 20:43:48 1999
@@ -15,6 +15,7 @@ details. */
 #include <stdio.h>
 #include <errno.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 
 #define Win32_Winsock
 #include "winsup.h"
@@ -371,29 +372,33 @@ cygwin_socket (int af, int type, int pro
   if (fd < 0)
     {
       set_errno (ENMFILE);
-      goto done;
     }
+  else
+    {
+      debug_printf ("socket (%d, %d, %d)", af, type, protocol);
 
-  debug_printf ("socket (%d, %d, %d)", af, type, protocol);
+      soc = socket (AF_INET, type, 0);
 
-  soc = socket (af, type, protocol);
+      if (soc == INVALID_SOCKET)
+        {
+          set_winsock_errno ();
+          goto done;
+        }
 
-  if (soc == INVALID_SOCKET)
-    {
-      set_winsock_errno ();
-      goto done;
-    }
+      soc = duplicate_socket (soc);
 
-  soc = duplicate_socket (soc);
+      const char *name;
+      if (af == AF_INET)
+        name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp");
+      else
+        name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");
 
-  const char *name;
-  if (af == AF_INET)
-    name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp");
-  else
-    name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");
+      fdsock (fd, name, soc);
+      res = fd;
+      fhandler_socket *h = (fhandler_socket *) dtable[fd];
 
-  fdsock (fd, name, soc);
-  res = fd;
+      h->set_addr_family (af);
+    }
 
 done:
   out ("socket");
@@ -402,6 +407,43 @@ done:
   return res;
 }
 
+/* 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)
+{
+  if (in->sa_family == AF_INET)
+    {
+      *out = * (sockaddr_in *)in;
+      *outlen = inlen;
+      return 1;
+    }
+  else if (in->sa_family == AF_UNIX)
+    {
+      sockaddr_in sin;
+      char buf[32];
+
+      memset (buf, 0, sizeof buf);
+      int fd = open (in->sa_data, O_RDONLY);
+      if (fd == -1)
+	return 0;
+      if (read (fd, buf, sizeof buf) == -1)
+	return 0;
+      sin.sin_family = AF_INET;
+      sscanf (buf + strlen (SOCKET_COOKIE), "%hu", &sin.sin_port);
+      sin.sin_port = htons (sin.sin_port);
+      sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+      *out = sin;
+      *outlen = sizeof sin;
+      return 1;
+    }
+  else
+    {
+      set_errno (EAFNOSUPPORT);
+      return 0;
+    }
+}
+
 /* exported as sendto: standards? */
 extern "C"
 int
@@ -415,8 +457,14 @@ cygwin_sendto (int fd,
   fhandler_socket *h = (fhandler_socket *) dtable[fd];
 
   in ("sendto");
+
+  sockaddr_in sin;
+
+  if (get_inet_addr (to, tolen, &sin, &tolen) == 0)
+    return -1;
+  
   int res = sendto (h->get_socket (), (const char *) buf, len,
-						      flags, to, tolen);
+				flags, (sockaddr *) &sin, tolen);
   if (res == SOCKET_ERROR)
     {
       set_winsock_errno ();
@@ -440,6 +488,7 @@ cygwin_recvfrom (int fd,
   in ("recvfrom");
 
   debug_printf ("recvfrom %d", h->get_socket ());
+  
   int res = recvfrom (h->get_socket (), buf, len, flags, from, fromlen);
   if (res == SOCKET_ERROR)
     {
@@ -598,13 +647,18 @@ cygwin_connect (int fd,
   in ("connect");
   int res;
   fhandler_socket *sock = get (fd);
+  sockaddr_in sin;
+
+  if (get_inet_addr (name, namelen, &sin, &namelen) == 0)
+    return -1;
+  
   if (!sock)
     {
       res = -1;
     }
   else
     {
-      res = connect (sock->get_socket (), name, namelen);
+      res = connect (sock->get_socket (), (sockaddr *) &sin, namelen);
       if (res)
 	set_winsock_errno ();
       out ("connect");
@@ -738,9 +792,18 @@ cygwin_accept (int fd, struct sockaddr *
   int res = -1;
 
   in ("accept");
+  
   fhandler_socket *sock = get (fd);
   if (sock)
     {
+
+      /* accept on NT fails if len < sizeof (sockaddr_in)
+       * some programs set len to 
+       * sizeof(name.sun_family) + strlen(name.sun_path) for UNIX domain
+       */
+      if (len && ((unsigned) *len < sizeof (struct sockaddr_in)))
+	*len = sizeof (struct sockaddr_in);
+
       res = accept (sock->get_socket (), peer, len);  // can't use a blocking call inside a lock
 
       SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK," accept");
@@ -780,10 +843,67 @@ cygwin_bind (int fd, struct sockaddr *my
   fhandler_socket *sock = get (fd);
   if (sock)
     {
-      res = bind (sock->get_socket (), my_addr, addrlen);
-      if (res)
-	set_winsock_errno ();
+      if (my_addr->sa_family == AF_UNIX)
+	{
+	  struct sockaddr_in sin;
+	  int len = sizeof sin;
+	  int fd;
+
+	  sin.sin_family = AF_INET;
+	  sin.sin_port = 0;
+	  sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+	  res = bind (sock->get_socket (), (sockaddr *) &sin, len);
+	  if (res)
+	    {
+	      set_winsock_errno ();
+	      syscall_printf ("AF_UNIX: bind failed %d", get_errno ());
+	      goto out;
+	    }
+	  res = getsockname (sock->get_socket (), (sockaddr *) &sin, &len);
+	  if (res)
+	    {
+	      set_winsock_errno ();
+	      syscall_printf ("AF_UNIX: getsockname failed %d", get_errno ());
+	      goto out;
+	    }
+
+	  sin.sin_port = ntohs (sin.sin_port);
+	  debug_printf ("AF_UNIX: socket bound to port %u", sin.sin_port);
+
+	  res = -1;
+	  fd = _open (my_addr->sa_data, O_WRONLY | O_CREAT | O_BINARY, 0);
+	  if (fd >= 0)
+	    {
+	      char buf[sizeof (SOCKET_COOKIE) + 10];
+
+	      __small_sprintf (buf, "%s%u", SOCKET_COOKIE, sin.sin_port);
+	      int len = strlen (buf) + 1;
+
+	      /* Note that the terminating nul is written.  */
+	      if (_write (fd, buf, len) != len)
+		{
+		  int saved_errno = get_errno ();
+		  _close (fd);
+		  _unlink (my_addr->sa_data);
+		  set_errno (saved_errno);
+		}
+	      else
+		{
+		  _close (fd);
+		  chmod (my_addr->sa_data,
+		    (S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO) & ~myself->umask);
+		  res = 0;
+		}
+	    }
+	}
+      else
+	{
+	  res = bind (sock->get_socket (), my_addr, addrlen);
+	  if (res)
+	    set_winsock_errno ();
+	}
     }
+out:
   out ("bind");
   syscall_printf ("%d = bind (%d, %x, %d)", res, fd, my_addr, addrlen);
   return res;
diff -uprN /winsup/path.cc winsup/path.cc
--- /winsup/path.cc	Thu Jul 15 06:49:24 1999
+++ winsup/path.cc	Tue Jul 27 05:51:01 1999
@@ -2168,6 +2168,13 @@ symlink_check_one (const char *in_path, 
 		    res = got;
 		}
 	    }
+	  else if (got == sizeof (cookie_buf)
+		   && memcmp (cookie_buf, SOCKET_COOKIE,
+			      sizeof (cookie_buf)) == 0)
+	    {
+	      res = 0;
+	      *pflags |= PATH_SOCKET;
+	    }
 	  else if (*pflags & PATH_EXEC)
 	    goto close_and_return;
 	  else if (!(*pflags & PATH_EXEC))
diff -uprN /winsup/path.h winsup/path.h
--- /winsup/path.h	Fri Jul 09 06:43:08 1999
+++ winsup/path.h	Tue Jul 27 05:45:16 1999
@@ -30,6 +30,7 @@ enum
   PATH_SYMLINK = 1,
   PATH_BINARY = MOUNT_BINARY,
   PATH_EXEC = MOUNT_EXEC,
+  PATH_SOCKET =  0x40000000,
   PATH_HASACLS = 0x80000000
 };
 
@@ -45,6 +46,7 @@ class path_conv
   int hasgood_inode () {return path_flags & PATH_HASACLS;}  // Not strictly correct
   int isbinary () {return path_flags & PATH_BINARY;}
   int issymlink () {return path_flags & PATH_SYMLINK;}
+  int issocket () {return path_flags & PATH_SOCKET;}
   int isexec () {return path_flags & PATH_EXEC;}
 
   void set_binary () {path_flags |= PATH_BINARY;}
@@ -71,6 +73,9 @@ class path_conv
 
 /* Symlink marker */
 #define SYMLINK_COOKIE "!<symlink>"
+
+/* Socket marker */
+#define SOCKET_COOKIE  "!<socket >"
 
 /* Maximum depth of symlinks (after which ELOOP is issued).  */
 #define MAX_LINK_DEPTH 10
diff -uprN /winsup/syscalls.cc winsup/syscalls.cc
--- /winsup/syscalls.cc	Thu Jul 08 08:13:31 1999
+++ winsup/syscalls.cc	Thu Jul 29 16:27:51 1999
@@ -714,7 +714,7 @@ chmod (const char *path, mode_t mode)
 	{
 	  now |= FILE_ATTRIBUTE_READONLY;
 	}
-      if (S_ISLNK (mode))
+      if (S_ISLNK (mode) || S_ISSOCK (mode))
 	{
 	  now |= FILE_ATTRIBUTE_SYSTEM;
 	}
