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>2010-04-13 23:56:30 +0400
committerCorinna Vinschen <corinna@vinschen.de>2010-04-13 23:56:30 +0400
commit0ef4bb7c5003d6a841068725e089c233b6ed304e (patch)
tree85966243b4a48c29c7f5d79c3f380ceafab8f7a4 /winsup/cygwin/fhandler_socket.cc
parent2bba259eb77d8f4150ca838a9c2f52ec56a1c931 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r--winsup/cygwin/fhandler_socket.cc46
1 files changed, 32 insertions, 14 deletions
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 66ba3e9b2..82be0ca38 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,