[newlib-cygwin] Cygwin: AF_UNIX: Implement read, readv, recvfrom, write, writev, sendto

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=5bb4cc1e6cfba2d3246bd72c419e89c54b15ad56

commit 5bb4cc1e6cfba2d3246bd72c419e89c54b15ad56
Author: Corinna Vinschen 
Date:   Wed Mar 7 21:53:56 2018 +0100

Cygwin: AF_UNIX: Implement read, readv, recvfrom, write, writev, sendto

All of these functions just call recvfrom/sendmsg which are still TODO

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler_socket_unix.cc | 108 +++---
 1 file changed, 88 insertions(+), 20 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index 6eca668..d27cdad 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -1545,18 +1545,33 @@ fhandler_socket_unix::getpeereid (pid_t *pid, uid_t 
*euid, gid_t *egid)
 }
 
 ssize_t
-fhandler_socket_unix::recvfrom (void *ptr, size_t len, int flags,
-   struct sockaddr *from, int *fromlen)
+fhandler_socket_unix::recvmsg (struct msghdr *msg, int flags)
 {
   set_errno (EAFNOSUPPORT);
   return -1;
 }
 
 ssize_t
-fhandler_socket_unix::recvmsg (struct msghdr *msg, int flags)
+fhandler_socket_unix::recvfrom (void *ptr, size_t len, int flags,
+   struct sockaddr *from, int *fromlen)
 {
-  set_errno (EAFNOSUPPORT);
-  return -1;
+  struct iovec iov;
+  struct msghdr msg;
+  ssize_t ret;
+
+  iov.iov_base = ptr;
+  iov.iov_len = len;
+  msg.msg_name = from;
+  msg.msg_namelen = from && fromlen ? *fromlen : 0;
+  msg.msg_iov = 
+  msg.msg_iovlen = 1;
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+  msg.msg_flags = 0;
+  ret = recvmsg (, flags);
+  if (ret >= 0 && from && fromlen)
+*fromlen = msg.msg_namelen;
+  return ret;
 }
 
 void __reg3
@@ -1564,42 +1579,95 @@ fhandler_socket_unix::read (void *ptr, size_t& len)
 {
   set_errno (EAFNOSUPPORT);
   len = 0;
+  struct iovec iov;
+  struct msghdr msg;
+
+  iov.iov_base = ptr;
+  iov.iov_len = len;
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_iov = 
+  msg.msg_iovlen = 1;
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+  msg.msg_flags = 0;
+  len = recvmsg (, 0);
 }
 
 ssize_t __stdcall
