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