aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-04-13 19:56:30 +0000
committerCorinna Vinschen <corinna@vinschen.de>2010-04-13 19:56:30 +0000
commit0ef4bb7c5003d6a841068725e089c233b6ed304e (patch)
tree85966243b4a48c29c7f5d79c3f380ceafab8f7a4
parent2bba259eb77d8f4150ca838a9c2f52ec56a1c931 (diff)
downloadnewlib-0ef4bb7c5003d6a841068725e089c233b6ed304e.zip
newlib-0ef4bb7c5003d6a841068725e089c233b6ed304e.tar.gz
newlib-0ef4bb7c5003d6a841068725e089c233b6ed304e.tar.bz2
* fhandler_socket.cc (get_inet_addr): Only test the file for being a
socket after opening it. Retry if opening failed with sharing violation. Explain why we do this. (fhandler_socket::bind): Create file with no sharing allowed.
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/fhandler_socket.cc46
2 files changed, 39 insertions, 14 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2e3321a..305660f 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,10 @@
+2010-04-13 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (get_inet_addr): Only test the file for being a
+ socket after opening it. Retry if opening failed with sharing
+ violation. Explain why we do this.
+ (fhandler_socket::bind): Create file with no sharing allowed.
+
2010-04-13 John Bowman <bowman@math.ualberta.ca>
* cygheap.cc (cwcsdup): Fix allocation size to accommodate sizeof WCHAR.
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 66ba3e9..82be0ca 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -38,6 +38,7 @@
#include "cygtls.h"
#include "cygwin/in6.h"
#include "ntdll.h"
+#include "miscfuncs.h"
#define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
#define EVENT_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE)
@@ -94,21 +95,33 @@ get_inet_addr (const struct sockaddr *in, int inlen,
set_errno (ENOENT);
return 0;
}
- if (!pc.issocket ())
- {
- set_errno (EBADF);
- return 0;
- }
- status = NtOpenFile (&fh, GENERIC_READ | SYNCHRONIZE,
- pc.get_object_attr (attr, sec_none_nih), &io,
- FILE_SHARE_VALID_FLAGS,
- FILE_SYNCHRONOUS_IO_NONALERT
- | FILE_OPEN_FOR_BACKUP_INTENT);
- if (!NT_SUCCESS (status))
+ /* Do NOT test for the file being a socket file here. The socket file
+ creation is not an atomic operation, so there is a chance that socket
+ files which are just in the process of being created are recognized
+ as non-socket files. To work around this problem we now create the
+ file with all sharing disabled. If the below NtOpenFile fails
+ with STATUS_SHARING_VIOLATION we know that the file already exists,
+ but the creating process isn't finished yet. So we yield and try
+ again, until we can either open the file successfully, or some error
+ other than STATUS_SHARING_VIOLATION occurs.
+ Since we now don't know if the file is actually a socket file, we
+ perform this check here explicitely. */
+ pc.get_object_attr (attr, sec_none_nih);
+ do
{
- __seterrno_from_nt_status (status);
- return 0;
+ status = NtOpenFile (&fh, GENERIC_READ | SYNCHRONIZE, &attr, &io,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_FOR_BACKUP_INTENT);
+ if (status == STATUS_SHARING_VIOLATION)
+ yield ();
+ else if (!NT_SUCCESS (status))
+ {
+ __seterrno_from_nt_status (status);
+ return 0;
+ }
}
+ while (status == STATUS_SHARING_VIOLATION);
int ret = 0;
char buf[128];
memset (buf, 0, sizeof buf);
@@ -119,6 +132,11 @@ get_inet_addr (const struct sockaddr *in, int inlen,
struct sockaddr_in sin;
char ctype;
sin.sin_family = AF_INET;
+ if (strncmp (buf, SOCKET_COOKIE, strlen (SOCKET_COOKIE)))
+ {
+ set_errno (EBADF);
+ return 0;
+ }
sscanf (buf + strlen (SOCKET_COOKIE), "%hu %c %08x-%08x-%08x-%08x",
&sin.sin_port,
&ctype,
@@ -972,7 +990,7 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
status = NtCreateFile (&fh, DELETE | FILE_GENERIC_WRITE,
pc.get_object_attr (attr, sa), &io, NULL, fattr,
- FILE_SHARE_VALID_FLAGS, FILE_CREATE,
+ 0, FILE_CREATE,
FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
| FILE_OPEN_FOR_BACKUP_INTENT,