-fhandler_socket_unix::readv (const struct iovec *, int iovcnt, ssize_t tot)
-{
-  set_errno (EAFNOSUPPORT);
-  return -1;
+fhandler_socket_unix::readv (const struct iovec *const iov, int iovcnt,
+ssize_t tot)
+{
+  struct msghdr msg;
+
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_iov = (struct iovec *) iov;
+  msg.msg_iovlen = iovcnt;
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+  msg.msg_flags = 0;
+  return recvmsg (, 0);
 }
 
 ssize_t
-fhandler_socket_unix::sendto (const void *in_ptr, size_t len, int flags,
-  const struct sockaddr *to, int tolen)
+fhandler_socket_unix::sendmsg (const struct msghdr *msg, int flags)
 {
   set_errno (EAFNOSUPPORT);
   return -1;
 }
 
 ssize_t
-fhandler_socket_unix::sendmsg (const struct msghdr *msg, int flags)
+fhandler_socket_unix::sendto (const void *in_ptr, size_t len, int flags,
+  const struct sockaddr *to, int tolen)
 {
-  set_errno (EAFNOSUPPORT);
-  return -1;
+  struct iovec iov;
+  struct msghdr msg;
+
+  iov.iov_base = (void *) in_ptr;
+  iov.iov_len = len;
+  msg.msg_name = (void *) to;
+  msg.msg_namelen = to ? tolen : 0;
+  msg.msg_iov = 
+  msg.msg_iovlen = 1;
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+  msg.msg_flags = 0;
+  return sendmsg (, flags);
 }
 
 ssize_t __stdcall
 fhandler_socket_unix::write (const void *ptr, size_t len)
 {
-  set_errno (EAFNOSUPPORT);
-  return -1;
+  struct iovec iov;
+  struct msghdr msg;
+
+  iov.iov_base = (void *) ptr;
+  iov.iov_len = len;
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_iov = 
+  msg.msg_iovlen = 1;
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+  msg.msg_flags = 0;
+  return sendmsg (, 0);
 }
 
 ssize_t __stdcall
-fhandler_socket_unix::writev (const struct iovec *, int iovcnt, ssize_t tot)
-{
-  set_errno (EAFNOSUPPORT);
-  return -1;
+fhandler_socket_unix::writev (const struct iovec *const iov, int iovcnt,
+ ssize_t tot)
+{
+  struct msghdr msg;
+
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_iov = (struct iovec *) iov;
+  msg.msg_iovlen = iovcnt;
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+  msg.msg_flags = 0;
+  return sendmsg (, 0);
 }
 
 int


[newlib-cygwin] Cygwin: AF_UNIX: define AF_UNIX_CONNECT_TIMEOUT

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=483cbf89549545051717d3afabadf31c9c70c2f5

commit 483cbf89549545051717d3afabadf31c9c70c2f5
Author: Corinna Vinschen 
Date:   Wed Mar 7 21:55:34 2018 +0100

Cygwin: AF_UNIX: define AF_UNIX_CONNECT_TIMEOUT

Use macro AF_UNIX_CONNECT_TIMEOUT instead of numerical constant
for connect timeout.

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler_socket_unix.cc | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index d27cdad..afd57fc 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -154,6 +154,9 @@ GUID __cygwin_socket_guid = {
   _s == STATUS_BUFFER_OVERFLOW \
   || _s == STATUS_MORE_PROCESSING_REQUIRED; })
 
+/* Default timeout value of connect: 20 secs, as on Linux. */
+#define AF_UNIX_CONNECT_TIMEOUT (-20 * NS100PERSEC)
+
 sun_name_t::sun_name_t ()
 {
   un_len = sizeof (sa_family_t);
@@ -619,7 +622,7 @@ fhandler_socket_unix::recv_peer_name ()
   DWORD ret;
   LARGE_INTEGER timeout;
 
-  timeout.QuadPart = -20 * NS100PERSEC;/* 20 secs */
+  timeout.QuadPart = AF_UNIX_CONNECT_TIMEOUT;
   ret = cygwait (evt, , cw_sig_eintr);
   switch (ret)
{
@@ -1062,7 +1065,7 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING 
pipe_name)
 goto out;
   pwbuf_size = offsetof (FILE_PIPE_WAIT_FOR_BUFFER, Name) + pipe_name->Length;
   pwbuf = (PFILE_PIPE_WAIT_FOR_BUFFER) alloca (pwbuf_size);
-  pwbuf->Timeout.QuadPart = -20 * NS100PERSEC; /* 20 secs */
+  pwbuf->Timeout.QuadPart = AF_UNIX_CONNECT_TIMEOUT;
   pwbuf->NameLength = pipe_name->Length;
   pwbuf->TimeoutSpecified = TRUE;
   memcpy (pwbuf->Name, pipe_name->Buffer, pipe_name->Length);


[newlib-cygwin] Cygwin: Define FSCTL_PIPE_FLUSH

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=2f48ddb1ca45055eaeaa61af766653251b575a72

commit 2f48ddb1ca45055eaeaa61af766653251b575a72
Author: Corinna Vinschen 
Date:   Wed Mar 7 21:54:46 2018 +0100

Cygwin: Define FSCTL_PIPE_FLUSH

This fsctl might come in handy at one point...

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/ntdll.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index b251055..64babef 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -157,6 +157,7 @@ extern GUID __cygwin_socket_guid;
 #define FILE_VC_VALID_MASK  0x03ff
 
 /* IOCTL code to impersonate client of named pipe. */
+
 #define FSCTL_PIPE_DISCONNECT  CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, \
 METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define FSCTL_PIPE_LISTEN  CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2, \
@@ -165,6 +166,8 @@ extern GUID __cygwin_socket_guid;
 METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define FSCTL_PIPE_IMPERSONATE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, \
 METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_PIPE_FLUSH   CTL_CODE(FILE_DEVICE_NAMED_PIPE, 16, \
+METHOD_BUFFERED, FILE_WRITE_DATA)
 
 typedef enum _FILE_INFORMATION_CLASS
 {


[newlib-cygwin] Cygwin: reorder read/write calls in fhandler_socket_unix

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=d7f7d292d83e2a3cd41d8da66d5abe0951b331b0

commit d7f7d292d83e2a3cd41d8da66d5abe0951b331b0
Author: Corinna Vinschen 
Date:   Wed Mar 7 21:52:29 2018 +0100

Cygwin: reorder read/write calls in fhandler_socket_unix

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler.h | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 13f4068..7d45aa0 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -922,18 +922,19 @@ class fhandler_socket_unix : public fhandler_socket
   int shutdown (int how);
   int close ();
   int getpeereid (pid_t *pid, uid_t *euid, gid_t *egid);
+  ssize_t recvmsg (struct msghdr *msg, int flags);
   ssize_t recvfrom (void *ptr, size_t len, int flags,
struct sockaddr *from, int *fromlen);
-  ssize_t recvmsg (struct msghdr *msg, int flags);
   void __reg3 read (void *ptr, size_t& len);
-  ssize_t __stdcall readv (const struct iovec *, int iovcnt,
+  ssize_t __stdcall readv (const struct iovec *const iov, int iovcnt,
   ssize_t tot = -1);
 
+  ssize_t sendmsg (const struct msghdr *msg, int flags);
   ssize_t sendto (const void *ptr, size_t len, int flags,
  const struct sockaddr *to, int tolen);
-  ssize_t sendmsg (const struct msghdr *msg, int flags);
   ssize_t __stdcall write (const void *ptr, size_t len);
-  ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = 
-1);
+  ssize_t __stdcall writev (const struct iovec *const iov, int iovcnt,
+   ssize_t tot = -1);
   int setsockopt (int level, int optname, const void *optval,
  __socklen_t optlen);
   int getsockopt (int level, int optname, const void *optval,


[newlib-cygwin] Cygwin: AF_UNIX: implement getsockopt SO_RCVBUF/SO_SNDBUF

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=7d525c171f79243de864d7a736d1cf85209b62db

commit 7d525c171f79243de864d7a736d1cf85209b62db
Author: Corinna Vinschen 
Date:   Wed Mar 7 21:56:42 2018 +0100

Cygwin: AF_UNIX: implement getsockopt SO_RCVBUF/SO_SNDBUF

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler_socket_unix.cc | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index afd57fc..388fbdf 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -1780,6 +1780,16 @@ fhandler_socket_unix::getsockopt (int level, int 
optname, const void *optval,
break;
  }
 
+   case SO_RCVBUF:
+   case SO_SNDBUF:
+ if (*optlen < (socklen_t) sizeof (int))
+   {
+ set_errno (EINVAL);
+ return -1;
+   }
+ *(int *) optval = (optname == SO_RCVBUF) ? rmem () : wmem ();
+ break;
+
case SO_RCVTIMEO:
case SO_SNDTIMEO:
  {


[newlib-cygwin] describe new locale modifier @cjkwide for user guide

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=e4c65b2e918107287845ab345bc0607bde0323f7

commit e4c65b2e918107287845ab345bc0607bde0323f7
Author: Thomas Wolff 
Date:   Thu Mar 8 00:29:25 2018 +0100

describe new locale modifier @cjkwide for user guide

Diff:
---
 winsup/doc/setup-locale.xml | 13 +
 1 file changed, 13 insertions(+)

diff --git a/winsup/doc/setup-locale.xml b/winsup/doc/setup-locale.xml
index 29502a2..4872ae2 100644
--- a/winsup/doc/setup-locale.xml
+++ b/winsup/doc/setup-locale.xml
@@ -166,6 +166,19 @@ can be used to force wcwidth/wcswidth to return 1 for the 
ambiguous width
 characters.
 
 
+
+For the same class of "CJK Ambiguous Width" characters, it may be
+desirable to handle them as double-width even when a non-CJK language
+setting is selected.  This supports e.g. certain graphic symbols used
+by "Powerline" and provided by "Powerline fonts".  Some terminals have
+options to enforce this width handling (xterm -cjk_width,
+mintty -o Charwidth=ambig-wide, putty configuration) but that alone
+makes character rendering and locale information inconsistent for those
+characters.  The locale modifier "@cjkwide" supports consistent locale
+response with this option; it forces wcwidth/wcswidth to return 2 for the
+ambiguous width characters.
+
+
 
 
 


[newlib-cygwin] Cygwin: AF_UNIX: fix SEGV when sending an empty socket name from connect

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=4de52a0fe1009d2a5318a731400dbf4280b184cc

commit 4de52a0fe1009d2a5318a731400dbf4280b184cc
Author: Corinna Vinschen 
Date:   Wed Mar 7 16:08:15 2018 +0100

Cygwin: AF_UNIX: fix SEGV when sending an empty socket name from connect

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler_socket_unix.cc | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index f320453..27ac958 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -540,15 +540,18 @@ fhandler_socket_unix::set_pipe_non_blocking (bool 
nonblocking)
 int
 fhandler_socket_unix::send_my_name ()
 {
+  sun_name_t *sun;
   size_t name_len = 0;
   af_unix_pkt_hdr_t *packet;
   NTSTATUS status;
   IO_STATUS_BLOCK io;
 
   AcquireSRWLockShared (_lock);
-  name_len = get_sun_path ()->un_len;
+  sun = get_sun_path ();
+  name_len = sun ? sun->un_len : 0;
   packet = (af_unix_pkt_hdr_t *) alloca (sizeof *packet + name_len);
-  memcpy (AF_UNIX_PKT_NAME (packet), _sun_path ()->un, name_len);
+  if (sun)
+memcpy (AF_UNIX_PKT_NAME (packet), >un, name_len);
   ReleaseSRWLockShared (_lock);
 
   packet->init (0, name_len, 0, 0);


[newlib-cygwin] Cygwin: AF_UNIX: fix creation of npfs handle

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=2f2a75b7bbf521057f3e8e502f1a6641a2baf376

commit 2f2a75b7bbf521057f3e8e502f1a6641a2baf376
Author: Corinna Vinschen 
Date:   Wed Mar 7 15:48:21 2018 +0100

Cygwin: AF_UNIX: fix creation of npfs handle

The handle to the device is never needed.  As the name impies,
FSCTL_PIPE_WAIT works on the file system, not on the device level.

Drop opening the device and make sure to open only one handle to NPFS.

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler.h  |  8 +---
 winsup/cygwin/fhandler_socket_unix.cc | 37 ---
 winsup/cygwin/globals.cc  |  3 +--
 3 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 392ba6c..4166126 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -852,12 +852,6 @@ class sun_name_t
 
 class fhandler_socket_unix : public fhandler_socket
 {
-   enum npfs_hdl_t
-   {
- NPFS_DEVICE,
- NPFS_DIR
-   };
-
  protected:
   SRWLOCK conn_lock;
   SRWLOCK bind_lock;
@@ -886,7 +880,7 @@ class fhandler_socket_unix : public fhandler_socket
   void set_pipe_non_blocking (bool nonblocking);
   int send_my_name ();
   int recv_peer_name ();
-  static NTSTATUS npfs_handle (HANDLE , npfs_hdl_t type);
+  static NTSTATUS npfs_handle (HANDLE );
   HANDLE create_pipe ();
   HANDLE create_pipe_instance ();
   NTSTATUS open_pipe (HANDLE , PUNICODE_STRING pipe_name);
diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index ea8aece..f320453 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -620,28 +620,33 @@ fhandler_socket_unix::recv_peer_name ()
 }
 
 NTSTATUS
-fhandler_socket_unix::npfs_handle (HANDLE , npfs_hdl_t type)
+fhandler_socket_unix::npfs_handle (HANDLE )
 {
-  static NO_COPY HANDLE npfs_devh;
+  static NO_COPY SRWLOCK npfs_lock;
   static NO_COPY HANDLE npfs_dirh;
 
-  HANDLE _ref = (type == NPFS_DEVICE) ? npfs_devh : npfs_dirh;
-  PUNICODE_STRING path = (type == NPFS_DEVICE) ? _u_npfs : _u_npfs_dir;
-  NTSTATUS status;
+  NTSTATUS status = STATUS_SUCCESS;
   OBJECT_ATTRIBUTES attr;
   IO_STATUS_BLOCK io;
 
-  if (!npfs_ref)
+  /* Lockless after first call. */
+  if (npfs_dirh)
+{
+  nph = npfs_dirh;
+  return STATUS_SUCCESS;
+}
+  AcquireSRWLockExclusive (_lock);
+  if (!npfs_dirh)
 {
-  InitializeObjectAttributes (, path, 0, NULL, NULL);
-  status = NtOpenFile (_ref, FILE_READ_ATTRIBUTES | SYNCHRONIZE,
+  InitializeObjectAttributes (, _u_npfs, 0, NULL, NULL);
+  status = NtOpenFile (_dirh, FILE_READ_ATTRIBUTES | SYNCHRONIZE,
   , , FILE_SHARE_READ | FILE_SHARE_WRITE,
   FILE_SYNCHRONOUS_IO_NONALERT);
-  if (!NT_SUCCESS (status))
-   return status;
 }
-  nph = npfs_ref;
-  return STATUS_SUCCESS;
+  ReleaseSRWLockExclusive (_lock);
+  if (NT_SUCCESS (status))
+nph = npfs_dirh;
+  return status;
 }
 
 HANDLE
@@ -658,7 +663,7 @@ fhandler_socket_unix::create_pipe ()
   ULONG max_instances;
   LARGE_INTEGER timeout;
 
-  status = npfs_handle (npfsh, NPFS_DIR);
+  status = npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
 {
   __seterrno_from_nt_status (status);
@@ -700,7 +705,7 @@ fhandler_socket_unix::create_pipe_instance ()
   ULONG max_instances;
   LARGE_INTEGER timeout;
 
-  status = npfs_handle (npfsh, NPFS_DIR);
+  status = npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
 {
   __seterrno_from_nt_status (status);
@@ -738,7 +743,7 @@ fhandler_socket_unix::open_pipe (HANDLE , 
PUNICODE_STRING pipe_name)
   IO_STATUS_BLOCK io;
   ULONG sharing;
 
-  status = npfs_handle (npfsh, NPFS_DIR);
+  status = npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
 return status;
   access = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE;
@@ -996,7 +1001,7 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING 
pipe_name)
   LONGLONG stamp;
   HANDLE ph = NULL;
 
-  status = npfs_handle (npfsh, NPFS_DEVICE);
+  status = npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
 {
   error = geterrno_from_nt_status (status);
diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
index 9dac030..7c84eb6 100644
--- a/winsup/cygwin/globals.cc
+++ b/winsup/cygwin/globals.cc
@@ -149,8 +149,7 @@ const int __collate_load_error = 0;
   extern UNICODE_STRING _RDATA ro_u_natdir = _ROU (L"Directory");
   extern UNICODE_STRING _RDATA ro_u_natsyml = _ROU (L"SymbolicLink");
   extern UNICODE_STRING _RDATA ro_u_natdev = _ROU (L"Device");
-  extern UNICODE_STRING _RDATA ro_u_npfs = _ROU (L"\\Device\\NamedPipe");
-  extern UNICODE_STRING _RDATA ro_u_npfs_dir = _ROU (L"\\Device\\NamedPipe\\");
+  extern UNICODE_STRING _RDATA ro_u_npfs = _ROU (L"\\Device\\NamedPipe\\");
   #undef _ROU
 
   /* This is an exported copy 

[newlib-cygwin] Cygwin: AF_UNIX: Add create_event helper and use throughout

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=d69bcdd671539caea906f18e327dfd2eb9f1da85

commit d69bcdd671539caea906f18e327dfd2eb9f1da85
Author: Corinna Vinschen 
Date:   Wed Mar 7 16:00:36 2018 +0100

Cygwin: AF_UNIX:  Add create_event helper and use throughout

Minimize overhead in creating a nameless event object.

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler_socket_unix.cc | 40 ++-
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index d5f617d..ea8aece 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -148,6 +148,24 @@ sun_name_t::sun_name_t (const struct sockaddr *name, 
socklen_t namelen)
   _nul[sizeof (struct sockaddr_un)] = '\0';
 }
 
+static HANDLE
+create_event ()
+{
+  NTSTATUS status;
+  OBJECT_ATTRIBUTES attr;
+  HANDLE evt = NULL;
+
+  InitializeObjectAttributes (, NULL, 0, NULL, NULL);
+  status = NtCreateEvent (, EVENT_ALL_ACCESS, ,
+ NotificationEvent, FALSE);
+  if (!NT_SUCCESS (status))
+__seterrno_from_nt_status (status);
+  return evt;
+}
+
+/* Character length of pipe name, excluding trailing NUL. */
+#define CYGWIN_PIPE_SOCKET_NAME_LEN 47
+
 /* Character position encoding the socket type in a pipe name. */
 #define CYGWIN_PIPE_SOCKET_TYPE_POS29
 
@@ -555,6 +573,7 @@ fhandler_socket_unix::send_my_name ()
 int
 fhandler_socket_unix::recv_peer_name ()
 {
+  HANDLE evt;
   NTSTATUS status;
   IO_STATUS_BLOCK io;
   af_unix_pkt_hdr_t *packet;
@@ -562,10 +581,12 @@ fhandler_socket_unix::recv_peer_name ()
   ULONG len;
   int ret = 0;
 
+  if (!(evt = create_event ()))
+return ENOBUFS;
   len = sizeof *packet + sizeof *un;
   packet = (af_unix_pkt_hdr_t *) alloca (len);
   set_pipe_non_blocking (false);
-  status = NtReadFile (get_handle (), NULL, NULL, NULL, , packet, len,
+  status = NtReadFile (get_handle (), evt, NULL, NULL, , packet, len,
   NULL, NULL);
   if (status == STATUS_PENDING)
 {
@@ -573,7 +594,7 @@ fhandler_socket_unix::recv_peer_name ()
   LARGE_INTEGER timeout;
 
   timeout.QuadPart = -20 * NS100PERSEC;/* 20 secs */
-  ret = cygwait (connect_wait_thr, , cw_sig_eintr);
+  ret = cygwait (evt, , cw_sig_eintr);
   switch (ret)
{
case WAIT_OBJECT_0:
@@ -835,22 +856,11 @@ fhandler_socket_unix::listen_pipe ()
 {
   NTSTATUS status;
   IO_STATUS_BLOCK io;
-  OBJECT_ATTRIBUTES attr;
   HANDLE evt = NULL;
 
   io.Status = STATUS_PENDING;
-  if (!is_nonblocking ())
-{
-  /* Create event object and set APC context pointer. */
-  InitializeObjectAttributes (, NULL, 0, NULL, NULL);
-  status = NtCreateEvent (, EVENT_ALL_ACCESS, ,
- NotificationEvent, FALSE);
-  if (!NT_SUCCESS (status))
-   {
- __seterrno_from_nt_status (status);
- return -1;
-   }
-}
+  if (!is_nonblocking () && !(evt = create_event ()))
+return -1;
   status = NtFsControlFile (get_handle (), evt, NULL, NULL, ,
FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0);
   if (status == STATUS_PENDING)


[newlib-cygwin] Cygwin: AF_UNIX: make sure connect wait thread is cleanly interruptible

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=cde2648c2250eb373d1e245160e2aca26dc0555c

commit cde2648c2250eb373d1e245160e2aca26dc0555c
Author: Corinna Vinschen 
Date:   Wed Mar 7 16:19:32 2018 +0100

Cygwin: AF_UNIX: make sure connect wait thread is cleanly interruptible

Using TerminateThread potentially leaks resources.  In our case,
the connect wait thread may be forcefully terminated after
having successfully opened a client side pipe handle.  If this
occurs, we have a stale pipe server instance, so the pipe will
never be closed as long as the process lives.

Avoid this by changing the npfs handle to non-blocking, so we can
wait on a termination event object from inside the thread itself
and cleanly exit from the thread instead of terminating.

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler.h  |  1 +
 winsup/cygwin/fhandler_socket_unix.cc | 56 ++-
 2 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 4166126..13f4068 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -860,6 +860,7 @@ class fhandler_socket_unix : public fhandler_socket
   if the socket is backed by a file in the
   file system (actually a reparse point) */
   HANDLE connect_wait_thr;
+  HANDLE cwt_termination_evt;
   PVOID cwt_param;
   LONG so_error;
   sun_name_t *sun_path;
diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index 099000d..dcd4938 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -667,7 +667,7 @@ fhandler_socket_unix::npfs_handle (HANDLE )
   InitializeObjectAttributes (, _u_npfs, 0, NULL, NULL);
   status = NtOpenFile (_dirh, FILE_READ_ATTRIBUTES | SYNCHRONIZE,
   , , FILE_SHARE_READ | FILE_SHARE_WRITE,
-  FILE_SYNCHRONOUS_IO_NONALERT);
+  0);
 }
   ReleaseSRWLockExclusive (_lock);
   if (NT_SUCCESS (status))
@@ -808,7 +808,11 @@ fhandler_socket_unix::wait_pipe (PUNICODE_STRING pipe_name)
   conn_wait_info_t *wait_info;
   DWORD waitret, err;
   int ret = -1;
+  HANDLE thr, evt;
+  PVOID param;
 
+  if (!(cwt_termination_evt = create_event ()))
+  return -1;
   wait_info = (conn_wait_info_t *)
  cmalloc_abort (HEAP_FHANDLER, sizeof *wait_info);
   wait_info->fh = this;
@@ -823,23 +827,28 @@ fhandler_socket_unix::wait_pipe (PUNICODE_STRING 
pipe_name)
 {
   cfree (wait_info);
   __seterrno ();
-  return -1;
+  goto out;
 }
   if (is_nonblocking ())
 {
   set_errno (EINPROGRESS);
-  return -1;
+  goto out;
 }
 
   waitret = cygwait (connect_wait_thr, cw_infinite, cw_cancel | cw_sig_eintr);
   if (waitret == WAIT_OBJECT_0)
 GetExitCodeThread (connect_wait_thr, );
   else
-TerminateThread (connect_wait_thr, 0);
-  HANDLE thr = InterlockedExchangePointer (_wait_thr, NULL);
+{
+  SetEvent (cwt_termination_evt);
+  WaitForSingleObject (connect_wait_thr, INFINITE);
+  GetExitCodeThread (connect_wait_thr, );
+  waitret = WAIT_SIGNALED;
+}
+  thr = InterlockedExchangePointer (_wait_thr, NULL);
   if (thr)
 CloseHandle (thr);
-  PVOID param = InterlockedExchangePointer (_param, NULL);
+  param = InterlockedExchangePointer (_param, NULL);
   if (param)
 cfree (param);
   switch (waitret)
@@ -858,6 +867,10 @@ fhandler_socket_unix::wait_pipe (PUNICODE_STRING pipe_name)
ret = 0;
   break;
 }
+out:
+  evt = InterlockedExchangePointer (_termination_evt, NULL);
+  if (evt)
+NtClose (evt);
   return ret;
 }
 
@@ -965,6 +978,7 @@ fhandler_socket_unix::fixup_after_fork (HANDLE parent)
   InitializeSRWLock (_lock);
   InitializeSRWLock (_lock);
   connect_wait_thr = NULL;
+  cwt_termination_evt = NULL;
   cwt_param = NULL;
 }
 
@@ -1001,6 +1015,7 @@ fhandler_socket_unix::dup (fhandler_base *child, int 
flags)
   InitializeSRWLock (>bind_lock);
   InitializeSRWLock (>io_lock);
   fhs->connect_wait_thr = NULL;
+  fhs->cwt_termination_evt = NULL;
   fhs->cwt_param = NULL;
   return fhandler_socket::dup (child, flags);
 }
@@ -1019,6 +1034,7 @@ DWORD
 fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING pipe_name)
 {
   HANDLE npfsh;
+  HANDLE evt;
   LONG error = 0;
   NTSTATUS status;
   IO_STATUS_BLOCK io;
@@ -1033,6 +1049,8 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING 
pipe_name)
   error = geterrno_from_nt_status (status);
   goto out;
 }
+  if (!(evt = create_event ()))
+goto out;
   pwbuf_size = offsetof (FILE_PIPE_WAIT_FOR_BUFFER, Name) + pipe_name->Length;
   pwbuf = (PFILE_PIPE_WAIT_FOR_BUFFER) alloca (pwbuf_size);
   pwbuf->Timeout.QuadPart = -20 * NS100PERSEC; /* 20 secs */
@@ -1042,8 

[newlib-cygwin] Cygwin: AF_UNIX: fix accept behaviour

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=855e5d7e144ac1e302087cf08c37eec13c62f75a

commit 855e5d7e144ac1e302087cf08c37eec13c62f75a
Author: Corinna Vinschen 
Date:   Wed Mar 7 16:23:44 2018 +0100

Cygwin: AF_UNIX: fix accept behaviour

* Use correct cygwait/WFSO invocation to not die on cancel and signals
  uncontrolled.
* Manage io handles under io_lock.
* Copy peer address to user space under SEH to avoid a resource leak.

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler_socket_unix.cc | 52 +--
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index dcd4938..6eca668 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -901,6 +901,7 @@ fhandler_socket_unix::listen_pipe ()
   NTSTATUS status;
   IO_STATUS_BLOCK io;
   HANDLE evt = NULL;
+  DWORD waitret = WAIT_OBJECT_0;
 
   io.Status = STATUS_PENDING;
   if (!is_nonblocking () && !(evt = create_event ()))
@@ -909,12 +910,18 @@ fhandler_socket_unix::listen_pipe ()
FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0);
   if (status == STATUS_PENDING)
 {
-  if (cygwait (evt ?: get_handle ()) == WAIT_OBJECT_0)
+  waitret = cygwait (evt ?: get_handle (), cw_infinite,
+cw_cancel | cw_sig_eintr);
+  if (waitret == WAIT_OBJECT_0)
status = io.Status;
 }
   if (evt)
 NtClose (evt);
-  if (status == STATUS_PIPE_LISTENING)
+  if (waitret == WAIT_CANCELED)
+pthread::static_cancel_self ();
+  else if (waitret == WAIT_SIGNALED)
+set_errno (EINTR);
+  else if (status == STATUS_PIPE_LISTENING)
 set_errno (EAGAIN);
   else if (status != STATUS_PIPE_CONNECTED)
 __seterrno_from_nt_status (status);
@@ -929,7 +936,9 @@ fhandler_socket_unix::disconnect_pipe (HANDLE ph)
 
   status = NtFsControlFile (ph, NULL, NULL, NULL, , FSCTL_PIPE_DISCONNECT,
NULL, 0, NULL, 0);
-  if (status == STATUS_PENDING && cygwait (ph) == WAIT_OBJECT_0)
+  /* Short-lived.  Don't use cygwait.  We don't want to be interrupted. */
+  if (status == STATUS_PENDING
+  && WaitForSingleObject (ph, INFINITE) == WAIT_OBJECT_0)
 status = io.Status;
   if (!NT_SUCCESS (status))
 {
@@ -1290,13 +1299,17 @@ fhandler_socket_unix::accept4 (struct sockaddr *peer, 
int *len, int flags)
   /* Our handle is now connected with a client.  This handle is used
  for the accepted socket.  Our handle has to be replaced with a
 new instance handle for the next accept. */
+  AcquireSRWLockExclusive (_lock);
   HANDLE accepted = get_handle ();
   HANDLE new_inst = create_pipe_instance ();
   int error = ENOBUFS;
-  if (new_inst)
+  if (!new_inst)
+   ReleaseSRWLockExclusive (_lock);
+  else
{
  /* Set new io handle. */
  set_io_handle (new_inst);
+ ReleaseSRWLockExclusive (_lock);
  /* Prepare new file descriptor. */
  cygheap_fdnew fd;
 
@@ -1323,21 +1336,30 @@ fhandler_socket_unix::accept4 (struct sockaddr *peer, 
int *len, int flags)
  error = sock->recv_peer_name ();
  if (error == 0)
{
- if (peer)
+ __try
{
- sun_name_t *sun = sock->get_peer_sun_path ();
- if (sun)
+ if (peer)
{
- memcpy (peer, >un, MIN (*len, sun->un_len));
- *len = sun->un_len;
+ sun_name_t *sun = sock->get_peer_sun_path ();
+ if (sun)
+   {
+ memcpy (peer, >un,
+ MIN (*len, sun->un_len));
+ *len = sun->un_len;
+   }
+ else if (len)
+   *len = 0;
}
- else if (len)
-   *len = 0;
+ fd = sock;
+ if (fd <= 2)
+   set_std_handle (fd);
+ return fd;
+   }
+ __except (NO_ERROR)
+   {
+ error = EFAULT;
}
- fd = sock;
- if (fd <= 2)
-   set_std_handle (fd);
- return fd;
+ __endtry
}
  delete sock;
}


[newlib-cygwin] Cygwin: AF_UNIX: fix comments and move a macro

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=e94fa4ebf39384446f89a44b3769756fb51cb4f9

commit e94fa4ebf39384446f89a44b3769756fb51cb4f9
Author: Corinna Vinschen 
Date:   Wed Mar 7 15:43:26 2018 +0100

Cygwin: AF_UNIX: fix comments and move a macro

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler_socket_unix.cc | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index ae422dd..d5f617d 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -67,12 +67,12 @@
for the entire packet, as well as for all three data blocks.  The
combined maximum size of a packet is 64K, including the header.
 
-   A connecting, bound STREAM socket send it's local sun_path once after
+   A connecting, bound STREAM socket sends it's local sun_path once after
a successful connect.  An already connected socket also sends its local
sun_path after a successful bind (border case, but still...).  These
packages don't contain any other data (cmsg_len == 0, data_len == 0).
 
-   A bound DGRAM socket send its sun_path with each sendmsg/sendto.
+   A bound DGRAM socket sends its sun_path with each sendmsg/sendto.
 */
 class af_unix_pkt_hdr_t
 {
@@ -124,9 +124,6 @@ class af_unix_pkt_hdr_t
   (void *)(((PBYTE)(_p)) + AF_UNIX_PKT_OFFSETOF_DATA (_p)); \
})
 
-/* Character length of pipe name, excluding trailing NUL. */
-#define CYGWIN_PIPE_SOCKET_NAME_LEN 47
-
 GUID __cygwin_socket_guid = {
   .Data1 = 0xefc1714d,
   .Data2 = 0x7b19,
@@ -973,7 +970,7 @@ fhandler_socket_unix::dup (fhandler_base *child, int flags)
things to do:
 
- Set the peer pipe handle if successful
-   - Send own sun_path to peer if successful TODO
+   - Send own sun_path to peer if successful
- Set connect_state
- Set so_error for later call to select
 */


[newlib-cygwin] Cygwin: AF_UNIX: some pipe errors may have multiple status codes

2018-03-07 Thread Corinna Vinschen
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=27a63d4ef2d062d318330682e01f88b4a7298f97

commit 27a63d4ef2d062d318330682e01f88b4a7298f97
Author: Corinna Vinschen 
Date:   Wed Mar 7 16:12:55 2018 +0100

Cygwin: AF_UNIX: some pipe errors may have multiple status codes

Depending on the exact circumstances, some erros are indicated
by different status codes.  Add helper macros to handle them
together.

Signed-off-by: Corinna Vinschen 

Diff:
---
 winsup/cygwin/fhandler_socket_unix.cc | 29 ++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index 27ac958..099000d 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -131,6 +131,29 @@ GUID __cygwin_socket_guid = {
   .Data4 = { 0xba, 0xb3, 0xc5, 0xb1, 0xf9, 0x2c, 0xb8, 0x8c }
 };
 
+/* Some error conditions on pipes have multiple status codes, unfortunately. */
+#define STATUS_PIPE_NO_INSTANCE_AVAILABLE(status)  \
+   ({ NTSTATUS _s = (status); \
+  _s == STATUS_INSTANCE_NOT_AVAILABLE \
+  || _s == STATUS_PIPE_NOT_AVAILABLE \
+  || _s == STATUS_PIPE_BUSY; })
+
+#define STATUS_PIPE_IS_CLOSING(status) \
+   ({ NTSTATUS _s = (status); \
+  _s == STATUS_PIPE_CLOSING \
+  || _s == STATUS_PIPE_EMPTY; })
+
+#define STATUS_PIPE_INVALID(status) \
+   ({ NTSTATUS _s = (status); \
+  _s == STATUS_INVALID_INFO_CLASS \
+  || _s == STATUS_INVALID_PIPE_STATE \
+  || _s == STATUS_INVALID_READ_MODE; })
+
+#define STATUS_PIPE_MORE_DATA(status) \
+   ({ NTSTATUS _s = (status); \
+  _s == STATUS_BUFFER_OVERFLOW \
+  || _s == STATUS_MORE_PROCESSING_REQUIRED; })
+
 sun_name_t::sun_name_t ()
 {
   un_len = sizeof (sa_family_t);
@@ -847,7 +870,7 @@ fhandler_socket_unix::connect_pipe (PUNICODE_STRING 
pipe_name)
   /* Try connecting first.  If it doesn't work, wait for the pipe
  to become available. */
   status = open_pipe (ph, pipe_name);
-  if (status == STATUS_PIPE_BUSY)
+  if (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status))
 return wait_pipe (pipe_name);
   if (!NT_SUCCESS (status))
 {
@@ -1026,7 +1049,7 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING 
pipe_name)
  case STATUS_SUCCESS:
{
  status = open_pipe (ph, pipe_name);
- if (status == STATUS_PIPE_BUSY)
+ if (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status))
{
  /* Another concurrent connect grabbed the pipe instance
 under our nose.  Fix the timeout value and go waiting
@@ -1057,7 +1080,7 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING 
pipe_name)
break;
}
 }
-  while (status == STATUS_PIPE_BUSY);
+  while (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status));
 out:
   PVOID param = InterlockedExchangePointer (_param, NULL);
   if (param)