OSDN Git Service

17d98dc38ae0cbcf5dca9cbf677927e4171b6313
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / fhandler_socket.cc
1 /* fhandler_socket.cc. See fhandler.h for a description of the fhandler classes.
2
3    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4    2009, 2010, 2011 Red Hat, Inc.
5
6    This file is part of Cygwin.
7
8    This software is a copyrighted work licensed under the terms of the
9    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10    details. */
11
12 /* #define DEBUG_NEST_ON 1 */
13
14 #define  __INSIDE_CYGWIN_NET__
15
16 #include "winsup.h"
17 #include <sys/un.h>
18 #include <asm/byteorder.h>
19
20 #include <stdlib.h>
21 #define USE_SYS_TYPES_FD_SET
22 #include <winsock2.h>
23 #include <mswsock.h>
24 #include <iphlpapi.h>
25 #include "cygerrno.h"
26 #include "security.h"
27 #include "cygwin/version.h"
28 #include "perprocess.h"
29 #include "path.h"
30 #include "fhandler.h"
31 #include "dtable.h"
32 #include "cygheap.h"
33 #include "shared_info.h"
34 #include "sigproc.h"
35 #include "wininfo.h"
36 #include <unistd.h>
37 #include <sys/acl.h>
38 #include "cygtls.h"
39 #include "cygwin/in6.h"
40 #include "ntdll.h"
41 #include "miscfuncs.h"
42
43 #define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
44 #define EVENT_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE)
45
46 extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc);
47 extern "C" {
48 int sscanf (const char *, const char *, ...);
49 } /* End of "C" section */
50
51 fhandler_dev_random* entropy_source;
52
53 static inline mode_t
54 adjust_socket_file_mode (mode_t mode)
55 {
56   /* Kludge: Don't allow to remove read bit on socket files for
57      user/group/other, if the accompanying write bit is set.  It would
58      be nice to have exact permissions on a socket file, but it's
59      necessary that somebody able to access the socket can always read
60      the contents of the socket file to avoid spurious "permission
61      denied" messages. */
62   return mode | ((mode & (S_IWUSR | S_IWGRP | S_IWOTH)) << 1);
63 }
64
65 /* cygwin internal: map sockaddr into internet domain address */
66 int
67 get_inet_addr (const struct sockaddr *in, int inlen,
68                struct sockaddr_storage *out, int *outlen,
69                int *type = NULL, int *secret = NULL)
70 {
71   int secret_buf [4];
72   int* secret_ptr = (secret ? : secret_buf);
73
74   switch (in->sa_family)
75     {
76     case AF_LOCAL:
77       break;
78     case AF_INET:
79     case AF_INET6:
80       memcpy (out, in, inlen);
81       *outlen = inlen;
82       return 0;
83     default:
84       set_errno (EAFNOSUPPORT);
85       return SOCKET_ERROR;
86     }
87   /* AF_LOCAL/AF_UNIX only */
88   path_conv pc (in->sa_data, PC_SYM_FOLLOW);
89   if (pc.error)
90     {
91       set_errno (pc.error);
92       return SOCKET_ERROR;
93     }
94   if (!pc.exists ())
95     {
96       set_errno (ENOENT);
97       return SOCKET_ERROR;
98     }
99   /* Do NOT test for the file being a socket file here.  The socket file
100      creation is not an atomic operation, so there is a chance that socket
101      files which are just in the process of being created are recognized
102      as non-socket files.  To work around this problem we now create the
103      file with all sharing disabled.  If the below NtOpenFile fails
104      with STATUS_SHARING_VIOLATION we know that the file already exists,
105      but the creating process isn't finished yet.  So we yield and try
106      again, until we can either open the file successfully, or some error
107      other than STATUS_SHARING_VIOLATION occurs.
108      Since we now don't know if the file is actually a socket file, we
109      perform this check here explicitely. */
110   NTSTATUS status;
111   HANDLE fh;
112   OBJECT_ATTRIBUTES attr;
113   IO_STATUS_BLOCK io;
114
115   pc.get_object_attr (attr, sec_none_nih);
116   do
117     {
118       status = NtOpenFile (&fh, GENERIC_READ | SYNCHRONIZE, &attr, &io,
119                            FILE_SHARE_VALID_FLAGS,
120                            FILE_SYNCHRONOUS_IO_NONALERT
121                            | FILE_OPEN_FOR_BACKUP_INTENT
122                            | FILE_NON_DIRECTORY_FILE);
123       if (status == STATUS_SHARING_VIOLATION)
124         {
125           /* While we hope that the sharing violation is only temporary, we
126              also could easily get stuck here, waiting for a file in use by
127              some greedy Win32 application.  Therefore we should never wait
128              endlessly without checking for signals and thread cancel event. */
129           pthread_testcancel ();
130           /* Using IsEventSignalled like this is racy since another thread could
131              be waiting for signal_arrived. */
132           if (IsEventSignalled (signal_arrived)
133               && !_my_tls.call_signal_handler ())
134             {
135               set_errno (EINTR);
136               return SOCKET_ERROR;
137             }
138           yield ();
139         }
140       else if (!NT_SUCCESS (status))
141         {
142           __seterrno_from_nt_status (status);
143           return SOCKET_ERROR;
144         }
145     }
146   while (status == STATUS_SHARING_VIOLATION);
147   /* Now test for the SYSTEM bit. */
148   FILE_BASIC_INFORMATION fbi;
149   status = NtQueryInformationFile (fh, &io, &fbi, sizeof fbi,
150                                    FileBasicInformation);
151   if (!NT_SUCCESS (status))
152     {
153       __seterrno_from_nt_status (status);
154       return SOCKET_ERROR;
155     }
156   if (!(fbi.FileAttributes & FILE_ATTRIBUTE_SYSTEM))
157     {
158       NtClose (fh);
159       set_errno (EBADF);
160       return SOCKET_ERROR;
161     }
162   /* Eventually check the content and fetch the required information. */
163   char buf[128];
164   memset (buf, 0, sizeof buf);
165   status = NtReadFile (fh, NULL, NULL, NULL, &io, buf, 128, NULL, NULL);
166   NtClose (fh);
167   if (NT_SUCCESS (status))
168     {
169       struct sockaddr_in sin;
170       char ctype;
171       sin.sin_family = AF_INET;
172       if (strncmp (buf, SOCKET_COOKIE, strlen (SOCKET_COOKIE)))
173         {
174           set_errno (EBADF);
175           return SOCKET_ERROR;
176         }
177       sscanf (buf + strlen (SOCKET_COOKIE), "%hu %c %08x-%08x-%08x-%08x",
178               &sin.sin_port,
179               &ctype,
180               secret_ptr, secret_ptr + 1, secret_ptr + 2, secret_ptr + 3);
181       sin.sin_port = htons (sin.sin_port);
182       sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
183       memcpy (out, &sin, sizeof sin);
184       *outlen = sizeof sin;
185       if (type)
186         *type = (ctype == 's' ? SOCK_STREAM :
187                  ctype == 'd' ? SOCK_DGRAM
188                               : 0);
189       return 0;
190     }
191   __seterrno_from_nt_status (status);
192   return SOCKET_ERROR;
193 }
194
195 /**********************************************************************/
196 /* fhandler_socket */
197
198 fhandler_socket::fhandler_socket () :
199   fhandler_base (),
200   wsock_events (NULL),
201   wsock_mtx (NULL),
202   wsock_evt (NULL),
203   prot_info_ptr (NULL),
204   sun_path (NULL),
205   peer_sun_path (NULL),
206   status ()
207 {
208   need_fork_fixup (true);
209 }
210
211 fhandler_socket::~fhandler_socket ()
212 {
213   if (prot_info_ptr)
214     cfree (prot_info_ptr);
215   if (sun_path)
216     cfree (sun_path);
217   if (peer_sun_path)
218     cfree (peer_sun_path);
219 }
220
221 char *
222 fhandler_socket::get_proc_fd_name (char *buf)
223 {
224   __small_sprintf (buf, "socket:[%d]", get_socket ());
225   return buf;
226 }
227
228 int
229 fhandler_socket::open (int flags, mode_t mode)
230 {
231   set_errno (ENXIO);
232   return 0;
233 }
234
235 void
236 fhandler_socket::af_local_set_sockpair_cred ()
237 {
238   sec_pid = sec_peer_pid = getpid ();
239   sec_uid = sec_peer_uid = geteuid32 ();
240   sec_gid = sec_peer_gid = getegid32 ();
241 }
242
243 void
244 fhandler_socket::af_local_setblocking (bool &async, bool &nonblocking)
245 {
246   async = async_io ();
247   nonblocking = is_nonblocking ();
248   if (async)
249     {
250       WSAAsyncSelect (get_socket (), winmsg, 0, 0);
251       WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK);
252     }
253   set_nonblocking (false);
254   async_io (false);
255 }
256
257 void
258 fhandler_socket::af_local_unsetblocking (bool async, bool nonblocking)
259 {
260   if (nonblocking)
261     set_nonblocking (true);
262   if (async)
263     {
264       WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
265       async_io (true);
266     }
267 }
268
269 bool
270 fhandler_socket::af_local_recv_secret ()
271 {
272   int out[4] = { 0, 0, 0, 0 };
273   int rest = sizeof out;
274   char *ptr = (char *) out;
275   while (rest > 0)
276     {
277       int ret = recvfrom (ptr, rest, 0, NULL, NULL);
278       if (ret <= 0)
279         break;
280       rest -= ret;
281       ptr += ret;
282     }
283   if (rest == 0)
284     {
285       debug_printf ("Received af_local secret: %08x-%08x-%08x-%08x",
286                     out[0], out[1], out[2], out[3]);
287       if (out[0] != connect_secret[0] || out[1] != connect_secret[1]
288           || out[2] != connect_secret[2] || out[3] != connect_secret[3])
289         {
290           debug_printf ("Receiving af_local secret mismatch");
291           return false;
292         }
293     }
294   else
295     debug_printf ("Receiving af_local secret failed");
296   return rest == 0;
297 }
298
299 bool
300 fhandler_socket::af_local_send_secret ()
301 {
302   int rest = sizeof connect_secret;
303   char *ptr = (char *) connect_secret;
304   while (rest > 0)
305     {
306       int ret = sendto (ptr, rest, 0, NULL, 0);
307       if (ret <= 0)
308         break;
309       rest -= ret;
310       ptr += ret;
311     }
312   debug_printf ("Sending af_local secret %s", rest == 0 ? "succeeded"
313                                                         : "failed");
314   return rest == 0;
315 }
316
317 bool
318 fhandler_socket::af_local_recv_cred ()
319 {
320   struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
321   int rest = sizeof out;
322   char *ptr = (char *) &out;
323   while (rest > 0)
324     {
325       int ret = recvfrom (ptr, rest, 0, NULL, NULL);
326       if (ret <= 0)
327         break;
328       rest -= ret;
329       ptr += ret;
330     }
331   if (rest == 0)
332     {
333       debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
334                     out.pid, out.uid, out.gid);
335       sec_peer_pid = out.pid;
336       sec_peer_uid = out.uid;
337       sec_peer_gid = out.gid;
338     }
339   else
340     debug_printf ("Receiving eid credentials failed");
341   return rest == 0;
342 }
343
344 bool
345 fhandler_socket::af_local_send_cred ()
346 {
347   struct ucred in = { sec_pid, sec_uid, sec_gid };
348   int rest = sizeof in;
349   char *ptr = (char *) &in;
350   while (rest > 0)
351     {
352       int ret = sendto (ptr, rest, 0, NULL, 0);
353       if (ret <= 0)
354         break;
355       rest -= ret;
356       ptr += ret;
357     }
358   if (rest == 0)
359     debug_printf ("Sending eid credentials succeeded");
360   else
361     debug_printf ("Sending eid credentials failed");
362   return rest == 0;
363 }
364
365 int
366 fhandler_socket::af_local_connect ()
367 {
368   /* This keeps the test out of select. */
369   if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
370     return 0;
371
372   debug_printf ("af_local_connect called");
373   bool orig_async_io, orig_is_nonblocking;
374   af_local_setblocking (orig_async_io, orig_is_nonblocking);
375   if (!af_local_send_secret () || !af_local_recv_secret ()
376       || !af_local_send_cred () || !af_local_recv_cred ())
377     {
378       debug_printf ("accept from unauthorized server");
379       ::shutdown (get_socket (), SD_BOTH);
380       WSASetLastError (WSAECONNREFUSED);
381       return -1;
382     }
383   af_local_unsetblocking (orig_async_io, orig_is_nonblocking);
384   return 0;
385 }
386
387 int
388 fhandler_socket::af_local_accept ()
389 {
390   debug_printf ("af_local_accept called");
391   bool orig_async_io, orig_is_nonblocking;
392   af_local_setblocking (orig_async_io, orig_is_nonblocking);
393   if (!af_local_recv_secret () || !af_local_send_secret ()
394       || !af_local_recv_cred () || !af_local_send_cred ())
395     {
396       debug_printf ("connect from unauthorized client");
397       ::shutdown (get_socket (), SD_BOTH);
398       ::closesocket (get_socket ());
399       WSASetLastError (WSAECONNABORTED);
400       return -1;
401     }
402   af_local_unsetblocking (orig_async_io, orig_is_nonblocking);
403   return 0;
404 }
405
406 void
407 fhandler_socket::af_local_set_cred ()
408 {
409   sec_pid = getpid ();
410   sec_uid = geteuid32 ();
411   sec_gid = getegid32 ();
412   sec_peer_pid = (pid_t) 0;
413   sec_peer_uid = (__uid32_t) -1;
414   sec_peer_gid = (__gid32_t) -1;
415 }
416
417 void
418 fhandler_socket::af_local_copy (fhandler_socket *sock)
419 {
420   sock->connect_secret[0] = connect_secret[0];
421   sock->connect_secret[1] = connect_secret[1];
422   sock->connect_secret[2] = connect_secret[2];
423   sock->connect_secret[3] = connect_secret[3];
424   sock->sec_pid = sec_pid;
425   sock->sec_uid = sec_uid;
426   sock->sec_gid = sec_gid;
427   sock->sec_peer_pid = sec_peer_pid;
428   sock->sec_peer_uid = sec_peer_uid;
429   sock->sec_peer_gid = sec_peer_gid;
430 }
431
432 void
433 fhandler_socket::af_local_set_secret (char *buf)
434 {
435   if (!entropy_source)
436     {
437       void *buf = malloc (sizeof (fhandler_dev_random));
438       entropy_source = new (buf) fhandler_dev_random ();
439       entropy_source->dev () = *urandom_dev;
440     }
441   if (entropy_source &&
442       !entropy_source->open (O_RDONLY))
443     {
444       delete entropy_source;
445       entropy_source = NULL;
446     }
447   if (entropy_source)
448     {
449       size_t len = sizeof (connect_secret);
450       entropy_source->read (connect_secret, len);
451       if (len != sizeof (connect_secret))
452         bzero ((char*) connect_secret, sizeof (connect_secret));
453     }
454   __small_sprintf (buf, "%08x-%08x-%08x-%08x",
455                    connect_secret [0], connect_secret [1],
456                    connect_secret [2], connect_secret [3]);
457 }
458
459 /* Maximum number of concurrently opened sockets from all Cygwin processes
460    per session.  Note that shared sockets (through dup/fork/exec) are
461    counted as one socket. */
462 #define NUM_SOCKS       (32768 / sizeof (wsa_event))
463
464 #define LOCK_EVENTS     WaitForSingleObject (wsock_mtx, INFINITE)
465 #define UNLOCK_EVENTS   ReleaseMutex (wsock_mtx)
466
467 static wsa_event wsa_events[NUM_SOCKS] __attribute__((section (".cygwin_dll_common"), shared));
468
469 static LONG socket_serial_number __attribute__((section (".cygwin_dll_common"), shared));
470
471 static HANDLE wsa_slot_mtx;
472
473 static PWCHAR
474 sock_shared_name (PWCHAR buf, LONG num)
475 {
476   __small_swprintf (buf, L"socket.%d", num);
477   return buf;
478 }
479
480 static wsa_event *
481 search_wsa_event_slot (LONG new_serial_number)
482 {
483   WCHAR name[32], searchname[32];
484   UNICODE_STRING uname;
485   OBJECT_ATTRIBUTES attr;
486   NTSTATUS status;
487
488   if (!wsa_slot_mtx)
489     {
490       RtlInitUnicodeString (&uname, sock_shared_name (name, 0));
491       InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF,
492                                   get_session_parent_dir (),
493                                   everyone_sd (CYG_MUTANT_ACCESS));
494       status = NtCreateMutant (&wsa_slot_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
495       if (!NT_SUCCESS (status))
496         api_fatal ("Couldn't create/open shared socket mutex %S, %p",
497                    &uname, status);
498     }
499   switch (WaitForSingleObject (wsa_slot_mtx, INFINITE))
500     {
501     case WAIT_OBJECT_0:
502     case WAIT_ABANDONED:
503       break;
504     default:
505       api_fatal ("WFSO failed for shared socket mutex, %E");
506       break;
507     }
508   unsigned int slot = new_serial_number % NUM_SOCKS;
509   while (wsa_events[slot].serial_number)
510     {
511       HANDLE searchmtx;
512       RtlInitUnicodeString (&uname, sock_shared_name (searchname,
513                                         wsa_events[slot].serial_number));
514       InitializeObjectAttributes (&attr, &uname, 0, get_session_parent_dir (),
515                                   NULL);
516       status = NtOpenMutant (&searchmtx, READ_CONTROL, &attr);
517       if (!NT_SUCCESS (status))
518         break;
519       /* Mutex still exists, attached socket is active, try next slot. */
520       NtClose (searchmtx);
521       slot = (slot + 1) % NUM_SOCKS;
522       if (slot == (new_serial_number % NUM_SOCKS))
523         {
524           /* Did the whole array once.   Too bad. */
525           debug_printf ("No free socket slot");
526           ReleaseMutex (wsa_slot_mtx);
527           return NULL;
528         }
529     }
530   memset (&wsa_events[slot], 0, sizeof (wsa_event));
531   wsa_events[slot].serial_number = new_serial_number;
532   ReleaseMutex (wsa_slot_mtx);
533   return wsa_events + slot;
534 }
535
536 bool
537 fhandler_socket::init_events ()
538 {
539   LONG new_serial_number;
540   WCHAR name[32];
541   UNICODE_STRING uname;
542   OBJECT_ATTRIBUTES attr;
543   NTSTATUS status;
544
545   do
546     {
547       new_serial_number =
548         InterlockedIncrement (&socket_serial_number);
549       if (!new_serial_number)   /* 0 is reserved for global mutex */
550         InterlockedIncrement (&socket_serial_number);
551       RtlInitUnicodeString (&uname, sock_shared_name (name, new_serial_number));
552       InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF,
553                                   get_session_parent_dir (),
554                                   everyone_sd (CYG_MUTANT_ACCESS));
555       status = NtCreateMutant (&wsock_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
556       if (!NT_SUCCESS (status))
557         {
558           debug_printf ("NtCreateMutant(%S), %p", &uname, status);
559           set_errno (ENOBUFS);
560           return false;
561         }
562       if (status == STATUS_OBJECT_NAME_EXISTS)
563         NtClose (wsock_mtx);
564     }
565   while (status == STATUS_OBJECT_NAME_EXISTS);
566   if ((wsock_evt = CreateEvent (&sec_all, TRUE, FALSE, NULL))
567       == WSA_INVALID_EVENT)
568     {
569       debug_printf ("CreateEvent, %E");
570       set_errno (ENOBUFS);
571       NtClose (wsock_mtx);
572       return false;
573     }
574   if (WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK) == SOCKET_ERROR)
575     {
576       debug_printf ("WSAEventSelect, %E");
577       set_winsock_errno ();
578       NtClose (wsock_evt);
579       NtClose (wsock_mtx);
580       return false;
581     }
582   wsock_events = search_wsa_event_slot (new_serial_number);
583   /* sock type not yet set here. */
584   if (pc.dev == FH_UDP || pc.dev == FH_DGRAM)
585     wsock_events->events = FD_WRITE;
586   return true;
587 }
588
589 int
590 fhandler_socket::evaluate_events (const long event_mask, long &events,
591                                   const bool erase)
592 {
593   int ret = 0;
594   long events_now = 0;
595
596   WSANETWORKEVENTS evts = { 0 };
597   if (!(WSAEnumNetworkEvents (get_socket (), wsock_evt, &evts)))
598     {
599       if (evts.lNetworkEvents)
600         {
601           LOCK_EVENTS;
602           wsock_events->events |= evts.lNetworkEvents;
603           events_now = (wsock_events->events & event_mask);
604           if (evts.lNetworkEvents & FD_CONNECT)
605             wsock_events->connect_errorcode = evts.iErrorCode[FD_CONNECT_BIT];
606           UNLOCK_EVENTS;
607           if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
608             kill (wsock_events->owner, SIGURG);
609         }
610     }
611
612   LOCK_EVENTS;
613   if ((events = events_now) != 0
614       || (events = (wsock_events->events & event_mask)) != 0)
615     {
616       if (events & FD_CONNECT)
617         {
618           int wsa_err = 0;
619           if ((wsa_err = wsock_events->connect_errorcode) != 0)
620             {
621               WSASetLastError (wsa_err);
622               ret = SOCKET_ERROR;
623             }
624           else
625             wsock_events->events |= FD_WRITE;
626           wsock_events->events &= ~FD_CONNECT;
627           wsock_events->connect_errorcode = 0;
628         }
629       /* This test makes the accept function behave as on Linux when
630          accept is called on a socket for which shutdown for the read side
631          has been called.  The second half of this code is in the shutdown
632          method.  See there for more info. */
633       if ((event_mask & FD_ACCEPT) && (events & FD_CLOSE))
634         {
635           WSASetLastError (WSAEINVAL);
636           ret = SOCKET_ERROR;
637         }
638       if (erase)
639         wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE));
640     }
641   UNLOCK_EVENTS;
642
643   return ret;
644 }
645
646 int
647 fhandler_socket::wait_for_events (const long event_mask, const DWORD flags)
648 {
649   if (async_io ())
650     return 0;
651
652   int ret;
653   long events;
654
655   while (!(ret = evaluate_events (event_mask, events, !(flags & MSG_PEEK)))
656          && !events)
657     {
658       if (is_nonblocking () || (flags & MSG_DONTWAIT))
659         {
660           WSASetLastError (WSAEWOULDBLOCK);
661           return SOCKET_ERROR;
662         }
663
664       WSAEVENT ev[2] = { wsock_evt, signal_arrived };
665       switch (WSAWaitForMultipleEvents (2, ev, FALSE, 50, FALSE))
666         {
667           case WSA_WAIT_TIMEOUT:
668             pthread_testcancel ();
669             /*FALLTHRU*/
670           case WSA_WAIT_EVENT_0:
671             break;
672
673           case WSA_WAIT_EVENT_0 + 1:
674             if (_my_tls.call_signal_handler ())
675               break;
676             WSASetLastError (WSAEINTR);
677             return SOCKET_ERROR;
678
679           default:
680             WSASetLastError (WSAEFAULT);
681             return SOCKET_ERROR;
682         }
683     }
684
685   return ret;
686 }
687
688 void
689 fhandler_socket::release_events ()
690 {
691   NtClose (wsock_evt);
692   NtClose (wsock_mtx);
693 }
694
695 /* Called from net.cc:fdsock() if a freshly created socket is not
696    inheritable.  In that case we use fixup_before_fork_exec.  See
697    the comment in fdsock() for a description of the problem. */
698 void
699 fhandler_socket::init_fixup_before ()
700 {
701   prot_info_ptr = (LPWSAPROTOCOL_INFOW)
702                   cmalloc_abort (HEAP_BUF, sizeof (WSAPROTOCOL_INFOW));
703   cygheap->fdtab.inc_need_fixup_before ();
704 }
705
706 int
707 fhandler_socket::fixup_before_fork_exec (DWORD win_pid)
708 {
709   SOCKET ret = WSADuplicateSocketW (get_socket (), win_pid, prot_info_ptr);
710   if (ret)
711     set_winsock_errno ();
712   else
713     debug_printf ("WSADuplicateSocket succeeded (%lx)", prot_info_ptr->dwProviderReserved);
714   return (int) ret;
715 }
716
717 void
718 fhandler_socket::fixup_after_fork (HANDLE parent)
719 {
720   fork_fixup (parent, wsock_mtx, "wsock_mtx");
721   fork_fixup (parent, wsock_evt, "wsock_evt");
722
723   if (!need_fixup_before ())
724     {
725       fhandler_base::fixup_after_fork (parent);
726       return;
727     }
728
729   SOCKET new_sock = WSASocketW (FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
730                                 FROM_PROTOCOL_INFO, prot_info_ptr, 0,
731                                 WSA_FLAG_OVERLAPPED);
732   if (new_sock == INVALID_SOCKET)
733     {
734       set_winsock_errno ();
735       set_io_handle ((HANDLE) INVALID_SOCKET);
736     }
737   else
738     {
739       /* Even though the original socket was not inheritable, the duplicated
740          socket is potentially inheritable again. */
741       SetHandleInformation ((HANDLE) new_sock, HANDLE_FLAG_INHERIT, 0);
742       set_io_handle ((HANDLE) new_sock);
743       debug_printf ("WSASocket succeeded (%lx)", new_sock);
744     }
745 }
746
747 void
748 fhandler_socket::fixup_after_exec ()
749 {
750   if (need_fixup_before () && !close_on_exec ())
751     fixup_after_fork (NULL);
752 }
753
754 int
755 fhandler_socket::dup (fhandler_base *child, int flags)
756 {
757   debug_printf ("here");
758   fhandler_socket *fhs = (fhandler_socket *) child;
759
760   if (!DuplicateHandle (GetCurrentProcess (), wsock_mtx,
761                         GetCurrentProcess (), &fhs->wsock_mtx,
762                         0, TRUE, DUPLICATE_SAME_ACCESS))
763     {
764       __seterrno ();
765       return -1;
766     }
767   if (!DuplicateHandle (GetCurrentProcess (), wsock_evt,
768                         GetCurrentProcess (), &fhs->wsock_evt,
769                         0, TRUE, DUPLICATE_SAME_ACCESS))
770     {
771       __seterrno ();
772       NtClose (fhs->wsock_mtx);
773       return -1;
774     }
775   if (get_addr_family () == AF_LOCAL)
776     {
777       fhs->set_sun_path (get_sun_path ());
778       fhs->set_peer_sun_path (get_peer_sun_path ());
779     }
780   if (!need_fixup_before ())
781     {
782       int ret = fhandler_base::dup (child, flags);
783       if (ret)
784         {
785           NtClose (fhs->wsock_evt);
786           NtClose (fhs->wsock_mtx);
787         }
788       return ret;
789     }
790
791   cygheap->user.deimpersonate ();
792   fhs->init_fixup_before ();
793   fhs->set_io_handle (get_io_handle ());
794   int ret = fhs->fixup_before_fork_exec (GetCurrentProcessId ());
795   cygheap->user.reimpersonate ();
796   if (!ret)
797     {
798       fhs->fixup_after_fork (GetCurrentProcess ());
799       if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
800         return 0;
801     }
802   cygheap->fdtab.dec_need_fixup_before ();
803   NtClose (fhs->wsock_evt);
804   NtClose (fhs->wsock_mtx);
805   return -1;
806 }
807
808 int __stdcall
809 fhandler_socket::fstat (struct __stat64 *buf)
810 {
811   int res;
812   if (get_device () == FH_UNIX)
813     {
814       res = fhandler_base::fstat_fs (buf);
815       if (!res)
816         {
817           buf->st_mode = (buf->st_mode & ~S_IFMT) | S_IFSOCK;
818           buf->st_size = 0;
819         }
820     }
821   else
822     {
823       res = fhandler_base::fstat (buf);
824       if (!res)
825         {
826           buf->st_dev = 0;
827           buf->st_ino = (__ino64_t) ((DWORD) get_handle ());
828           buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO;
829           buf->st_size = 0;
830         }
831     }
832   return res;
833 }
834
835 int __stdcall
836 fhandler_socket::fstatvfs (struct statvfs *sfs)
837 {
838   if (get_device () == FH_UNIX)
839     {
840       fhandler_disk_file fh (pc);
841       fh.get_device () = FH_FS;
842       return fh.fstatvfs (sfs);
843     }
844   set_errno (EBADF);
845   return -1;
846 }
847
848 int
849 fhandler_socket::fchmod (mode_t mode)
850 {
851   if (get_device () == FH_UNIX)
852     {
853       fhandler_disk_file fh (pc);
854       fh.get_device () = FH_FS;
855       int ret = fh.fchmod (S_IFSOCK | adjust_socket_file_mode (mode));
856       return ret;
857     }
858   set_errno (EBADF);
859   return -1;
860 }
861
862 int
863 fhandler_socket::fchown (__uid32_t uid, __gid32_t gid)
864 {
865   if (get_device () == FH_UNIX)
866     {
867       fhandler_disk_file fh (pc);
868       return fh.fchown (uid, gid);
869     }
870   set_errno (EBADF);
871   return -1;
872 }
873
874 int
875 fhandler_socket::facl (int cmd, int nentries, __aclent32_t *aclbufp)
876 {
877   if (get_device () == FH_UNIX)
878     {
879       fhandler_disk_file fh (pc);
880       return fh.facl (cmd, nentries, aclbufp);
881     }
882   set_errno (EBADF);
883   return -1;
884 }
885
886 int
887 fhandler_socket::link (const char *newpath)
888 {
889   if (get_device () == FH_UNIX)
890     {
891       fhandler_disk_file fh (pc);
892       return fh.link (newpath);
893     }
894   return fhandler_base::link (newpath);
895 }
896
897 int
898 fhandler_socket::bind (const struct sockaddr *name, int namelen)
899 {
900   int res = -1;
901
902   if (name->sa_family == AF_LOCAL)
903     {
904 #define un_addr ((struct sockaddr_un *) name)
905       struct sockaddr_in sin;
906       int len = sizeof sin;
907
908       if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
909         {
910           set_errno (ENAMETOOLONG);
911           goto out;
912         }
913       sin.sin_family = AF_INET;
914       sin.sin_port = 0;
915       sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
916       if (::bind (get_socket (), (sockaddr *) &sin, len))
917         {
918           syscall_printf ("AF_LOCAL: bind failed");
919           set_winsock_errno ();
920           goto out;
921         }
922       if (::getsockname (get_socket (), (sockaddr *) &sin, &len))
923         {
924           syscall_printf ("AF_LOCAL: getsockname failed");
925           set_winsock_errno ();
926           goto out;
927         }
928
929       sin.sin_port = ntohs (sin.sin_port);
930       debug_printf ("AF_LOCAL: socket bound to port %u", sin.sin_port);
931
932       path_conv pc (un_addr->sun_path, PC_SYM_FOLLOW);
933       if (pc.error)
934         {
935           set_errno (pc.error);
936           goto out;
937         }
938       if (pc.exists ())
939         {
940           set_errno (EADDRINUSE);
941           goto out;
942         }
943       mode_t mode = adjust_socket_file_mode ((S_IRWXU | S_IRWXG | S_IRWXO)
944                                              & ~cygheap->umask);
945       DWORD fattr = FILE_ATTRIBUTE_SYSTEM;
946       if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)) && !pc.has_acls ())
947         fattr |= FILE_ATTRIBUTE_READONLY;
948       SECURITY_ATTRIBUTES sa = sec_none_nih;
949       NTSTATUS status;
950       HANDLE fh;
951       OBJECT_ATTRIBUTES attr;
952       IO_STATUS_BLOCK io;
953       ULONG access = DELETE | FILE_GENERIC_WRITE;
954
955       /* If the filesystem supports ACLs, we will overwrite the DACL after the
956          call to NtCreateFile.  This requires a handle with READ_CONTROL and
957          WRITE_DAC access, otherwise get_file_sd and set_file_sd both have to
958          open the file again.
959          FIXME: On remote NTFS shares open sometimes fails because even the
960          creator of the file doesn't have the right to change the DACL.
961          I don't know what setting that is or how to recognize such a share,
962          so for now we don't request WRITE_DAC on remote drives. */
963       if (pc.has_acls () && !pc.isremote ())
964         access |= READ_CONTROL | WRITE_DAC;
965
966       status = NtCreateFile (&fh, access, pc.get_object_attr (attr, sa), &io,
967                              NULL, fattr, 0, FILE_CREATE,
968                              FILE_NON_DIRECTORY_FILE
969                              | FILE_SYNCHRONOUS_IO_NONALERT
970                              | FILE_OPEN_FOR_BACKUP_INTENT,
971                              NULL, 0);
972       if (!NT_SUCCESS (status))
973         {
974           if (io.Information == FILE_EXISTS)
975             set_errno (EADDRINUSE);
976           else
977             __seterrno_from_nt_status (status);
978         }
979       else
980         {
981           if (pc.has_acls ())
982             set_file_attribute (fh, pc, ILLEGAL_UID, ILLEGAL_GID,
983                                 S_JUSTCREATED | mode);
984           char buf[sizeof (SOCKET_COOKIE) + 80];
985           __small_sprintf (buf, "%s%u %c ", SOCKET_COOKIE, sin.sin_port,
986                            get_socket_type () == SOCK_STREAM ? 's'
987                            : get_socket_type () == SOCK_DGRAM ? 'd' : '-');
988           af_local_set_secret (strchr (buf, '\0'));
989           DWORD blen = strlen (buf) + 1;
990           status = NtWriteFile (fh, NULL, NULL, NULL, &io, buf, blen, NULL, 0);
991           if (!NT_SUCCESS (status))
992             {
993               __seterrno_from_nt_status (status);
994               FILE_DISPOSITION_INFORMATION fdi = { TRUE };
995               status = NtSetInformationFile (fh, &io, &fdi, sizeof fdi,
996                                              FileDispositionInformation);
997               if (!NT_SUCCESS (status))
998                 debug_printf ("Setting delete dispostion failed, status = %p",
999                               status);
1000             }
1001           else
1002             {
1003               set_sun_path (un_addr->sun_path);
1004               res = 0;
1005             }
1006           NtClose (fh);
1007         }
1008 #undef un_addr
1009     }
1010   else
1011     {
1012       if (!saw_reuseaddr ())
1013         {
1014           /* If the application didn't explicitely request SO_REUSEADDR,
1015              enforce POSIX standard socket binding behaviour by setting the
1016              SO_EXCLUSIVEADDRUSE socket option.  See cygwin_setsockopt()
1017              for a more detailed description.
1018
1019              KB 870562: Note that a bug in Win2K SP1-3 and XP up to SP1 only
1020              enables this option for users in the local administrators group. */
1021           int on = 1;
1022           int ret = ::setsockopt (get_socket (), SOL_SOCKET,
1023                                   ~(SO_REUSEADDR),
1024                                   (const char *) &on, sizeof on);
1025           debug_printf ("%d = setsockopt(SO_EXCLUSIVEADDRUSE), %E", ret);
1026         }
1027       if (::bind (get_socket (), name, namelen))
1028         set_winsock_errno ();
1029       else
1030         res = 0;
1031     }
1032
1033 out:
1034   return res;
1035 }
1036
1037 int
1038 fhandler_socket::connect (const struct sockaddr *name, int namelen)
1039 {
1040   bool in_progress = false;
1041   struct sockaddr_storage sst;
1042   DWORD err;
1043   int type;
1044
1045   pthread_testcancel ();
1046
1047   if (get_inet_addr (name, namelen, &sst, &namelen, &type, connect_secret)
1048       == SOCKET_ERROR)
1049     return SOCKET_ERROR;
1050
1051   if (get_addr_family () == AF_LOCAL && get_socket_type () != type)
1052     {
1053       WSASetLastError (WSAEPROTOTYPE);
1054       set_winsock_errno ();
1055       return SOCKET_ERROR;
1056     }
1057
1058   int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
1059   if (!is_nonblocking ()
1060       && res == SOCKET_ERROR
1061       && WSAGetLastError () == WSAEWOULDBLOCK)
1062     res = wait_for_events (FD_CONNECT | FD_CLOSE, 0);
1063
1064   if (!res)
1065     err = 0;
1066   else
1067     {
1068       err = WSAGetLastError ();
1069       /* Special handling for connect to return the correct error code
1070          when called on a non-blocking socket. */
1071       if (is_nonblocking ())
1072         {
1073           if (err == WSAEWOULDBLOCK || err == WSAEALREADY)
1074             in_progress = true;
1075
1076           if (err == WSAEWOULDBLOCK)
1077             WSASetLastError (err = WSAEINPROGRESS);
1078         }
1079       if (err == WSAEINVAL)
1080         WSASetLastError (err = WSAEISCONN);
1081       set_winsock_errno ();
1082     }
1083
1084   if (get_addr_family () == AF_LOCAL && (!res || in_progress))
1085     set_peer_sun_path (name->sa_data);
1086
1087   if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
1088     {
1089       af_local_set_cred (); /* Don't move into af_local_connect since
1090                                af_local_connect is called from select,
1091                                possibly running under another identity. */
1092       if (!res && af_local_connect ())
1093         {
1094           set_winsock_errno ();
1095           return SOCKET_ERROR;
1096         }
1097     }
1098
1099   if (err == WSAEINPROGRESS || err == WSAEALREADY)
1100     connect_state (connect_pending);
1101   else if (err)
1102     connect_state (connect_failed);
1103   else
1104     connect_state (connected);
1105
1106   return res;
1107 }
1108
1109 int
1110 fhandler_socket::listen (int backlog)
1111 {
1112   int res = ::listen (get_socket (), backlog);
1113   if (res && WSAGetLastError () == WSAEINVAL)
1114     {
1115       /* It's perfectly valid to call listen on an unbound INET socket.
1116          In this case the socket is automatically bound to an unused
1117          port number, listening on all interfaces.  On WinSock, listen
1118          fails with WSAEINVAL when it's called on an unbound socket.
1119          So we have to bind manually here to have POSIX semantics. */
1120       if (get_addr_family () == AF_INET)
1121         {
1122           struct sockaddr_in sin;
1123           sin.sin_family = AF_INET;
1124           sin.sin_port = 0;
1125           sin.sin_addr.s_addr = INADDR_ANY;
1126           if (!::bind (get_socket (), (struct sockaddr *) &sin, sizeof sin))
1127             res = ::listen (get_socket (), backlog);
1128         }
1129       else if (get_addr_family () == AF_INET6)
1130         {
1131           struct sockaddr_in6 sin6 =
1132             {
1133               sin6_family: AF_INET6,
1134               sin6_port: 0,
1135               sin6_flowinfo: 0,
1136               sin6_addr: {{IN6ADDR_ANY_INIT}},
1137               sin6_scope_id: 0
1138             };
1139           if (!::bind (get_socket (), (struct sockaddr *) &sin6, sizeof sin6))
1140             res = ::listen (get_socket (), backlog);
1141         }
1142     }
1143   if (!res)
1144     {
1145       if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
1146         af_local_set_cred ();
1147       connect_state (connected);
1148       listener (true);
1149     }
1150   else
1151     set_winsock_errno ();
1152   return res;
1153 }
1154
1155 int
1156 fhandler_socket::accept4 (struct sockaddr *peer, int *len, int flags)
1157 {
1158   /* Allows NULL peer and len parameters. */
1159   struct sockaddr_storage lpeer;
1160   int llen = sizeof (struct sockaddr_storage);
1161
1162   pthread_testcancel ();
1163
1164   int res = 0;
1165   while (!(res = wait_for_events (FD_ACCEPT | FD_CLOSE, 0))
1166          && (res = ::accept (get_socket (), (struct sockaddr *) &lpeer, &llen))
1167             == SOCKET_ERROR
1168          && WSAGetLastError () == WSAEWOULDBLOCK)
1169     ;
1170   if (res == (int) INVALID_SOCKET)
1171     set_winsock_errno ();
1172   else
1173     {
1174       cygheap_fdnew res_fd;
1175       if (res_fd >= 0 && fdsock (res_fd, &dev (), res))
1176         {
1177           fhandler_socket *sock = (fhandler_socket *) res_fd;
1178           sock->set_addr_family (get_addr_family ());
1179           sock->set_socket_type (get_socket_type ());
1180           sock->async_io (false); /* fdsock switches async mode off. */
1181           if (get_addr_family () == AF_LOCAL)
1182             {
1183               sock->set_sun_path (get_sun_path ());
1184               sock->set_peer_sun_path (get_peer_sun_path ());
1185               if (get_socket_type () == SOCK_STREAM)
1186                 {
1187                   /* Don't forget to copy credentials from accepting
1188                      socket to accepted socket and start transaction
1189                      on accepted socket! */
1190                   af_local_copy (sock);
1191                   res = sock->af_local_accept ();
1192                   if (res == -1)
1193                     {
1194                       res_fd.release ();
1195                       set_winsock_errno ();
1196                       goto out;
1197                     }
1198                 }
1199             }
1200           sock->set_nonblocking (flags & SOCK_NONBLOCK);
1201           if (flags & SOCK_CLOEXEC)
1202             sock->set_close_on_exec (true);
1203           /* No locking necessary at this point. */
1204           sock->wsock_events->events = wsock_events->events | FD_WRITE;
1205           sock->wsock_events->owner = wsock_events->owner;
1206           sock->connect_state (connected);
1207           res = res_fd;
1208           if (peer)
1209             {
1210               if (get_addr_family () == AF_LOCAL)
1211                 {
1212                   /* FIXME: Right now we have no way to determine the
1213                      bound socket name of the peer's socket.  For now
1214                      we just fake an unbound socket on the other side. */
1215                   static struct sockaddr_un un = { AF_LOCAL, "" };
1216                   memcpy (peer, &un, min (*len, (int) sizeof (un.sun_family)));
1217                   *len = (int) sizeof (un.sun_family);
1218                 }
1219               else
1220                 {
1221                   memcpy (peer, &lpeer, min (*len, llen));
1222                   *len = llen;
1223                 }
1224             }
1225         }
1226       else
1227         {
1228           closesocket (res);
1229           res = -1;
1230         }
1231     }
1232
1233 out:
1234   debug_printf ("res %d", res);
1235   return res;
1236 }
1237
1238 int
1239 fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
1240 {
1241   int res = -1;
1242
1243   if (get_addr_family () == AF_LOCAL)
1244     {
1245       struct sockaddr_un sun;
1246       sun.sun_family = AF_LOCAL;
1247       sun.sun_path[0] = '\0';
1248       if (get_sun_path ())
1249         strncat (sun.sun_path, get_sun_path (), UNIX_PATH_LEN - 1);
1250       memcpy (name, &sun, min (*namelen, (int) SUN_LEN (&sun) + 1));
1251       *namelen = (int) SUN_LEN (&sun) + (get_sun_path () ? 1 : 0);
1252       res = 0;
1253     }
1254   else
1255     {
1256       /* Always use a local big enough buffer and truncate later as necessary
1257          per POSIX.  WinSock unfortunaltey only returns WSAEFAULT if the buffer
1258          is too small. */
1259       struct sockaddr_storage sock;
1260       int len = sizeof sock;
1261       res = ::getsockname (get_socket (), (struct sockaddr *) &sock, &len);
1262       if (!res)
1263         {
1264           memcpy (name, &sock, min (*namelen, len));
1265           *namelen = len;
1266         }
1267       else
1268         {
1269           if (WSAGetLastError () == WSAEINVAL)
1270             {
1271               /* WinSock returns WSAEINVAL if the socket is locally
1272                  unbound.  Per SUSv3 this is not an error condition.
1273                  We're faking a valid return value here by creating the
1274                  same content in the sockaddr structure as on Linux. */
1275               memset (&sock, 0, sizeof sock);
1276               sock.ss_family = get_addr_family ();
1277               switch (get_addr_family ())
1278                 {
1279                 case AF_INET:
1280                   res = 0;
1281                   len = (int) sizeof (struct sockaddr_in);
1282                   break;
1283                 case AF_INET6:
1284                   res = 0;
1285                   len = (int) sizeof (struct sockaddr_in6);
1286                   break;
1287                 default:
1288                   WSASetLastError (WSAEOPNOTSUPP);
1289                   break;
1290                 }
1291               if (!res)
1292                 {
1293                   memcpy (name, &sock, min (*namelen, len));
1294                   *namelen = len;
1295                 }
1296             }
1297           if (res)
1298             set_winsock_errno ();
1299         }
1300     }
1301
1302   return res;
1303 }
1304
1305 int
1306 fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
1307 {
1308   /* Always use a local big enough buffer and truncate later as necessary
1309      per POSIX.  WinSock unfortunately only returns WSAEFAULT if the buffer
1310      is too small. */
1311   struct sockaddr_storage sock;
1312   int len = sizeof sock;
1313   int res = ::getpeername (get_socket (), (struct sockaddr *) &sock, &len);
1314   if (res)
1315     set_winsock_errno ();
1316   else if (get_addr_family () == AF_LOCAL)
1317     {
1318       struct sockaddr_un sun;
1319       memset (&sun, 0, sizeof sun);
1320       sun.sun_family = AF_LOCAL;
1321       sun.sun_path[0] = '\0';
1322       if (get_peer_sun_path ())
1323         strncat (sun.sun_path, get_peer_sun_path (), UNIX_PATH_LEN - 1);
1324       memcpy (name, &sun, min (*namelen, (int) SUN_LEN (&sun) + 1));
1325       *namelen = (int) SUN_LEN (&sun) + (get_peer_sun_path () ? 1 : 0);
1326     }
1327   else
1328     {
1329       memcpy (name, &sock, min (*namelen, len));
1330       *namelen = len;
1331     }
1332
1333   return res;
1334 }
1335
1336 void __stdcall
1337 fhandler_socket::read (void *in_ptr, size_t& len)
1338 {
1339   WSABUF wsabuf = { len, (char *) in_ptr };
1340   WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0,  NULL }, 0 };
1341   len = recv_internal (&wsamsg);
1342 }
1343
1344 int
1345 fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
1346                         ssize_t tot)
1347 {
1348   WSABUF wsabuf[iovcnt];
1349   WSABUF *wsaptr = wsabuf + iovcnt;
1350   const struct iovec *iovptr = iov + iovcnt;
1351   while (--wsaptr >= wsabuf)
1352     {
1353       wsaptr->len = (--iovptr)->iov_len;
1354       wsaptr->buf = (char *) iovptr->iov_base;
1355     }
1356   WSAMSG wsamsg = { NULL, 0, wsabuf, iovcnt, { 0,  NULL}, 0 };
1357   return recv_internal (&wsamsg);
1358 }
1359
1360 extern "C" {
1361 #define WSAID_WSARECVMSG \
1362           {0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}};
1363 typedef int (WSAAPI *LPFN_WSARECVMSG)(SOCKET,LPWSAMSG,LPDWORD,LPWSAOVERLAPPED,
1364                                       LPWSAOVERLAPPED_COMPLETION_ROUTINE);
1365 int WSAAPI WSASendMsg(SOCKET,LPWSAMSG,DWORD,LPDWORD, LPWSAOVERLAPPED,
1366                       LPWSAOVERLAPPED_COMPLETION_ROUTINE);
1367 };
1368
1369 /* There's no DLL which exports the symbol WSARecvMsg.  One has to call
1370    WSAIoctl as below to fetch the function pointer.  Why on earth did the
1371    MS developers decide not to export a normal symbol for these extension
1372    functions? */
1373 inline int
1374 get_ext_funcptr (SOCKET sock, void *funcptr)
1375 {
1376   DWORD bret;
1377   const GUID guid = WSAID_WSARECVMSG;
1378   return WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
1379                    (void *) &guid, sizeof (GUID), funcptr, sizeof (void *),
1380                    &bret, NULL, NULL);
1381 }
1382
1383 inline ssize_t
1384 fhandler_socket::recv_internal (LPWSAMSG wsamsg)
1385 {
1386   ssize_t res = 0;
1387   DWORD ret = 0, wret;
1388   int evt_mask = FD_READ | ((wsamsg->dwFlags & MSG_OOB) ? FD_OOB : 0);
1389   LPWSABUF &wsabuf = wsamsg->lpBuffers;
1390   ULONG &wsacnt = wsamsg->dwBufferCount;
1391   bool use_recvmsg = false;
1392   static NO_COPY LPFN_WSARECVMSG WSARecvMsg;
1393
1394   DWORD wait_flags = wsamsg->dwFlags;
1395   bool waitall = !!(wait_flags & MSG_WAITALL);
1396   wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE);
1397   if (wsamsg->Control.len > 0)
1398     {
1399       if (!WSARecvMsg
1400           && get_ext_funcptr (get_socket (), &WSARecvMsg) == SOCKET_ERROR)
1401         {
1402           set_winsock_errno ();
1403           return SOCKET_ERROR;
1404         }
1405       use_recvmsg = true;
1406     }
1407   if (waitall)
1408     {
1409       if (get_socket_type () != SOCK_STREAM)
1410         {
1411           WSASetLastError (WSAEOPNOTSUPP);
1412           set_winsock_errno ();
1413           return SOCKET_ERROR;
1414         }
1415       if (is_nonblocking () || (wsamsg->dwFlags & (MSG_OOB | MSG_PEEK)))
1416         waitall = false;
1417     }
1418
1419   /* Note: Don't call WSARecvFrom(MSG_PEEK) without actually having data
1420      waiting in the buffers, otherwise the event handling gets messed up
1421      for some reason. */
1422   while (!(res = wait_for_events (evt_mask | FD_CLOSE, wait_flags))
1423          || saw_shutdown_read ())
1424     {
1425       if (use_recvmsg)
1426         res = WSARecvMsg (get_socket (), wsamsg, &wret, NULL, NULL);
1427       /* This is working around a really weird problem in WinSock.
1428
1429          Assume you create a socket, fork the process (thus duplicating
1430          the socket), connect the socket in the child, then call recv
1431          on the original socket handle in the parent process.
1432          In this scenario, calls to WinSock's recvfrom and WSARecvFrom
1433          in the parent will fail with WSAEINVAL, regardless whether both
1434          address parameters, name and namelen, are NULL or point to valid
1435          storage.  However, calls to recv and WSARecv succeed as expected.
1436          Per MSDN, WSAEINVAL in the context of recv means  "The socket has not
1437          been bound".  It is as if the recvfrom functions test if the socket
1438          is bound locally, but in the parent process, WinSock doesn't know
1439          about that and fails, while the same test is omitted in the recv
1440          functions.
1441
1442          This also covers another weird case: WinSock returns WSAEFAULT if
1443          namelen is a valid pointer while name is NULL.  Both parameters are
1444          ignored for TCP sockets, so this only occurs when using UDP socket. */
1445       else if (!wsamsg->name || get_socket_type () == SOCK_STREAM)
1446         res = WSARecv (get_socket (), wsabuf, wsacnt, &wret, &wsamsg->dwFlags,
1447                        NULL, NULL);
1448       else
1449         res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &wret,
1450                            &wsamsg->dwFlags, wsamsg->name, &wsamsg->namelen,
1451                            NULL, NULL);
1452       if (!res)
1453         {
1454           ret += wret;
1455           if (!waitall)
1456             break;
1457           while (wret && wsacnt)
1458             {
1459               if (wsabuf->len > wret)
1460                 {
1461                   wsabuf->len -= wret;
1462                   wsabuf->buf += wret;
1463                   wret = 0;
1464                 }
1465               else
1466                 {
1467                   wret -= wsabuf->len;
1468                   ++wsabuf;
1469                   --wsacnt;
1470                 }
1471             }
1472           if (!wret)
1473             break;
1474         }
1475       else if (WSAGetLastError () != WSAEWOULDBLOCK)
1476         break;
1477     }
1478
1479   if (res)
1480     {
1481       /* According to SUSv3, errno isn't set in that case and no error
1482          condition is returned. */
1483       if (WSAGetLastError () == WSAEMSGSIZE)
1484         return ret + wret;
1485
1486       if (!ret)
1487         {
1488           /* ESHUTDOWN isn't defined for recv in SUSv3.  Simply EOF is returned
1489              in this case. */
1490           if (WSAGetLastError () == WSAESHUTDOWN)
1491             return 0;
1492
1493           set_winsock_errno ();
1494           return SOCKET_ERROR;
1495         }
1496     }
1497
1498   return ret;
1499 }
1500
1501 ssize_t
1502 fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
1503                            struct sockaddr *from, int *fromlen)
1504 {
1505   pthread_testcancel ();
1506
1507   WSABUF wsabuf = { len, (char *) ptr };
1508   WSAMSG wsamsg = { from, from && fromlen ? *fromlen : 0,
1509                     &wsabuf, 1,
1510                     { 0, NULL},
1511                     flags };
1512   ssize_t ret = recv_internal (&wsamsg);
1513   if (fromlen)
1514     *fromlen = wsamsg.namelen;
1515   return ret;
1516 }
1517
1518 ssize_t
1519 fhandler_socket::recvmsg (struct msghdr *msg, int flags)
1520 {
1521   pthread_testcancel ();
1522
1523   /* TODO: Descriptor passing on AF_LOCAL sockets. */
1524
1525   /* Disappointing but true:  Even if WSARecvMsg is supported, it's only
1526      supported for datagram and raw sockets. */
1527   if (!wincap.has_recvmsg () || get_socket_type () == SOCK_STREAM
1528       || get_addr_family () == AF_LOCAL)
1529     {
1530       msg->msg_controllen = 0;
1531       if (!CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
1532         msg->msg_flags = 0;
1533     }
1534
1535   WSABUF wsabuf[msg->msg_iovlen];
1536   WSABUF *wsaptr = wsabuf + msg->msg_iovlen;
1537   const struct iovec *iovptr = msg->msg_iov + msg->msg_iovlen;
1538   while (--wsaptr >= wsabuf)
1539     {
1540       wsaptr->len = (--iovptr)->iov_len;
1541       wsaptr->buf = (char *) iovptr->iov_base;
1542     }
1543   WSAMSG wsamsg = { (struct sockaddr *) msg->msg_name, msg->msg_namelen,
1544                     wsabuf, msg->msg_iovlen,
1545                     { msg->msg_controllen, (char *) msg->msg_control },
1546                     flags };
1547   ssize_t ret = recv_internal (&wsamsg);
1548   if (ret >= 0)
1549     {
1550       msg->msg_namelen = wsamsg.namelen;
1551       msg->msg_controllen = wsamsg.Control.len;
1552       if (!CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
1553         msg->msg_flags = wsamsg.dwFlags;
1554     }
1555   return ret;
1556 }
1557
1558 int
1559 fhandler_socket::write (const void *ptr, size_t len)
1560 {
1561   WSABUF wsabuf = { len, (char *) ptr };
1562   WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 };
1563   return send_internal (&wsamsg, 0);
1564 }
1565
1566 int
1567 fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
1568                          ssize_t tot)
1569 {
1570   WSABUF wsabuf[iovcnt];
1571   WSABUF *wsaptr = wsabuf;
1572   const struct iovec *iovptr = iov;
1573   for (int i = 0; i < iovcnt; ++i)
1574     {
1575       wsaptr->len = iovptr->iov_len;
1576       (wsaptr++)->buf = (char *) (iovptr++)->iov_base;
1577     }
1578   WSAMSG wsamsg = { NULL, 0, wsabuf, iovcnt, { 0, NULL}, 0 };
1579   return send_internal (&wsamsg, 0);
1580 }
1581
1582 inline ssize_t
1583 fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
1584 {
1585   int res = 0;
1586   DWORD ret = 0, err = 0, sum = 0, off = 0;
1587   WSABUF buf;
1588   bool use_sendmsg = false;
1589   DWORD wait_flags = flags & MSG_DONTWAIT;
1590   bool nosignal = !!(flags & MSG_NOSIGNAL);
1591
1592   flags &= (MSG_OOB | MSG_DONTROUTE);
1593   if (wsamsg->Control.len > 0)
1594     use_sendmsg = true;
1595   for (DWORD i = 0; i < wsamsg->dwBufferCount;
1596        off >= wsamsg->lpBuffers[i].len && (++i, off = 0))
1597     {
1598       /* CV 2009-12-02: Don't split datagram messages. */
1599       /* FIXME: Look for a way to split a message into the least number of
1600                 pieces to minimize the number of WsaSendTo calls. */
1601       if (get_socket_type () == SOCK_STREAM)
1602         {
1603           buf.buf = wsamsg->lpBuffers[i].buf + off;
1604           buf.len = wsamsg->lpBuffers[i].len - off;
1605           /* See net.cc:fdsock() and MSDN KB 823764 */
1606           if (buf.len >= (unsigned) wmem ())
1607             buf.len = (unsigned) wmem ();
1608         }
1609
1610       do
1611         {
1612           if (use_sendmsg)
1613             res = WSASendMsg (get_socket (), wsamsg, flags, &ret, NULL, NULL);
1614           else if (get_socket_type () == SOCK_STREAM)
1615             res = WSASendTo (get_socket (), &buf, 1, &ret, flags,
1616                              wsamsg->name, wsamsg->namelen, NULL, NULL);
1617           else
1618             res = WSASendTo (get_socket (), wsamsg->lpBuffers,
1619                              wsamsg->dwBufferCount, &ret, flags,
1620                              wsamsg->name, wsamsg->namelen, NULL, NULL);
1621           if (res && (err = WSAGetLastError ()) == WSAEWOULDBLOCK)
1622             {
1623               LOCK_EVENTS;
1624               wsock_events->events &= ~FD_WRITE;
1625               UNLOCK_EVENTS;
1626             }
1627         }
1628       while (res && err == WSAEWOULDBLOCK
1629              && !(res = wait_for_events (FD_WRITE | FD_CLOSE, wait_flags)));
1630
1631       if (!res)
1632         {
1633           off += ret;
1634           sum += ret;
1635           if (get_socket_type () != SOCK_STREAM)
1636             break;
1637         }
1638       else if (is_nonblocking () || err != WSAEWOULDBLOCK)
1639         break;
1640     }
1641
1642   if (sum)
1643     res = sum;
1644   else if (res == SOCKET_ERROR)
1645     {
1646       set_winsock_errno ();
1647
1648       /* Special handling for EPIPE and SIGPIPE.
1649
1650          EPIPE is generated if the local end has been shut down on a connection
1651          oriented socket.  In this case the process will also receive a SIGPIPE
1652          unless MSG_NOSIGNAL is set.  */
1653       if ((get_errno () == ECONNABORTED || get_errno () == ESHUTDOWN)
1654           && get_socket_type () == SOCK_STREAM)
1655         {
1656           set_errno (EPIPE);
1657           if (!nosignal)
1658             raise (SIGPIPE);
1659         }
1660     }
1661
1662   return res;
1663 }
1664
1665 ssize_t
1666 fhandler_socket::sendto (const void *ptr, size_t len, int flags,
1667                          const struct sockaddr *to, int tolen)
1668 {
1669   struct sockaddr_storage sst;
1670
1671   pthread_testcancel ();
1672
1673   if (to && get_inet_addr (to, tolen, &sst, &tolen) == SOCKET_ERROR)
1674     return SOCKET_ERROR;
1675
1676   WSABUF wsabuf = { len, (char *) ptr };
1677   WSAMSG wsamsg = { to ? (struct sockaddr *) &sst : NULL, tolen,
1678                     &wsabuf, 1,
1679                     { 0, NULL},
1680                     0 };
1681   return send_internal (&wsamsg, flags);
1682 }
1683
1684 int
1685 fhandler_socket::sendmsg (const struct msghdr *msg, int flags)
1686 {
1687   /* TODO: Descriptor passing on AF_LOCAL sockets. */
1688
1689   struct sockaddr_storage sst;
1690   int len = 0;
1691
1692   pthread_testcancel ();
1693
1694   if (msg->msg_name
1695       && get_inet_addr ((struct sockaddr *) msg->msg_name, msg->msg_namelen,
1696                         &sst, &len) == SOCKET_ERROR)
1697     return SOCKET_ERROR;
1698
1699   WSABUF wsabuf[msg->msg_iovlen];
1700   WSABUF *wsaptr = wsabuf;
1701   const struct iovec *iovptr = msg->msg_iov;
1702   for (int i = 0; i < msg->msg_iovlen; ++i)
1703     {
1704       wsaptr->len = iovptr->iov_len;
1705       (wsaptr++)->buf = (char *) (iovptr++)->iov_base;
1706     }
1707   WSAMSG wsamsg = { msg->msg_name ? (struct sockaddr *) &sst : NULL, len,
1708                     wsabuf, msg->msg_iovlen,
1709                     /* Disappointing but true:  Even if WSASendMsg is
1710                        supported, it's only supported for datagram and
1711                        raw sockets. */
1712                     { !wincap.has_sendmsg ()
1713                       || get_socket_type () == SOCK_STREAM
1714                       || get_addr_family () == AF_LOCAL
1715                       ? 0 : msg->msg_controllen, (char *) msg->msg_control },
1716                     0 };
1717   return send_internal (&wsamsg, flags);
1718 }
1719
1720 int
1721 fhandler_socket::shutdown (int how)
1722 {
1723   int res = ::shutdown (get_socket (), how);
1724
1725   /* Linux allows to call shutdown for any socket, even if it's not connected.
1726      This also disables to call accept on this socket, if shutdown has been
1727      called with the SHUT_RD or SHUT_RDWR parameter.  In contrast, WinSock
1728      only allows to call shutdown on a connected socket.  The accept function
1729      is in no way affected.  So, what we do here is to fake success, and to
1730      change the event settings so that an FD_CLOSE event is triggered for the
1731      calling Cygwin function.  The evaluate_events method handles the call
1732      from accept specially to generate a Linux-compatible behaviour. */
1733   if (res && WSAGetLastError () != WSAENOTCONN)
1734     set_winsock_errno ();
1735   else
1736     {
1737       res = 0;
1738       switch (how)
1739         {
1740         case SHUT_RD:
1741           saw_shutdown_read (true);
1742           wsock_events->events |= FD_CLOSE;
1743           SetEvent (wsock_evt);
1744           break;
1745         case SHUT_WR:
1746           saw_shutdown_write (true);
1747           break;
1748         case SHUT_RDWR:
1749           saw_shutdown_read (true);
1750           saw_shutdown_write (true);
1751           wsock_events->events |= FD_CLOSE;
1752           SetEvent (wsock_evt);
1753           break;
1754         }
1755     }
1756   return res;
1757 }
1758
1759 int
1760 fhandler_socket::close ()
1761 {
1762   int res = 0;
1763   /* TODO: CV - 2008-04-16.  Lingering disabled.  The original problem
1764      could be no longer reproduced on NT4, XP, 2K8.  Any return of a
1765      spurious "Connection reset by peer" *could* be caused by disabling
1766      the linger code here... */
1767 #if 0
1768   /* HACK to allow a graceful shutdown even if shutdown() hasn't been
1769      called by the application. Note that this isn't the ultimate
1770      solution but it helps in many cases. */
1771   struct linger linger;
1772   linger.l_onoff = 1;
1773   linger.l_linger = 240; /* secs. default 2MSL value according to MSDN. */
1774   setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
1775               (const char *)&linger, sizeof linger);
1776 #endif
1777   release_events ();
1778   while ((res = closesocket (get_socket ())) != 0)
1779     {
1780       if (WSAGetLastError () != WSAEWOULDBLOCK)
1781         {
1782           set_winsock_errno ();
1783           res = -1;
1784           break;
1785         }
1786       if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
1787         {
1788           set_errno (EINTR);
1789           res = -1;
1790           break;
1791         }
1792       WSASetLastError (0);
1793     }
1794
1795   debug_printf ("%d = fhandler_socket::close()", res);
1796   return res;
1797 }
1798
1799 /* Definitions of old ifreq stuff used prior to Cygwin 1.7.0. */
1800 #define OLD_SIOCGIFFLAGS    _IOW('s', 101, struct __old_ifreq)
1801 #define OLD_SIOCGIFADDR     _IOW('s', 102, struct __old_ifreq)
1802 #define OLD_SIOCGIFBRDADDR  _IOW('s', 103, struct __old_ifreq)
1803 #define OLD_SIOCGIFNETMASK  _IOW('s', 104, struct __old_ifreq)
1804 #define OLD_SIOCGIFHWADDR   _IOW('s', 105, struct __old_ifreq)
1805 #define OLD_SIOCGIFMETRIC   _IOW('s', 106, struct __old_ifreq)
1806 #define OLD_SIOCGIFMTU      _IOW('s', 107, struct __old_ifreq)
1807 #define OLD_SIOCGIFINDEX    _IOW('s', 108, struct __old_ifreq)
1808
1809 #define CONV_OLD_TO_NEW_SIO(old) (((old)&0xff00ffff)|(((long)sizeof(struct ifreq)&IOCPARM_MASK)<<16))
1810
1811 struct __old_ifreq {
1812 #define __OLD_IFNAMSIZ  16
1813   union {
1814     char    ifrn_name[__OLD_IFNAMSIZ];   /* if name, e.g. "en0" */
1815   } ifr_ifrn;
1816
1817   union {
1818     struct  sockaddr ifru_addr;
1819     struct  sockaddr ifru_broadaddr;
1820     struct  sockaddr ifru_netmask;
1821     struct  sockaddr ifru_hwaddr;
1822     short   ifru_flags;
1823     int     ifru_metric;
1824     int     ifru_mtu;
1825     int     ifru_ifindex;
1826   } ifr_ifru;
1827 };
1828
1829 int
1830 fhandler_socket::ioctl (unsigned int cmd, void *p)
1831 {
1832   extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */
1833   int res;
1834   struct ifconf ifc, *ifcp;
1835   struct ifreq *ifrp;
1836
1837   switch (cmd)
1838     {
1839     case SIOCGIFCONF:
1840       ifcp = (struct ifconf *) p;
1841       if (!ifcp)
1842         {
1843           set_errno (EINVAL);
1844           return -1;
1845         }
1846       if (CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ)
1847         {
1848           ifc.ifc_len = ifcp->ifc_len / sizeof (struct __old_ifreq)
1849                         * sizeof (struct ifreq);
1850           ifc.ifc_buf = (caddr_t) alloca (ifc.ifc_len);
1851         }
1852       else
1853         {
1854           ifc.ifc_len = ifcp->ifc_len;
1855           ifc.ifc_buf = ifcp->ifc_buf;
1856         }
1857       res = get_ifconf (&ifc, cmd);
1858       if (res)
1859         debug_printf ("error in get_ifconf");
1860       if (CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ)
1861         {
1862           struct __old_ifreq *ifr = (struct __old_ifreq *) ifcp->ifc_buf;
1863           for (ifrp = ifc.ifc_req;
1864                (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
1865                ++ifrp, ++ifr)
1866             {
1867               memcpy (&ifr->ifr_ifrn, &ifrp->ifr_ifrn, sizeof ifr->ifr_ifrn);
1868               ifr->ifr_name[__OLD_IFNAMSIZ - 1] = '\0';
1869               memcpy (&ifr->ifr_ifru, &ifrp->ifr_ifru, sizeof ifr->ifr_ifru);
1870             }
1871           ifcp->ifc_len = ifc.ifc_len / sizeof (struct ifreq)
1872                           * sizeof (struct __old_ifreq);
1873         }
1874       else
1875         ifcp->ifc_len = ifc.ifc_len;
1876       break;
1877     case OLD_SIOCGIFFLAGS:
1878     case OLD_SIOCGIFADDR:
1879     case OLD_SIOCGIFBRDADDR:
1880     case OLD_SIOCGIFNETMASK:
1881     case OLD_SIOCGIFHWADDR:
1882     case OLD_SIOCGIFMETRIC:
1883     case OLD_SIOCGIFMTU:
1884     case OLD_SIOCGIFINDEX:
1885       cmd = CONV_OLD_TO_NEW_SIO (cmd);
1886       /*FALLTHRU*/
1887     case SIOCGIFFLAGS:
1888     case SIOCGIFBRDADDR:
1889     case SIOCGIFNETMASK:
1890     case SIOCGIFADDR:
1891     case SIOCGIFHWADDR:
1892     case SIOCGIFMETRIC:
1893     case SIOCGIFMTU:
1894     case SIOCGIFINDEX:
1895     case SIOCGIFFRNDLYNAM:
1896     case SIOCGIFDSTADDR:
1897       {
1898         if (!p)
1899           {
1900             debug_printf ("ifr == NULL");
1901             set_errno (EINVAL);
1902             return -1;
1903           }
1904
1905         if (cmd > SIOCGIFINDEX && CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ)
1906           {
1907             debug_printf ("cmd not supported on this platform");
1908             set_errno (EINVAL);
1909             return -1;
1910           }
1911         ifc.ifc_len = 64 * sizeof (struct ifreq);
1912         ifc.ifc_buf = (caddr_t) alloca (ifc.ifc_len);
1913         if (cmd == SIOCGIFFRNDLYNAM)
1914           {
1915             struct ifreq_frndlyname *iff = (struct ifreq_frndlyname *)
1916                                 alloca (64 * sizeof (struct ifreq_frndlyname));
1917             for (int i = 0; i < 64; ++i)
1918               ifc.ifc_req[i].ifr_frndlyname = &iff[i];
1919           }
1920
1921         res = get_ifconf (&ifc, cmd);
1922         if (res)
1923           {
1924             debug_printf ("error in get_ifconf");
1925             break;
1926           }
1927
1928         if (CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ)
1929           {
1930             struct __old_ifreq *ifr = (struct __old_ifreq *) p;
1931             debug_printf ("    name: %s", ifr->ifr_name);
1932             for (ifrp = ifc.ifc_req;
1933                  (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
1934                  ++ifrp)
1935               {
1936                 debug_printf ("testname: %s", ifrp->ifr_name);
1937                 if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
1938                   {
1939                     memcpy (&ifr->ifr_ifru, &ifrp->ifr_ifru,
1940                             sizeof ifr->ifr_ifru);
1941                     break;
1942                   }
1943               }
1944           }
1945         else
1946           {
1947             struct ifreq *ifr = (struct ifreq *) p;
1948             debug_printf ("    name: %s", ifr->ifr_name);
1949             for (ifrp = ifc.ifc_req;
1950                  (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
1951                  ++ifrp)
1952               {
1953                 debug_printf ("testname: %s", ifrp->ifr_name);
1954                 if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
1955                   {
1956                     if (cmd == SIOCGIFFRNDLYNAM)
1957                       /* The application has to care for the space. */
1958                       memcpy (ifr->ifr_frndlyname, ifrp->ifr_frndlyname,
1959                               sizeof (struct ifreq_frndlyname));
1960                     else
1961                       memcpy (&ifr->ifr_ifru, &ifrp->ifr_ifru,
1962                               sizeof ifr->ifr_ifru);
1963                     break;
1964                   }
1965               }
1966           }
1967         if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
1968           {
1969             set_errno (EINVAL);
1970             return -1;
1971           }
1972         break;
1973       }
1974     case FIOASYNC:
1975       res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
1976               *(int *) p ? ASYNC_MASK : 0);
1977       syscall_printf ("Async I/O on socket %s",
1978               *(int *) p ? "started" : "cancelled");
1979       async_io (*(int *) p != 0);
1980       /* If async_io is switched off, revert the event handling. */
1981       if (*(int *) p == 0)
1982         WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK);
1983       break;
1984     case FIONREAD:
1985       res = ioctlsocket (get_socket (), FIONREAD, (unsigned long *) p);
1986       if (res == SOCKET_ERROR)
1987         set_winsock_errno ();
1988       break;
1989     default:
1990       /* Sockets are always non-blocking internally.  So we just note the
1991          state here. */
1992       if (cmd == FIONBIO)
1993         {
1994           syscall_printf ("socket is now %sblocking",
1995                             *(int *) p ? "non" : "");
1996           set_nonblocking (*(int *) p);
1997           res = 0;
1998         }
1999       else
2000         res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);
2001       break;
2002     }
2003   syscall_printf ("%d = ioctl_socket(%x, %x)", res, cmd, p);
2004   return res;
2005 }
2006
2007 int
2008 fhandler_socket::fcntl (int cmd, void *arg)
2009 {
2010   int res = 0;
2011   int request, current;
2012
2013   switch (cmd)
2014     {
2015     case F_SETOWN:
2016       {
2017         pid_t pid = (pid_t) arg;
2018         LOCK_EVENTS;
2019         wsock_events->owner = pid;
2020         UNLOCK_EVENTS;
2021         debug_printf ("owner set to %d", pid);
2022       }
2023       break;
2024     case F_GETOWN:
2025       res = wsock_events->owner;
2026       break;
2027     case F_SETFL:
2028       {
2029         /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
2030            Set only the flag that has been passed in.  If both are set, just
2031            record O_NONBLOCK.   */
2032         int new_flags = (int) arg & O_NONBLOCK_MASK;
2033         if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
2034           new_flags = O_NONBLOCK;
2035         current = get_flags () & O_NONBLOCK_MASK;
2036         request = new_flags ? 1 : 0;
2037         if (!!current != !!new_flags && (res = ioctl (FIONBIO, &request)))
2038           break;
2039         set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags);
2040         break;
2041       }
2042     default:
2043       res = fhandler_base::fcntl (cmd, arg);
2044       break;
2045     }
2046   return res;
2047 }
2048
2049 void
2050 fhandler_socket::set_close_on_exec (bool val)
2051 {
2052   set_no_inheritance (wsock_mtx, val);
2053   set_no_inheritance (wsock_evt, val);
2054   if (need_fixup_before ())
2055     {
2056       close_on_exec (val);
2057       debug_printf ("set close_on_exec for %s to %d", get_name (), val);
2058     }
2059   else
2060     fhandler_base::set_close_on_exec (val);
2061 }
2062
2063 void
2064 fhandler_socket::set_sun_path (const char *path)
2065 {
2066   sun_path = path ? cstrdup (path) : NULL;
2067 }
2068
2069 void
2070 fhandler_socket::set_peer_sun_path (const char *path)
2071 {
2072   peer_sun_path = path ? cstrdup (path) : NULL;
2073 }
2074
2075 int
2076 fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid)
2077 {
2078   if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
2079     {
2080       set_errno (EINVAL);
2081       return -1;
2082     }
2083   if (connect_state () != connected)
2084     {
2085       set_errno (ENOTCONN);
2086       return -1;
2087     }
2088   if (sec_peer_pid == (pid_t) 0)
2089     {
2090       set_errno (ENOTCONN);     /* Usually when calling getpeereid on
2091                                    accepting (instead of accepted) socket. */
2092       return -1;
2093     }
2094
2095   myfault efault;
2096   if (efault.faulted (EFAULT))
2097     return -1;
2098   if (pid)
2099     *pid = sec_peer_pid;
2100   if (euid)
2101     *euid = sec_peer_uid;
2102   if (egid)
2103     *egid = sec_peer_gid;
2104   return 0;
2105 }