OSDN Git Service

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