OSDN Git Service

563db53470c106a7f2aa1ea39d1026857dc49197
[pf3gnuchains/sourceware.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 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/socket.h>
17 #include <sys/un.h>
18 #include <sys/uio.h>
19 #include <asm/byteorder.h>
20
21 #include <stdlib.h>
22 #define USE_SYS_TYPES_FD_SET
23 #include <winsock2.h>
24 #include "cygerrno.h"
25 #include "security.h"
26 #include "cygwin/version.h"
27 #include "perprocess.h"
28 #include "path.h"
29 #include "fhandler.h"
30 #include "pinfo.h"
31 #include "dtable.h"
32 #include "cygheap.h"
33 #include "sigproc.h"
34 #include "cygthread.h"
35 #include "select.h"
36 #include "wininfo.h"
37 #include <unistd.h>
38 #include <sys/acl.h>
39 #include "cygtls.h"
40
41 #define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
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 /* cygwin internal: map sockaddr into internet domain address */
51 static int
52 get_inet_addr (const struct sockaddr *in, int inlen,
53                struct sockaddr_in *out, int *outlen,
54                int *type = NULL, int *secret = NULL)
55 {
56   int secret_buf [4];
57   int* secret_ptr = (secret ? : secret_buf);
58
59   if (in->sa_family == AF_INET)
60     {
61       *out = * (struct sockaddr_in *)in;
62       *outlen = inlen;
63       return 1;
64     }
65   else if (in->sa_family == AF_LOCAL)
66     {
67       path_conv pc (in->sa_data, PC_SYM_FOLLOW);
68       if (pc.error)
69         {
70           set_errno (pc.error);
71           return 0;
72         }
73       if (!pc.exists ())
74         {
75           set_errno (ENOENT);
76           return 0;
77         }
78       if (!pc.issocket ())
79         {
80           set_errno (EBADF);
81           return 0;
82         }
83       HANDLE fh = CreateFile (pc, GENERIC_READ, wincap.shared (), &sec_none,
84                               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
85       if (fh == INVALID_HANDLE_VALUE)
86         {
87           __seterrno ();
88           return 0;
89         }
90       int ret = 0;
91       DWORD len = 0;
92       char buf[128];
93       memset (buf, 0, sizeof buf);
94       if (ReadFile (fh, buf, 128, &len, 0))
95         {
96           struct sockaddr_in sin;
97           char ctype;
98           sin.sin_family = AF_INET;
99           sscanf (buf + strlen (SOCKET_COOKIE), "%hu %c %08x-%08x-%08x-%08x",
100                   &sin.sin_port,
101                   &ctype,
102                   secret_ptr, secret_ptr + 1, secret_ptr + 2, secret_ptr + 3);
103           sin.sin_port = htons (sin.sin_port);
104           sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
105           *out = sin;
106           *outlen = sizeof sin;
107           if (type)
108             *type = (ctype == 's' ? SOCK_STREAM :
109                      ctype == 'd' ? SOCK_DGRAM
110                                   : 0);
111           ret = 1;
112         }
113       else
114         __seterrno ();
115       CloseHandle (fh);
116       return ret;
117     }
118   else
119     {
120       set_errno (EAFNOSUPPORT);
121       return 0;
122     }
123 }
124
125 /**********************************************************************/
126 /* fhandler_socket */
127
128 fhandler_socket::fhandler_socket () :
129   fhandler_base (),
130   sun_path (NULL),
131   status ()
132 {
133   need_fork_fixup (true);
134   prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF,
135                                                  sizeof (WSAPROTOCOL_INFOA));
136 #if 0
137   if (pc.is_fs_special ())
138     {
139       fhandler_socket * fhs = (fhandler_socket *) fh;
140       fhs->set_addr_family (AF_LOCAL);
141       fhs->set_sun_path (posix_path);
142     }
143 #endif
144 }
145
146 fhandler_socket::~fhandler_socket ()
147 {
148   if (prot_info_ptr)
149     cfree (prot_info_ptr);
150   if (sun_path)
151     cfree (sun_path);
152 }
153
154 char *
155 fhandler_socket::get_proc_fd_name (char *buf)
156 {
157   __small_sprintf (buf, "socket:[%d]", get_socket ());
158   return buf;
159 }
160
161 int
162 fhandler_socket::open (int flags, mode_t mode)
163 {
164   set_errno (ENXIO);
165   return 0;
166 }
167
168 void
169 fhandler_socket::af_local_set_sockpair_cred ()
170 {
171   sec_pid = sec_peer_pid = getpid ();
172   sec_uid = sec_peer_uid = geteuid32 ();
173   sec_gid = sec_peer_gid = getegid32 ();
174 }
175
176 void
177 fhandler_socket::af_local_setblocking (bool &async, bool &nonblocking)
178 {
179   async = async_io ();
180   nonblocking = is_nonblocking ();
181   if (async || nonblocking)
182   WSAAsyncSelect (get_socket (), winmsg, 0, 0);
183   unsigned long p = 0;
184   ioctlsocket (get_socket (), FIONBIO, &p);
185   set_nonblocking (false);
186   async_io (false);
187 }
188
189 void
190 fhandler_socket::af_local_unsetblocking (bool async, bool nonblocking)
191 {
192   if (nonblocking)
193     {
194       unsigned long p = 1;
195       ioctlsocket (get_socket (), FIONBIO, &p);
196       set_nonblocking (true);
197     }
198   if (async)
199     {
200       WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
201       async_io (true);
202     }
203 }
204
205 bool
206 fhandler_socket::af_local_recv_secret ()
207 {
208   int out[4] = { 0, 0, 0, 0 };
209   int rest = sizeof out;
210   char *ptr = (char *) out;
211   while (rest > 0)
212     {
213       int ret = recvfrom (ptr, rest, 0, NULL, NULL);
214       if (ret <= 0)
215         break;
216       rest -= ret;
217       ptr += ret;
218     }
219   if (rest == 0)
220     {
221       debug_printf ("Received af_local secret: %08x-%08x-%08x-%08x",
222                     out[0], out[1], out[2], out[3]);
223       if (out[0] != connect_secret[0] || out[1] != connect_secret[1]
224           || out[2] != connect_secret[2] || out[3] != connect_secret[3])
225         {
226           debug_printf ("Receiving af_local secret mismatch");
227           return false;
228         }
229     }
230   else
231     debug_printf ("Receiving af_local secret failed");
232   return rest == 0;
233 }
234
235 bool
236 fhandler_socket::af_local_send_secret ()
237 {
238   int rest = sizeof connect_secret;
239   char *ptr = (char *) connect_secret;
240   while (rest > 0)
241     {
242       int ret = sendto (ptr, rest, 0, NULL, 0);
243       if (ret <= 0)
244         break;
245       rest -= ret;
246       ptr += ret;
247     }
248   debug_printf ("Sending af_local secret %s", rest == 0 ? "succeeded"
249                                                         : "failed");
250   return rest == 0;
251 }
252
253 bool
254 fhandler_socket::af_local_recv_cred ()
255 {
256   struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
257   int rest = sizeof out;
258   char *ptr = (char *) &out;
259   while (rest > 0)
260     {
261       int ret = recvfrom (ptr, rest, 0, NULL, NULL);
262       if (ret <= 0)
263         break;
264       rest -= ret;
265       ptr += ret;
266     }
267   if (rest == 0)
268     {
269       debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
270                     out.pid, out.uid, out.gid);
271       sec_peer_pid = out.pid;
272       sec_peer_uid = out.uid;
273       sec_peer_gid = out.gid;
274     }
275   else
276     debug_printf ("Receiving eid credentials failed");
277   return rest == 0;
278 }
279
280 bool
281 fhandler_socket::af_local_send_cred ()
282 {
283   struct ucred in = { sec_pid, sec_uid, sec_gid };
284   int rest = sizeof in;
285   char *ptr = (char *) &in;
286   while (rest > 0)
287     {
288       int ret = sendto (ptr, rest, 0, NULL, 0);
289       if (ret <= 0)
290         break;
291       rest -= ret;
292       ptr += ret;
293     }
294   if (rest == 0)
295     debug_printf ("Sending eid credentials succeeded");
296   else
297     debug_printf ("Sending eid credentials failed");
298   return rest == 0;
299 }
300
301 int
302 fhandler_socket::af_local_connect ()
303 {
304   /* This keeps the test out of select. */
305   if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
306     return 0;
307
308   debug_printf ("af_local_connect called");
309   bool orig_async_io, orig_is_nonblocking;
310   af_local_setblocking (orig_async_io, orig_is_nonblocking);
311   if (!af_local_send_secret () || !af_local_recv_secret ()
312       || !af_local_send_cred () || !af_local_recv_cred ())
313     {
314       debug_printf ("accept from unauthorized server");
315       ::shutdown (get_socket (), SD_BOTH);
316       WSASetLastError (WSAECONNREFUSED);
317       return -1;
318     }
319   af_local_unsetblocking (orig_async_io, orig_is_nonblocking);
320   return 0;
321 }
322
323 int
324 fhandler_socket::af_local_accept ()
325 {
326   debug_printf ("af_local_accept called");
327   bool orig_async_io, orig_is_nonblocking;
328   af_local_setblocking (orig_async_io, orig_is_nonblocking);
329   if (!af_local_recv_secret () || !af_local_send_secret ()
330       || !af_local_recv_cred () || !af_local_send_cred ())
331     {
332       debug_printf ("connect from unauthorized client");
333       ::shutdown (get_socket (), SD_BOTH);
334       ::closesocket (get_socket ());
335       WSASetLastError (WSAECONNABORTED);
336       return -1;
337     }
338   af_local_unsetblocking (orig_async_io, orig_is_nonblocking);
339   return 0;
340 }
341
342 void
343 fhandler_socket::af_local_set_cred ()
344 {
345   sec_pid = getpid ();
346   sec_uid = geteuid32 ();
347   sec_gid = getegid32 ();
348   sec_peer_pid = (pid_t) 0;
349   sec_peer_uid = (__uid32_t) -1;
350   sec_peer_gid = (__gid32_t) -1;
351 }
352
353 void
354 fhandler_socket::af_local_copy (fhandler_socket *sock)
355 {
356   sock->connect_secret[0] = connect_secret[0];
357   sock->connect_secret[1] = connect_secret[1];
358   sock->connect_secret[2] = connect_secret[2];
359   sock->connect_secret[3] = connect_secret[3];
360   sock->sec_pid = sec_pid;
361   sock->sec_uid = sec_uid;
362   sock->sec_gid = sec_gid;
363   sock->sec_peer_pid = sec_peer_pid;
364   sock->sec_peer_uid = sec_peer_uid;
365   sock->sec_peer_gid = sec_peer_gid;
366 }
367
368 void
369 fhandler_socket::af_local_set_secret (char *buf)
370 {
371   if (!entropy_source)
372     {
373       void *buf = malloc (sizeof (fhandler_dev_random));
374       entropy_source = new (buf) fhandler_dev_random ();
375       entropy_source->dev () = *urandom_dev;
376     }
377   if (entropy_source &&
378       !entropy_source->open (O_RDONLY))
379     {
380       delete entropy_source;
381       entropy_source = NULL;
382     }
383   if (entropy_source)
384     {
385       size_t len = sizeof (connect_secret);
386       entropy_source->read (connect_secret, len);
387       if (len != sizeof (connect_secret))
388         bzero ((char*) connect_secret, sizeof (connect_secret));
389     }
390   __small_sprintf (buf, "%08x-%08x-%08x-%08x",
391                    connect_secret [0], connect_secret [1],
392                    connect_secret [2], connect_secret [3]);
393 }
394
395 void
396 fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
397 {
398   if (!winsock2_active)
399     {
400       fhandler_base::fixup_before_fork_exec (win_proc_id);
401       debug_printf ("Without Winsock 2.0");
402     }
403   else if (!WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr))
404     debug_printf ("WSADuplicateSocket went fine, sock %p, win_proc_id %d, prot_info_ptr %p",
405                   get_socket (), win_proc_id, prot_info_ptr);
406   else
407     {
408       debug_printf ("WSADuplicateSocket error, sock %p, win_proc_id %d, prot_info_ptr %p",
409                     get_socket (), win_proc_id, prot_info_ptr);
410       set_winsock_errno ();
411     }
412 }
413
414 extern "C" void __stdcall load_wsock32 ();
415 void
416 fhandler_socket::fixup_after_fork (HANDLE parent)
417 {
418   SOCKET new_sock;
419
420   debug_printf ("WSASocket begin, dwServiceFlags1=%d",
421                 prot_info_ptr->dwServiceFlags1);
422
423   if ((new_sock = WSASocketA (FROM_PROTOCOL_INFO,
424                                    FROM_PROTOCOL_INFO,
425                                    FROM_PROTOCOL_INFO,
426                                    prot_info_ptr, 0, 0)) == INVALID_SOCKET)
427     {
428       debug_printf ("WSASocket error");
429       set_io_handle ((HANDLE)INVALID_SOCKET);
430       set_winsock_errno ();
431     }
432   else if (!new_sock && !winsock2_active)
433     {
434       load_wsock32 ();
435       fhandler_base::fixup_after_fork (parent);
436       debug_printf ("Without Winsock 2.0");
437     }
438   else
439     {
440       debug_printf ("WSASocket went fine new_sock %p, old_sock %p", new_sock, get_io_handle ());
441       set_io_handle ((HANDLE) new_sock);
442     }
443 }
444
445 void
446 fhandler_socket::fixup_after_exec ()
447 {
448   debug_printf ("here");
449   if (!close_on_exec ())
450     fixup_after_fork (NULL);
451 #if 0
452   else if (!winsock2_active)
453     closesocket (get_socket ());
454 #endif
455 }
456
457 int
458 fhandler_socket::dup (fhandler_base *child, HANDLE from_proc)
459 {
460   HANDLE nh;
461
462   debug_printf ("here");
463   fhandler_socket *fhs = (fhandler_socket *) child;
464   fhs->addr_family = addr_family;
465   fhs->set_socket_type (get_socket_type ());
466   if (get_addr_family () == AF_LOCAL)
467     {
468       fhs->set_sun_path (get_sun_path ());
469       if (get_socket_type () == SOCK_STREAM)
470         {
471           fhs->sec_pid = sec_pid;
472           fhs->sec_uid = sec_uid;
473           fhs->sec_gid = sec_gid;
474           fhs->sec_peer_pid = sec_peer_pid;
475           fhs->sec_peer_uid = sec_peer_uid;
476           fhs->sec_peer_gid = sec_peer_gid;
477         }
478     }
479   fhs->connect_state (connect_state ());
480
481   if (winsock2_active && from_proc == hMainProc)
482     {
483       /* Since WSADuplicateSocket() fails on NT systems when the process
484          is currently impersonating a non-privileged account, we revert
485          to the original account before calling WSADuplicateSocket() and
486          switch back afterwards as it's also in fork().
487          If WSADuplicateSocket() still fails for some reason, we fall back
488          to DuplicateHandle(). */
489       WSASetLastError (0);
490       cygheap->user.deimpersonate ();
491       fhs->set_io_handle (get_io_handle ());
492       fhs->fixup_before_fork_exec (GetCurrentProcessId ());
493       cygheap->user.reimpersonate ();
494       if (!WSAGetLastError ())
495         {
496           fhs->fixup_after_fork (hMainProc);
497           if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
498             {
499               cygheap->fdtab.inc_need_fixup_before ();
500               return 0;
501             }
502         }
503       debug_printf ("WSADuplicateSocket failed, trying DuplicateHandle");
504     }
505
506   /* We don't call fhandler_base::dup here since that requires
507      having winsock called from fhandler_base and it creates only
508      inheritable sockets which is wrong for winsock2. */
509
510   if (!DuplicateHandle (from_proc, get_io_handle (), hMainProc, &nh, 0,
511                         !winsock2_active, DUPLICATE_SAME_ACCESS))
512     {
513       system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
514       __seterrno ();
515       return -1;
516     }
517   VerifyHandle (nh);
518   fhs->set_io_handle (nh);
519   cygheap->fdtab.inc_need_fixup_before ();
520   return 0;
521 }
522
523 int __stdcall
524 fhandler_socket::fstat (struct __stat64 *buf)
525 {
526   int res;
527   if (get_device () == FH_UNIX)
528     {
529       res = fhandler_base::fstat_fs (buf);
530       if (!res)
531         {
532           buf->st_mode = (buf->st_mode & ~S_IFMT) | S_IFSOCK;
533         }
534     }
535   else
536     {
537       res = fhandler_base::fstat (buf);
538       if (!res)
539         {
540           buf->st_dev = 0;
541           buf->st_ino = (__ino64_t) ((DWORD) get_handle ());
542           buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO;
543         }
544     }
545   return res;
546 }
547
548 int
549 fhandler_socket::fchmod (mode_t mode)
550 {
551   if (get_device () == FH_UNIX)
552     {
553       fhandler_disk_file fh (pc);
554       fh.get_device () = FH_FS;
555       int ret = fh.fchmod (mode);
556       SetFileAttributes (pc, GetFileAttributes (pc) | FILE_ATTRIBUTE_SYSTEM);
557       return ret;
558     }
559   return 0;
560 }
561
562 int
563 fhandler_socket::fchown (__uid32_t uid, __gid32_t gid)
564 {
565   if (get_device () == FH_UNIX)
566     {
567       fhandler_disk_file fh (pc);
568       return fh.fchown (uid, gid);
569     }
570   return 0;
571 }
572
573 int
574 fhandler_socket::facl (int cmd, int nentries, __aclent32_t *aclbufp)
575 {
576   if (get_device () == FH_UNIX)
577     {
578       fhandler_disk_file fh (pc);
579       return fh.facl (cmd, nentries, aclbufp);
580     }
581   return fhandler_base::facl (cmd, nentries, aclbufp);
582 }
583
584 int
585 fhandler_socket::link (const char *newpath)
586 {
587   if (get_device () == FH_UNIX)
588     {
589       fhandler_disk_file fh (pc);
590       return fh.link (newpath);
591     }
592   return fhandler_base::link (newpath);
593 }
594
595 int
596 fhandler_socket::bind (const struct sockaddr *name, int namelen)
597 {
598   int res = -1;
599
600   if (name->sa_family == AF_LOCAL)
601     {
602 #define un_addr ((struct sockaddr_un *) name)
603       struct sockaddr_in sin;
604       int len = sizeof sin;
605
606       if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
607         {
608           set_errno (ENAMETOOLONG);
609           goto out;
610         }
611       sin.sin_family = AF_INET;
612       sin.sin_port = 0;
613       sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
614       if (::bind (get_socket (), (sockaddr *) &sin, len))
615         {
616           syscall_printf ("AF_LOCAL: bind failed %d", get_errno ());
617           set_winsock_errno ();
618           goto out;
619         }
620       if (::getsockname (get_socket (), (sockaddr *) &sin, &len))
621         {
622           syscall_printf ("AF_LOCAL: getsockname failed %d", get_errno ());
623           set_winsock_errno ();
624           goto out;
625         }
626
627       sin.sin_port = ntohs (sin.sin_port);
628       debug_printf ("AF_LOCAL: socket bound to port %u", sin.sin_port);
629
630       path_conv pc (un_addr->sun_path, PC_SYM_FOLLOW);
631       if (pc.error)
632         {
633           set_errno (pc.error);
634           goto out;
635         }
636       if (pc.exists ())
637         {
638           set_errno (EADDRINUSE);
639           goto out;
640         }
641       mode_t mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask;
642       DWORD attr = FILE_ATTRIBUTE_SYSTEM;
643       if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
644         attr |= FILE_ATTRIBUTE_READONLY;
645       SECURITY_ATTRIBUTES sa = sec_none;
646       security_descriptor sd;
647       if (allow_ntsec && pc.has_acls ())
648         set_security_attribute (mode, &sa, sd);
649       HANDLE fh = CreateFile (pc, GENERIC_WRITE, 0, &sa, CREATE_NEW, attr, 0);
650       if (fh == INVALID_HANDLE_VALUE)
651         {
652           if (GetLastError () == ERROR_ALREADY_EXISTS)
653             set_errno (EADDRINUSE);
654           else
655             __seterrno ();
656         }
657
658       char buf[sizeof (SOCKET_COOKIE) + 80];
659       __small_sprintf (buf, "%s%u %c ", SOCKET_COOKIE, sin.sin_port, get_socket_type () == SOCK_STREAM ? 's' : get_socket_type () == SOCK_DGRAM ? 'd' : '-');
660       af_local_set_secret (strchr (buf, '\0'));
661       DWORD blen = strlen (buf) + 1;
662       if (!WriteFile (fh, buf, blen, &blen, 0))
663         {
664           __seterrno ();
665           CloseHandle (fh);
666           DeleteFile (pc);
667         }
668       else
669         {
670           CloseHandle (fh);
671           set_sun_path (un_addr->sun_path);
672           res = 0;
673         }
674 #undef un_addr
675     }
676   else if (::bind (get_socket (), name, namelen))
677     set_winsock_errno ();
678   else
679     res = 0;
680
681 out:
682   return res;
683 }
684
685 int
686 fhandler_socket::connect (const struct sockaddr *name, int namelen)
687 {
688   int res = -1;
689   bool in_progress = false;
690   struct sockaddr_in sin;
691   DWORD err;
692   int type;
693
694   if (!get_inet_addr (name, namelen, &sin, &namelen, &type, connect_secret))
695     return -1;
696
697   if (get_addr_family () == AF_LOCAL && get_socket_type () != type)
698     {
699       WSASetLastError (WSAEPROTOTYPE);
700       set_winsock_errno ();
701       return -1;
702     }
703
704   res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
705
706   if (!res)
707     err = 0;
708   else
709     {
710       err = WSAGetLastError ();
711       /* Special handling for connect to return the correct error code
712          when called on a non-blocking socket. */
713       if (is_nonblocking ())
714         {
715           if (err == WSAEWOULDBLOCK || err == WSAEALREADY)
716             in_progress = true;
717
718           if (err == WSAEWOULDBLOCK)
719             WSASetLastError (err = WSAEINPROGRESS);
720           else if (err == WSAEINVAL)
721             WSASetLastError (err = WSAEISCONN);
722         }
723       set_winsock_errno ();
724     }
725
726   if (get_addr_family () == AF_LOCAL && (!res || in_progress))
727     set_sun_path (name->sa_data);
728
729   if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
730     {
731       af_local_set_cred (); /* Don't move into af_local_connect since
732                                af_local_connect is called from select,
733                                possibly running under another identity. */
734       if (!res && af_local_connect ())
735         {
736           set_winsock_errno ();
737           return -1;
738         }
739     }
740
741   if (err == WSAEINPROGRESS || err == WSAEALREADY)
742     connect_state (connect_pending);
743   else if (err)
744     connect_state (connect_failed);
745   else
746     connect_state (connected);
747
748   return res;
749 }
750
751 int
752 fhandler_socket::listen (int backlog)
753 {
754   int res = ::listen (get_socket (), backlog);
755   if (res)
756     set_winsock_errno ();
757   else
758     {
759       if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
760         af_local_set_cred ();
761       connect_state (connected);
762     }
763   return res;
764 }
765
766 int
767 fhandler_socket::accept (struct sockaddr *peer, int *len)
768 {
769   int res = -1;
770
771   /* Allows NULL peer and len parameters. */
772   struct sockaddr_in peer_dummy;
773   int len_dummy;
774   if (!peer)
775     peer = (struct sockaddr *) &peer_dummy;
776   if (!len)
777     {
778       len_dummy = sizeof (struct sockaddr_in);
779       len = &len_dummy;
780     }
781
782   /* accept on NT fails if len < sizeof (sockaddr_in)
783    * some programs set len to
784    * sizeof (name.sun_family) + strlen (name.sun_path) for UNIX domain
785    */
786   if (len && ((unsigned) *len < sizeof (struct sockaddr_in)))
787     *len = sizeof (struct sockaddr_in);
788
789   res = ::accept (get_socket (), peer, len);
790
791   if (res == (int) INVALID_SOCKET)
792     set_winsock_errno ();
793   else
794     {
795       cygheap_fdnew res_fd;
796       if (res_fd >= 0 && fdsock (res_fd, &dev (), res))
797         {
798           fhandler_socket *sock = (fhandler_socket *) res_fd;
799           sock->set_addr_family (get_addr_family ());
800           sock->set_socket_type (get_socket_type ());
801           sock->async_io (async_io ());
802           sock->set_nonblocking (is_nonblocking ());
803           if (get_addr_family () == AF_LOCAL)
804             {
805               sock->set_sun_path (get_sun_path ());
806               if (get_socket_type () == SOCK_STREAM)
807                 {
808                   /* Don't forget to copy credentials from accepting
809                      socket to accepted socket and start transaction
810                      on accepted socket! */
811                   af_local_copy (sock);
812                   res = sock->af_local_accept ();
813                   if (res == -1)
814                     {
815                       res_fd.release ();
816                       set_winsock_errno ();
817                       goto out;
818                     }
819                 }
820             }
821           sock->connect_state (connected);
822           res = res_fd;
823         }
824       else
825         {
826           closesocket (res);
827           res = -1;
828         }
829     }
830
831 out:
832   debug_printf ("res %d", res);
833   return res;
834 }
835
836 int
837 fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
838 {
839   int res = -1;
840
841   if (get_addr_family () == AF_LOCAL)
842     {
843       struct sockaddr_un *sun = (struct sockaddr_un *) name;
844       memset (sun, 0, *namelen);
845       sun->sun_family = AF_LOCAL;
846
847       if (!get_sun_path ())
848         sun->sun_path[0] = '\0';
849       else
850         /* According to SUSv2 "If the actual length of the address is
851            greater than the length of the supplied sockaddr structure, the
852            stored address will be truncated."  We play it save here so
853            that the path always has a trailing 0 even if it's truncated. */
854         strncpy (sun->sun_path, get_sun_path (),
855                  *namelen - sizeof *sun + sizeof sun->sun_path - 1);
856
857       *namelen = sizeof *sun - sizeof sun->sun_path
858                  + strlen (sun->sun_path) + 1;
859       res = 0;
860     }
861   else
862     {
863       res = ::getsockname (get_socket (), name, namelen);
864       if (res)
865         set_winsock_errno ();
866     }
867
868   return res;
869 }
870
871 int
872 fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
873 {
874   int res = ::getpeername (get_socket (), name, namelen);
875   if (res)
876     set_winsock_errno ();
877
878   return res;
879 }
880
881 bool
882 fhandler_socket::prepare (HANDLE &event, long event_mask)
883 {
884   WSASetLastError (0);
885   closed (false);
886   if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT)
887     {
888       debug_printf ("WSACreateEvent, %E");
889       return false;
890     }
891   if (WSAEventSelect (get_socket (), event, event_mask) == SOCKET_ERROR)
892     {
893       debug_printf ("WSAEventSelect, %E");
894       return false;
895     }
896   return true;
897 }
898
899 int
900 fhandler_socket::wait (HANDLE event, int flags)
901 {
902   int ret = SOCKET_ERROR;
903   int wsa_err = 0;
904   WSAEVENT ev[2] = { event, signal_arrived };
905   WSANETWORKEVENTS evts;
906
907   switch (WSAWaitForMultipleEvents (2, ev, FALSE, 10, FALSE))
908     {
909       case WSA_WAIT_TIMEOUT:
910         ret = 0;
911         break;
912       case WSA_WAIT_EVENT_0:
913         if (!WSAEnumNetworkEvents (get_socket (), event, &evts))
914           {
915             if (!evts.lNetworkEvents)
916               {
917                 ret = 0;
918                 break;
919               }
920             if (evts.lNetworkEvents & FD_OOB)
921               {
922                 if (evts.iErrorCode[FD_OOB_BIT])
923                   wsa_err = evts.iErrorCode[FD_OOB_BIT];
924                 else if (flags & MSG_OOB)
925                   ret = 0;
926                 else
927                   {
928                     raise (SIGURG);
929                     WSASetLastError (WSAEINTR);
930                     break;
931                   }
932               }
933             if (evts.lNetworkEvents & FD_READ)
934               {
935                 if (evts.iErrorCode[FD_READ_BIT])
936                   wsa_err = evts.iErrorCode[FD_READ_BIT];
937                 else
938                   ret = 0;
939               }
940             else if (evts.lNetworkEvents & FD_WRITE)
941               {
942                 if (evts.iErrorCode[FD_WRITE_BIT])
943                   wsa_err = evts.iErrorCode[FD_WRITE_BIT];
944                 else
945                   ret = 0;
946               }
947             if (evts.lNetworkEvents & FD_CLOSE)
948               {
949                 closed (true);
950                 if (!wsa_err)
951                   {
952                     if (evts.iErrorCode[FD_CLOSE_BIT])
953                       wsa_err = evts.iErrorCode[FD_CLOSE_BIT];
954                     else
955                       ret = 0;
956                   }
957               }
958             if (wsa_err)
959               WSASetLastError (wsa_err);
960           }
961         break;
962       case WSA_WAIT_EVENT_0 + 1:
963         WSASetLastError (WSAEINTR);
964         break;
965       default:
966         WSASetLastError (WSAEFAULT);
967         break;
968     }
969   return ret;
970 }
971
972 void
973 fhandler_socket::release (HANDLE event)
974 {
975   int last_err = WSAGetLastError ();
976   /* KB 168349: NT4 fails if the event parameter is not NULL. */
977   WSAEventSelect (get_socket (), NULL, 0);
978   WSACloseEvent (event);
979   unsigned long non_block = 0;
980   if (ioctlsocket (get_socket (), FIONBIO, &non_block))
981     debug_printf ("return to blocking failed: %d", WSAGetLastError ());
982   else
983     WSASetLastError (last_err);
984 }
985
986 int
987 fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
988                         ssize_t tot)
989 {
990   struct msghdr msg =
991     {
992       msg_name:         NULL,
993       msg_namelen:      0,
994       msg_iov:          (struct iovec *) iov, // const_cast
995       msg_iovlen:       iovcnt,
996       msg_control:      NULL,
997       msg_controllen:   0,
998       msg_flags:        0
999     };
1000
1001   return recvmsg (&msg, 0, tot);
1002 }
1003
1004 int
1005 fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
1006                            struct sockaddr *from, int *fromlen)
1007 {
1008   int res = SOCKET_ERROR;
1009   DWORD ret = 0;
1010
1011   flags &= MSG_WINMASK;
1012   if (!winsock2_active)
1013     ret = res = ::recvfrom (get_socket (),
1014                             (char *) ptr, len, flags,
1015                             from, fromlen);
1016   else
1017     {
1018       WSABUF wsabuf = { len, (char *) ptr };
1019
1020       if (is_nonblocking () || closed () || async_io ())
1021         res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret,
1022                            (DWORD *) &flags, from, fromlen, NULL, NULL);
1023       else
1024         {
1025           HANDLE evt;
1026           if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
1027             {
1028               do
1029                 {
1030                   DWORD lflags = (DWORD) flags;
1031                   res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, &lflags,
1032                                      from, fromlen, NULL, NULL);
1033                 }
1034               while (res == SOCKET_ERROR
1035                      && WSAGetLastError () == WSAEWOULDBLOCK
1036                      && !closed ()
1037                      && !(res = wait (evt, flags)));
1038               release (evt);
1039             }
1040         }
1041     }
1042
1043   if (res == SOCKET_ERROR)
1044     {
1045       /* According to SUSv3, errno isn't set in that case and no error
1046          condition is returned. */
1047       if (WSAGetLastError () == WSAEMSGSIZE)
1048         return len;
1049
1050       set_winsock_errno ();
1051     }
1052   else
1053     res = ret;
1054
1055   return res;
1056 }
1057
1058 int
1059 fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
1060 {
1061   if (get_addr_family () == AF_LOCAL)
1062     {
1063       /* On AF_LOCAL sockets the (fixed-size) name of the shared memory
1064          area used for descriptor passing is transmitted first.
1065          If this string is empty, no descriptors are passed and we can
1066          go ahead recv'ing the normal data blocks.  Otherwise start
1067          special handling for descriptor passing. */
1068       /*TODO*/
1069       if (CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
1070         ((struct OLD_msghdr *) msg)->msg_accrightslen = 0;
1071       else
1072         msg->msg_controllen = 0;
1073     }
1074
1075   struct iovec *const iov = msg->msg_iov;
1076   const int iovcnt = msg->msg_iovlen;
1077
1078   struct sockaddr *from = (struct sockaddr *) msg->msg_name;
1079   int *fromlen = from ? &msg->msg_namelen : NULL;
1080
1081   int res = SOCKET_ERROR;
1082
1083   if (!winsock2_active)
1084     {
1085       if (iovcnt == 1)
1086         res = recvfrom (iov->iov_base, iov->iov_len, flags, from, fromlen);
1087       else
1088         {
1089           if (tot == -1)        // i.e. if not pre-calculated by the caller.
1090             {
1091               tot = 0;
1092               const struct iovec *iovptr = iov + iovcnt;
1093               do
1094                 {
1095                   iovptr -= 1;
1096                   tot += iovptr->iov_len;
1097                 }
1098               while (iovptr != iov);
1099             }
1100
1101           char *buf = (char *) alloca (tot);
1102
1103           if (!buf)
1104             {
1105               set_errno (ENOMEM);
1106               res = SOCKET_ERROR;
1107             }
1108           else
1109             {
1110               res = recvfrom (buf, tot, flags, from, fromlen);
1111
1112               const struct iovec *iovptr = iov;
1113               int nbytes = res;
1114
1115               while (nbytes > 0)
1116                 {
1117                   const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
1118                   memcpy (iovptr->iov_base, buf, frag);
1119                   buf += frag;
1120                   iovptr += 1;
1121                   nbytes -= frag;
1122                 }
1123             }
1124         }
1125     }
1126   else
1127     {
1128       WSABUF wsabuf[iovcnt];
1129       unsigned long len = 0L;
1130
1131       {
1132         const struct iovec *iovptr = iov + iovcnt;
1133         WSABUF *wsaptr = wsabuf + iovcnt;
1134         do
1135           {
1136             iovptr -= 1;
1137             wsaptr -= 1;
1138             len += wsaptr->len = iovptr->iov_len;
1139             wsaptr->buf = (char *) iovptr->iov_base;
1140           }
1141         while (wsaptr != wsabuf);
1142       }
1143
1144       DWORD ret = 0;
1145
1146       if (is_nonblocking () || closed () || async_io ())
1147         res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
1148                            (DWORD *) &flags, from, fromlen, NULL, NULL);
1149       else
1150         {
1151           HANDLE evt;
1152           if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
1153             {
1154               do
1155                 {
1156                   DWORD lflags = (DWORD) flags;
1157                   res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
1158                                      &lflags, from, fromlen, NULL, NULL);
1159                 }
1160               while (res == SOCKET_ERROR
1161                      && WSAGetLastError () == WSAEWOULDBLOCK
1162                      && !closed ()
1163                      && !(res = wait (evt, flags)));
1164               release (evt);
1165             }
1166         }
1167
1168       if (res == SOCKET_ERROR)
1169         {
1170           /* According to SUSv3, errno isn't set in that case and no error
1171              condition is returned. */
1172           if (WSAGetLastError () == WSAEMSGSIZE)
1173             return len;
1174
1175           set_winsock_errno ();
1176         }
1177       else
1178         res = ret;
1179     }
1180
1181   return res;
1182 }
1183
1184 int
1185 fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
1186                          ssize_t tot)
1187 {
1188   struct msghdr msg =
1189     {
1190       msg_name:         NULL,
1191       msg_namelen:      0,
1192       msg_iov:          (struct iovec *) iov, // const_cast
1193       msg_iovlen:       iovcnt,
1194       msg_control:      NULL,
1195       msg_controllen:   0,
1196       msg_flags:        0
1197     };
1198
1199   return sendmsg (&msg, 0, tot);
1200 }
1201
1202 int
1203 fhandler_socket::sendto (const void *ptr, size_t len, int flags,
1204                          const struct sockaddr *to, int tolen)
1205 {
1206   struct sockaddr_in sin;
1207
1208   if (to && !get_inet_addr (to, tolen, &sin, &tolen))
1209     return SOCKET_ERROR;
1210
1211   int res = SOCKET_ERROR;
1212   DWORD ret = 0;
1213
1214   if (!winsock2_active)
1215     ret = res = ::sendto (get_socket (), (const char *) ptr, len,
1216                           flags & MSG_WINMASK,
1217                           (to ? (const struct sockaddr *) &sin : NULL), tolen);
1218   else
1219     {
1220       WSABUF wsabuf = { len, (char *) ptr };
1221
1222       if (is_nonblocking () || closed () || async_io ())
1223         res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
1224                          flags & MSG_WINMASK,
1225                          (to ? (const struct sockaddr *) &sin : NULL), tolen,
1226                          NULL, NULL);
1227       else
1228         {
1229           HANDLE evt;
1230           if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
1231             {
1232               do
1233                 {
1234                   res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
1235                                    flags & MSG_WINMASK,
1236                                    (to ? (const struct sockaddr *) &sin : NULL),
1237                                    tolen, NULL, NULL);
1238                 }
1239               while (res == SOCKET_ERROR
1240                      && WSAGetLastError () == WSAEWOULDBLOCK
1241                      && !(res = wait (evt, 0))
1242                      && !closed ());
1243               release (evt);
1244             }
1245         }
1246     }
1247
1248   if (res == SOCKET_ERROR)
1249     set_winsock_errno ();
1250   else
1251     res = ret;
1252
1253   /* Special handling for EPIPE and SIGPIPE.
1254
1255      EPIPE is generated if the local end has been shut down on a connection
1256      oriented socket.  In this case the process will also receive a SIGPIPE
1257      unless MSG_NOSIGNAL is set.  */
1258   if (res == SOCKET_ERROR && get_errno () == ESHUTDOWN
1259       && get_socket_type () == SOCK_STREAM)
1260     {
1261       set_errno (EPIPE);
1262       if (! (flags & MSG_NOSIGNAL))
1263         raise (SIGPIPE);
1264     }
1265
1266   return res;
1267 }
1268
1269 int
1270 fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
1271 {
1272   struct cmsghdr *cmsg;
1273   bool descriptors_inflight = false;
1274
1275   if (get_addr_family () == AF_LOCAL
1276       && get_socket_type () == SOCK_STREAM
1277       && msg->msg_controllen > 0)       /* Works for ancient msghdr, too. */
1278     {
1279       /* For AF_LOCAL/SOCK_STREAM sockets, if descriptors are given, start
1280          the special handling for descriptor passing.  Otherwise just
1281          transmit an empty string to tell the receiver that no
1282          descriptor passing is done. */
1283
1284       /* NOTE: SOCK_DGRAMs are usually allowed, but we can't support them
1285          unless credential passing works for SOCK_DGRAM sockets as well.
1286          OTOH, since DGRAMs can be easily discarded, they are not reliable
1287          and seldomly used anyway. */
1288
1289       struct msghdr lmsg;
1290
1291       union {
1292         struct cmsghdr cm;
1293         char control[CMSG_SPACE (sizeof (int))];
1294       } control_un;
1295       if (CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
1296         {
1297           memcpy (&lmsg, msg, sizeof *msg);
1298           lmsg.msg_control = (void *) control_un.control;
1299           lmsg.msg_controllen = sizeof control_un.control;
1300           lmsg.msg_flags = 0;
1301           cmsg = CMSG_FIRSTHDR (&lmsg);
1302           cmsg->cmsg_len = CMSG_LEN (sizeof (int));
1303           cmsg->cmsg_level = SOL_SOCKET;
1304           cmsg->cmsg_type = SCM_RIGHTS;
1305           *((int *) CMSG_DATA (cmsg)) =
1306                             *(int *) ((OLD_msghdr *) msg)->msg_accrights;
1307           msg = &lmsg;
1308         }
1309
1310       pinfo p (sec_peer_pid);
1311       if (!p)
1312         {
1313           set_errno (ENOTCONN);
1314           return SOCKET_ERROR;
1315         }
1316       for (cmsg = CMSG_FIRSTHDR (msg); cmsg; cmsg = CMSG_NXTHDR (msg, cmsg))
1317         {
1318           if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS)
1319             {
1320               set_errno (ENOTSUP);
1321               return SOCKET_ERROR;
1322             }
1323           int *fds = (int *) CMSG_DATA (cmsg);
1324           int cnt = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr)))
1325                     / sizeof (int);
1326           if (!p->send_descriptors (cnt, fds))
1327             return SOCKET_ERROR;
1328           descriptors_inflight = true;
1329         }
1330     }
1331
1332   struct iovec *const iov = msg->msg_iov;
1333   const int iovcnt = msg->msg_iovlen;
1334
1335   int res = SOCKET_ERROR;
1336
1337   if (!winsock2_active)
1338     {
1339       if (iovcnt == 1)
1340         res = sendto (iov->iov_base, iov->iov_len, flags,
1341                       (struct sockaddr *) msg->msg_name,
1342                       msg->msg_namelen);
1343       else
1344         {
1345           if (tot == -1)        // i.e. if not pre-calculated by the caller.
1346             {
1347               tot = 0;
1348               const struct iovec *iovptr = iov + iovcnt;
1349               do
1350                 {
1351                   iovptr -= 1;
1352                   tot += iovptr->iov_len;
1353                 }
1354               while (iovptr != iov);
1355             }
1356
1357           char *const buf = (char *) alloca (tot);
1358
1359           if (!buf)
1360             {
1361               set_errno (ENOMEM);
1362               res = SOCKET_ERROR;
1363             }
1364           else
1365             {
1366               char *bufptr = buf;
1367               const struct iovec *iovptr = iov;
1368               int nbytes = tot;
1369
1370               while (nbytes != 0)
1371                 {
1372                   const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
1373                   memcpy (bufptr, iovptr->iov_base, frag);
1374                   bufptr += frag;
1375                   iovptr += 1;
1376                   nbytes -= frag;
1377                 }
1378
1379               res = sendto (buf, tot, flags,
1380                             (struct sockaddr *) msg->msg_name,
1381                             msg->msg_namelen);
1382             }
1383         }
1384     }
1385   else
1386     {
1387       WSABUF wsabuf[iovcnt];
1388
1389       {
1390         const struct iovec *iovptr = iov + iovcnt;
1391         WSABUF *wsaptr = wsabuf + iovcnt;
1392         do
1393           {
1394             iovptr -= 1;
1395             wsaptr -= 1;
1396             wsaptr->len = iovptr->iov_len;
1397             wsaptr->buf = (char *) iovptr->iov_base;
1398           }
1399         while (wsaptr != wsabuf);
1400       }
1401
1402       DWORD ret = 0;
1403
1404       if (is_nonblocking () || closed () || async_io ())
1405         res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret,
1406                          flags, (struct sockaddr *) msg->msg_name,
1407                          msg->msg_namelen, NULL, NULL);
1408       else
1409         {
1410           HANDLE evt;
1411           if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
1412             {
1413               do
1414                 {
1415                   res = WSASendTo (get_socket (), wsabuf, iovcnt,
1416                                    &ret, flags,
1417                                    (struct sockaddr *) msg->msg_name,
1418                                    msg->msg_namelen, NULL, NULL);
1419                 }
1420               while (res == SOCKET_ERROR
1421                      && WSAGetLastError () == WSAEWOULDBLOCK
1422                      && !(res = wait (evt, 0))
1423                      && !closed ());
1424               release (evt);
1425             }
1426         }
1427
1428       if (res == SOCKET_ERROR)
1429         {
1430           set_winsock_errno ();
1431         }
1432       else
1433         res = ret;
1434     }
1435
1436   if (res == SOCKET_ERROR)
1437     {
1438       /* If sendmsg fails, destroy all inflight descriptors. */
1439       if (descriptors_inflight && WSAGetLastError () != WSAEWOULDBLOCK)
1440         {
1441           pinfo p (sec_peer_pid);
1442           if (p)
1443             p->destroy_inflight_descriptors ();
1444         }
1445
1446       /* Special handling for EPIPE and SIGPIPE.
1447
1448          EPIPE is generated if the local end has been shut down on a connection
1449          oriented socket.  In this case the process will also receive a SIGPIPE
1450          unless MSG_NOSIGNAL is set.  */
1451       if (get_errno () == ESHUTDOWN && get_socket_type () == SOCK_STREAM)
1452         {
1453           set_errno (EPIPE);
1454           if (! (flags & MSG_NOSIGNAL))
1455             raise (SIGPIPE);
1456         }
1457     }
1458
1459   return res;
1460 }
1461
1462 int
1463 fhandler_socket::shutdown (int how)
1464 {
1465   int res = ::shutdown (get_socket (), how);
1466
1467   if (res)
1468     set_winsock_errno ();
1469   else
1470     switch (how)
1471       {
1472       case SHUT_RD:
1473         saw_shutdown_read (true);
1474         break;
1475       case SHUT_WR:
1476         saw_shutdown_write (true);
1477         break;
1478       case SHUT_RDWR:
1479         saw_shutdown_read (true);
1480         saw_shutdown_write (true);
1481         break;
1482       }
1483   return res;
1484 }
1485
1486 int
1487 fhandler_socket::close ()
1488 {
1489   int res = 0;
1490
1491   /* HACK to allow a graceful shutdown even if shutdown() hasn't been
1492      called by the application. Note that this isn't the ultimate
1493      solution but it helps in many cases. */
1494   struct linger linger;
1495   linger.l_onoff = 1;
1496   linger.l_linger = 240; /* secs. default 2MSL value according to MSDN. */
1497   setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
1498               (const char *)&linger, sizeof linger);
1499
1500   while ((res = closesocket (get_socket ())) != 0)
1501     {
1502       if (WSAGetLastError () != WSAEWOULDBLOCK)
1503         {
1504           set_winsock_errno ();
1505           res = -1;
1506           break;
1507         }
1508       if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
1509         {
1510           set_errno (EINTR);
1511           res = -1;
1512           break;
1513         }
1514       WSASetLastError (0);
1515     }
1516
1517   debug_printf ("%d = fhandler_socket::close()", res);
1518   return res;
1519 }
1520
1521 int
1522 fhandler_socket::ioctl (unsigned int cmd, void *p)
1523 {
1524   extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */
1525   int res;
1526   struct ifconf ifc, *ifcp;
1527   struct ifreq *ifr, *ifrp;
1528
1529   switch (cmd)
1530     {
1531     case SIOCGIFCONF:
1532       ifcp = (struct ifconf *) p;
1533       if (!ifcp)
1534         {
1535           set_errno (EINVAL);
1536           return -1;
1537         }
1538       res = get_ifconf (ifcp, cmd);
1539       if (res)
1540         debug_printf ("error in get_ifconf");
1541       break;
1542     case SIOCGIFFLAGS:
1543       ifr = (struct ifreq *) p;
1544       if (ifr == 0)
1545         {
1546           set_errno (EINVAL);
1547           return -1;
1548         }
1549       ifr->ifr_flags = IFF_NOTRAILERS | IFF_UP | IFF_RUNNING;
1550       if (!strncmp(ifr->ifr_name, "lo", 2)
1551           || ntohl (((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr)
1552           == INADDR_LOOPBACK)
1553         ifr->ifr_flags |= IFF_LOOPBACK;
1554       else
1555         ifr->ifr_flags |= IFF_BROADCAST;
1556       res = 0;
1557       break;
1558     case SIOCGIFBRDADDR:
1559     case SIOCGIFNETMASK:
1560     case SIOCGIFADDR:
1561     case SIOCGIFHWADDR:
1562     case SIOCGIFMETRIC:
1563     case SIOCGIFMTU:
1564       {
1565         ifc.ifc_len = 2048;
1566         ifc.ifc_buf = (char *) alloca (2048);
1567
1568         ifr = (struct ifreq *) p;
1569         if (ifr == 0)
1570           {
1571             debug_printf ("ifr == NULL");
1572             set_errno (EINVAL);
1573             return -1;
1574           }
1575
1576         res = get_ifconf (&ifc, cmd);
1577         if (res)
1578           {
1579             debug_printf ("error in get_ifconf");
1580             break;
1581           }
1582
1583         debug_printf ("    name: %s", ifr->ifr_name);
1584         for (ifrp = ifc.ifc_req;
1585              (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
1586              ++ifrp)
1587           {
1588             debug_printf ("testname: %s", ifrp->ifr_name);
1589             if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
1590               {
1591                 switch (cmd)
1592                   {
1593                   case SIOCGIFADDR:
1594                     ifr->ifr_addr = ifrp->ifr_addr;
1595                     break;
1596                   case SIOCGIFBRDADDR:
1597                     ifr->ifr_broadaddr = ifrp->ifr_broadaddr;
1598                     break;
1599                   case SIOCGIFNETMASK:
1600                     ifr->ifr_netmask = ifrp->ifr_netmask;
1601                     break;
1602                   case SIOCGIFHWADDR:
1603                     ifr->ifr_hwaddr = ifrp->ifr_hwaddr;
1604                     break;
1605                   case SIOCGIFMETRIC:
1606                     ifr->ifr_metric = ifrp->ifr_metric;
1607                     break;
1608                   case SIOCGIFMTU:
1609                     ifr->ifr_mtu = ifrp->ifr_mtu;
1610                     break;
1611                   }
1612                 break;
1613               }
1614           }
1615         if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
1616           {
1617             set_errno (EINVAL);
1618             return -1;
1619           }
1620         break;
1621       }
1622     case FIOASYNC:
1623       res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
1624               *(int *) p ? ASYNC_MASK : 0);
1625       syscall_printf ("Async I/O on socket %s",
1626               *(int *) p ? "started" : "cancelled");
1627       async_io (*(int *) p != 0);
1628       break;
1629     case FIONREAD:
1630       res = ioctlsocket (get_socket (), FIONREAD, (unsigned long *) p);
1631       if (res == SOCKET_ERROR)
1632         set_winsock_errno ();
1633       break;
1634     default:
1635       /* We must cancel WSAAsyncSelect (if any) before setting socket to
1636        * blocking mode
1637        */
1638       if (cmd == FIONBIO && async_io () && *(int *) p == 0)
1639         WSAAsyncSelect (get_socket (), winmsg, 0, 0);
1640       res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);
1641       if (res == SOCKET_ERROR)
1642           set_winsock_errno ();
1643       if (cmd == FIONBIO)
1644         {
1645           syscall_printf ("socket is now %sblocking",
1646                             *(int *) p ? "non" : "");
1647           /* Start AsyncSelect if async socket unblocked */
1648           if (*(int *) p && async_io ())
1649             WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
1650
1651           set_nonblocking (*(int *) p);
1652         }
1653       break;
1654     }
1655   syscall_printf ("%d = ioctl_socket (%x, %x)", res, cmd, p);
1656   return res;
1657 }
1658
1659 int
1660 fhandler_socket::fcntl (int cmd, void *arg)
1661 {
1662   int res = 0;
1663   int request, current;
1664
1665   switch (cmd)
1666     {
1667     case F_SETOWN:
1668       {
1669         /* Urgh!  Bad hack! */
1670         pid_t pid = (pid_t) arg;
1671         owner (pid == getpid ());
1672         debug_printf ("owner set to %d", owner ());
1673       }
1674       break;
1675     case F_SETFL:
1676       {
1677         /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
1678            Set only the flag that has been passed in.  If both are set, just
1679            record O_NONBLOCK.   */
1680         int new_flags = (int) arg & O_NONBLOCK_MASK;
1681         if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
1682           new_flags = O_NONBLOCK;
1683         current = get_flags () & O_NONBLOCK_MASK;
1684         request = new_flags ? 1 : 0;
1685         if (!!current != !!new_flags && (res = ioctl (FIONBIO, &request)))
1686           break;
1687         set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags);
1688         break;
1689       }
1690     default:
1691       res = fhandler_base::fcntl (cmd, arg);
1692       break;
1693     }
1694   return res;
1695 }
1696
1697 void
1698 fhandler_socket::set_close_on_exec (bool val)
1699 {
1700   if (!winsock2_active) /* < Winsock 2.0 */
1701     set_no_inheritance (get_handle (), val);
1702   close_on_exec (val);
1703   debug_printf ("set close_on_exec for %s to %d", get_name (), val);
1704 }
1705
1706 void
1707 fhandler_socket::set_sun_path (const char *path)
1708 {
1709   sun_path = path ? cstrdup (path) : NULL;
1710 }
1711
1712 int
1713 fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid)
1714 {
1715   if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
1716     {
1717       set_errno (EINVAL);
1718       return -1;
1719     }
1720   if (connect_state () != connected)
1721     {
1722       set_errno (ENOTCONN);
1723       return -1;
1724     }
1725   if (sec_peer_pid == (pid_t) 0)
1726     {
1727       set_errno (ENOTCONN);     /* Usually when calling getpeereid on
1728                                    accepting (instead of accepted) socket. */
1729       return -1;
1730     }
1731
1732   myfault efault;
1733   if (efault.faulted (EFAULT))
1734     return -1;
1735   if (pid)
1736     *pid = sec_peer_pid;
1737   if (euid)
1738     *euid = sec_peer_uid;
1739   if (egid)
1740     *egid = sec_peer_gid;
1741   return 0;
1742 }