1 /* fhandler_socket.cc. See fhandler.h for a description of the fhandler classes.
3 Copyright 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
11 /* #define DEBUG_NEST_ON 1 */
13 #define __INSIDE_CYGWIN_NET__
16 #include <sys/socket.h>
19 #include <asm/byteorder.h>
22 #define USE_SYS_TYPES_FD_SET
26 #include "cygwin/version.h"
27 #include "perprocess.h"
33 #include "cygthread.h"
39 #define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
41 extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc);
43 int sscanf (const char *, const char *, ...);
44 } /* End of "C" section */
46 fhandler_dev_random* entropy_source;
48 /* cygwin internal: map sockaddr into internet domain address */
50 get_inet_addr (const struct sockaddr *in, int inlen,
51 struct sockaddr_in *out, int *outlen,
52 int *type = NULL, int *secret = NULL)
55 int* secret_ptr = (secret ? : secret_buf);
57 if (in->sa_family == AF_INET)
59 *out = * (struct sockaddr_in *)in;
63 else if (in->sa_family == AF_LOCAL)
65 path_conv pc (in->sa_data, PC_SYM_FOLLOW);
81 HANDLE fh = CreateFile (pc, GENERIC_READ, wincap.shared (), &sec_none,
82 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
83 if (fh == INVALID_HANDLE_VALUE)
91 memset (buf, 0, sizeof buf);
92 if (ReadFile (fh, buf, 128, &len, 0))
94 struct sockaddr_in sin;
96 sin.sin_family = AF_INET;
97 sscanf (buf + strlen (SOCKET_COOKIE), "%hu %c %08x-%08x-%08x-%08x",
100 secret_ptr, secret_ptr + 1, secret_ptr + 2, secret_ptr + 3);
101 sin.sin_port = htons (sin.sin_port);
102 sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
104 *outlen = sizeof sin;
106 *type = (ctype == 's' ? SOCK_STREAM :
107 ctype == 'd' ? SOCK_DGRAM
116 set_errno (EAFNOSUPPORT);
121 /**********************************************************************/
122 /* fhandler_socket */
124 fhandler_socket::fhandler_socket () :
129 need_fork_fixup (true);
130 prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF,
131 sizeof (WSAPROTOCOL_INFOA));
133 if (pc.is_fs_special ())
135 fhandler_socket * fhs = (fhandler_socket *) fh;
136 fhs->set_addr_family (AF_LOCAL);
137 fhs->set_sun_path (posix_path);
142 fhandler_socket::~fhandler_socket ()
145 cfree (prot_info_ptr);
151 fhandler_socket::get_proc_fd_name (char *buf)
153 __small_sprintf (buf, "socket:[%d]", get_socket ());
158 fhandler_socket::open (int flags, mode_t mode)
165 fhandler_socket::af_local_set_sockpair_cred (void)
167 sec_pid = sec_peer_pid = getpid ();
168 sec_uid = sec_peer_uid = geteuid32 ();
169 sec_gid = sec_peer_gid = getegid32 ();
173 fhandler_socket::af_local_setblocking (bool &async, bool &nonblocking)
176 nonblocking = is_nonblocking ();
177 if (async || nonblocking)
178 WSAAsyncSelect (get_socket (), winmsg, 0, 0);
180 ioctlsocket (get_socket (), FIONBIO, &p);
181 set_nonblocking (false);
186 fhandler_socket::af_local_unsetblocking (bool async, bool nonblocking)
191 ioctlsocket (get_socket (), FIONBIO, &p);
192 set_nonblocking (true);
196 WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
202 fhandler_socket::af_local_recv_secret (void)
204 int out[4] = { 0, 0, 0, 0 };
205 int rest = sizeof out;
206 char *ptr = (char *) out;
209 int ret = recvfrom (ptr, rest, 0, NULL, NULL);
217 debug_printf ("Received af_local secret: %08x-%08x-%08x-%08x",
218 out[0], out[1], out[2], out[3]);
219 if (out[0] != connect_secret[0] || out[1] != connect_secret[1]
220 || out[2] != connect_secret[2] || out[3] != connect_secret[3])
222 debug_printf ("Receiving af_local secret mismatch");
227 debug_printf ("Receiving af_local secret failed");
232 fhandler_socket::af_local_send_secret (void)
234 int rest = sizeof connect_secret;
235 char *ptr = (char *) connect_secret;
238 int ret = sendto (ptr, rest, 0, NULL, 0);
244 debug_printf ("Sending af_local secret %s", rest == 0 ? "succeeded"
250 fhandler_socket::af_local_recv_cred (void)
252 struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
253 int rest = sizeof out;
254 char *ptr = (char *) &out;
257 int ret = recvfrom (ptr, rest, 0, NULL, NULL);
265 debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
266 out.pid, out.uid, out.gid);
267 sec_peer_pid = out.pid;
268 sec_peer_uid = out.uid;
269 sec_peer_gid = out.gid;
272 debug_printf ("Receiving eid credentials failed");
277 fhandler_socket::af_local_send_cred (void)
279 struct ucred in = { sec_pid, sec_uid, sec_gid };
280 int rest = sizeof in;
281 char *ptr = (char *) ∈
284 int ret = sendto (ptr, rest, 0, NULL, 0);
291 debug_printf ("Sending eid credentials succeeded");
293 debug_printf ("Sending eid credentials failed");
298 fhandler_socket::af_local_connect (void)
300 /* This keeps the test out of select. */
301 if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
304 debug_printf ("af_local_connect called");
305 bool orig_async_io, orig_is_nonblocking;
306 af_local_setblocking (orig_async_io, orig_is_nonblocking);
307 if (!af_local_send_secret () || !af_local_recv_secret ()
308 || !af_local_send_cred () || !af_local_recv_cred ())
310 debug_printf ("accept from unauthorized server");
311 ::shutdown (get_socket (), SD_BOTH);
312 WSASetLastError (WSAECONNREFUSED);
315 af_local_unsetblocking (orig_async_io, orig_is_nonblocking);
320 fhandler_socket::af_local_accept (void)
322 debug_printf ("af_local_accept called");
323 bool orig_async_io, orig_is_nonblocking;
324 af_local_setblocking (orig_async_io, orig_is_nonblocking);
325 if (!af_local_recv_secret () || !af_local_send_secret ()
326 || !af_local_recv_cred () || !af_local_send_cred ())
328 debug_printf ("connect from unauthorized client");
329 ::shutdown (get_socket (), SD_BOTH);
330 ::closesocket (get_socket ());
331 WSASetLastError (WSAECONNABORTED);
334 af_local_unsetblocking (orig_async_io, orig_is_nonblocking);
339 fhandler_socket::af_local_set_cred (void)
342 sec_uid = geteuid32 ();
343 sec_gid = getegid32 ();
344 sec_peer_pid = (pid_t) 0;
345 sec_peer_uid = (__uid32_t) -1;
346 sec_peer_gid = (__gid32_t) -1;
350 fhandler_socket::af_local_copy (fhandler_socket *sock)
352 sock->connect_secret[0] = connect_secret[0];
353 sock->connect_secret[1] = connect_secret[1];
354 sock->connect_secret[2] = connect_secret[2];
355 sock->connect_secret[3] = connect_secret[3];
356 sock->sec_pid = sec_pid;
357 sock->sec_uid = sec_uid;
358 sock->sec_gid = sec_gid;
359 sock->sec_peer_pid = sec_peer_pid;
360 sock->sec_peer_uid = sec_peer_uid;
361 sock->sec_peer_gid = sec_peer_gid;
365 fhandler_socket::af_local_set_secret (char *buf)
369 void *buf = malloc (sizeof (fhandler_dev_random));
370 entropy_source = new (buf) fhandler_dev_random ();
371 entropy_source->dev () = *urandom_dev;
373 if (entropy_source &&
374 !entropy_source->open (O_RDONLY))
376 delete entropy_source;
377 entropy_source = NULL;
381 size_t len = sizeof (connect_secret);
382 entropy_source->read (connect_secret, len);
383 if (len != sizeof (connect_secret))
384 bzero ((char*) connect_secret, sizeof (connect_secret));
386 __small_sprintf (buf, "%08x-%08x-%08x-%08x",
387 connect_secret [0], connect_secret [1],
388 connect_secret [2], connect_secret [3]);
392 fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
394 if (!winsock2_active)
396 fhandler_base::fixup_before_fork_exec (win_proc_id);
397 debug_printf ("Without Winsock 2.0");
399 else if (!WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr))
400 debug_printf ("WSADuplicateSocket went fine, sock %p, win_proc_id %d, prot_info_ptr %p",
401 get_socket (), win_proc_id, prot_info_ptr);
404 debug_printf ("WSADuplicateSocket error, sock %p, win_proc_id %d, prot_info_ptr %p",
405 get_socket (), win_proc_id, prot_info_ptr);
406 set_winsock_errno ();
410 extern "C" void __stdcall load_wsock32 ();
412 fhandler_socket::fixup_after_fork (HANDLE parent)
416 debug_printf ("WSASocket begin, dwServiceFlags1=%d",
417 prot_info_ptr->dwServiceFlags1);
419 if ((new_sock = WSASocketA (FROM_PROTOCOL_INFO,
422 prot_info_ptr, 0, 0)) == INVALID_SOCKET)
424 debug_printf ("WSASocket error");
425 set_io_handle ((HANDLE)INVALID_SOCKET);
426 set_winsock_errno ();
428 else if (!new_sock && !winsock2_active)
431 fhandler_base::fixup_after_fork (parent);
432 debug_printf ("Without Winsock 2.0");
436 debug_printf ("WSASocket went fine new_sock %p, old_sock %p", new_sock, get_io_handle ());
437 set_io_handle ((HANDLE) new_sock);
442 fhandler_socket::fixup_after_exec ()
444 debug_printf ("here");
445 if (!close_on_exec ())
446 fixup_after_fork (NULL);
448 else if (!winsock2_active)
449 closesocket (get_socket ());
454 fhandler_socket::dup (fhandler_base *child)
458 debug_printf ("here");
459 fhandler_socket *fhs = (fhandler_socket *) child;
460 fhs->addr_family = addr_family;
461 fhs->set_socket_type (get_socket_type ());
462 if (get_addr_family () == AF_LOCAL)
464 fhs->set_sun_path (get_sun_path ());
465 if (get_socket_type () == SOCK_STREAM)
467 fhs->sec_pid = sec_pid;
468 fhs->sec_uid = sec_uid;
469 fhs->sec_gid = sec_gid;
470 fhs->sec_peer_pid = sec_peer_pid;
471 fhs->sec_peer_uid = sec_peer_uid;
472 fhs->sec_peer_gid = sec_peer_gid;
475 fhs->connect_state (connect_state ());
479 /* Since WSADuplicateSocket() fails on NT systems when the process
480 is currently impersonating a non-privileged account, we revert
481 to the original account before calling WSADuplicateSocket() and
482 switch back afterwards as it's also in fork().
483 If WSADuplicateSocket() still fails for some reason, we fall back
484 to DuplicateHandle(). */
486 cygheap->user.deimpersonate ();
487 fhs->set_io_handle (get_io_handle ());
488 fhs->fixup_before_fork_exec (GetCurrentProcessId ());
489 cygheap->user.reimpersonate ();
490 if (!WSAGetLastError ())
492 fhs->fixup_after_fork (hMainProc);
493 if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
495 cygheap->fdtab.inc_need_fixup_before ();
499 debug_printf ("WSADuplicateSocket failed, trying DuplicateHandle");
502 /* We don't call fhandler_base::dup here since that requires
503 having winsock called from fhandler_base and it creates only
504 inheritable sockets which is wrong for winsock2. */
506 if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
507 !winsock2_active, DUPLICATE_SAME_ACCESS))
509 system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
514 fhs->set_io_handle (nh);
515 cygheap->fdtab.inc_need_fixup_before ();
520 fhandler_socket::fstat (struct __stat64 *buf)
523 if (get_device () == FH_UNIX)
525 res = fhandler_base::fstat_fs (buf);
528 buf->st_mode = (buf->st_mode & ~S_IFMT) | S_IFSOCK;
533 res = fhandler_base::fstat (buf);
537 buf->st_ino = (__ino64_t) ((DWORD) get_handle ());
538 buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO;
545 fhandler_socket::fchmod (mode_t mode)
547 if (get_device () == FH_UNIX)
549 fhandler_disk_file fh (pc);
550 fh.get_device () = FH_FS;
551 int ret = fh.fchmod (mode);
552 SetFileAttributes (pc, GetFileAttributes (pc) | FILE_ATTRIBUTE_SYSTEM);
559 fhandler_socket::fchown (__uid32_t uid, __gid32_t gid)
561 if (get_device () == FH_UNIX)
563 fhandler_disk_file fh (pc);
564 return fh.fchown (uid, gid);
570 fhandler_socket::facl (int cmd, int nentries, __aclent32_t *aclbufp)
572 if (get_device () == FH_UNIX)
574 fhandler_disk_file fh (pc);
575 return fh.facl (cmd, nentries, aclbufp);
577 return fhandler_base::facl (cmd, nentries, aclbufp);
581 fhandler_socket::link (const char *newpath)
583 if (get_device () == FH_UNIX)
585 fhandler_disk_file fh (pc);
586 return fh.link (newpath);
588 return fhandler_base::link (newpath);
592 fhandler_socket::bind (const struct sockaddr *name, int namelen)
596 if (name->sa_family == AF_LOCAL)
598 #define un_addr ((struct sockaddr_un *) name)
599 struct sockaddr_in sin;
600 int len = sizeof sin;
602 if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
604 set_errno (ENAMETOOLONG);
607 sin.sin_family = AF_INET;
609 sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
610 if (::bind (get_socket (), (sockaddr *) &sin, len))
612 syscall_printf ("AF_LOCAL: bind failed %d", get_errno ());
613 set_winsock_errno ();
616 if (::getsockname (get_socket (), (sockaddr *) &sin, &len))
618 syscall_printf ("AF_LOCAL: getsockname failed %d", get_errno ());
619 set_winsock_errno ();
623 sin.sin_port = ntohs (sin.sin_port);
624 debug_printf ("AF_LOCAL: socket bound to port %u", sin.sin_port);
626 path_conv pc (un_addr->sun_path, PC_SYM_FOLLOW);
629 set_errno (pc.error);
634 set_errno (EADDRINUSE);
637 mode_t mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask;
638 DWORD attr = FILE_ATTRIBUTE_SYSTEM;
639 if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
640 attr |= FILE_ATTRIBUTE_READONLY;
641 SECURITY_ATTRIBUTES sa = sec_none;
642 security_descriptor sd;
643 if (allow_ntsec && pc.has_acls ())
644 set_security_attribute (mode, &sa, sd);
645 HANDLE fh = CreateFile (pc, GENERIC_WRITE, 0, &sa, CREATE_NEW, attr, 0);
646 if (fh == INVALID_HANDLE_VALUE)
648 if (GetLastError () == ERROR_ALREADY_EXISTS)
649 set_errno (EADDRINUSE);
654 char buf[sizeof (SOCKET_COOKIE) + 80];
655 __small_sprintf (buf, "%s%u %c ", SOCKET_COOKIE, sin.sin_port, get_socket_type () == SOCK_STREAM ? 's' : get_socket_type () == SOCK_DGRAM ? 'd' : '-');
656 af_local_set_secret (strchr (buf, '\0'));
657 DWORD blen = strlen (buf) + 1;
658 if (!WriteFile (fh, buf, blen, &blen, 0))
667 set_sun_path (un_addr->sun_path);
672 else if (::bind (get_socket (), name, namelen))
673 set_winsock_errno ();
682 fhandler_socket::connect (const struct sockaddr *name, int namelen)
685 bool in_progress = false;
686 struct sockaddr_in sin;
690 if (!get_inet_addr (name, namelen, &sin, &namelen, &type, connect_secret))
693 if (get_addr_family () == AF_LOCAL && get_socket_type () != type)
695 WSASetLastError (WSAEPROTOTYPE);
696 set_winsock_errno ();
700 res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
706 err = WSAGetLastError ();
707 /* Special handling for connect to return the correct error code
708 when called on a non-blocking socket. */
709 if (is_nonblocking ())
711 if (err == WSAEWOULDBLOCK || err == WSAEALREADY)
714 if (err == WSAEWOULDBLOCK)
715 WSASetLastError (err = WSAEINPROGRESS);
716 else if (err == WSAEINVAL)
717 WSASetLastError (err = WSAEISCONN);
719 set_winsock_errno ();
722 if (get_addr_family () == AF_LOCAL && (!res || in_progress))
723 set_sun_path (name->sa_data);
725 if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
727 af_local_set_cred (); /* Don't move into af_local_connect since
728 af_local_connect is called from select,
729 possibly running under another identity. */
730 if (!res && af_local_connect ())
732 set_winsock_errno ();
737 if (err == WSAEINPROGRESS || err == WSAEALREADY)
738 connect_state (connect_pending);
740 connect_state (connect_failed);
742 connect_state (connected);
748 fhandler_socket::listen (int backlog)
750 int res = ::listen (get_socket (), backlog);
752 set_winsock_errno ();
755 if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
756 af_local_set_cred ();
757 connect_state (connected);
763 fhandler_socket::accept (struct sockaddr *peer, int *len)
767 /* Allows NULL peer and len parameters. */
768 struct sockaddr_in peer_dummy;
771 peer = (struct sockaddr *) &peer_dummy;
774 len_dummy = sizeof (struct sockaddr_in);
778 /* accept on NT fails if len < sizeof (sockaddr_in)
779 * some programs set len to
780 * sizeof (name.sun_family) + strlen (name.sun_path) for UNIX domain
782 if (len && ((unsigned) *len < sizeof (struct sockaddr_in)))
783 *len = sizeof (struct sockaddr_in);
785 res = ::accept (get_socket (), peer, len);
787 if (res == (int) INVALID_SOCKET)
788 set_winsock_errno ();
791 cygheap_fdnew res_fd;
792 if (res_fd >= 0 && fdsock (res_fd, &dev (), res))
794 fhandler_socket *sock = (fhandler_socket *) res_fd;
795 sock->set_addr_family (get_addr_family ());
796 sock->set_socket_type (get_socket_type ());
797 sock->async_io (async_io ());
798 sock->set_nonblocking (is_nonblocking ());
799 if (get_addr_family () == AF_LOCAL)
801 sock->set_sun_path (get_sun_path ());
802 if (get_socket_type () == SOCK_STREAM)
804 /* Don't forget to copy credentials from accepting
805 socket to accepted socket and start transaction
806 on accepted socket! */
807 af_local_copy (sock);
808 res = sock->af_local_accept ();
812 set_winsock_errno ();
817 sock->connect_state (connected);
828 debug_printf ("res %d", res);
833 fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
837 if (get_addr_family () == AF_LOCAL)
839 struct sockaddr_un *sun = (struct sockaddr_un *) name;
840 memset (sun, 0, *namelen);
841 sun->sun_family = AF_LOCAL;
843 if (!get_sun_path ())
844 sun->sun_path[0] = '\0';
846 /* According to SUSv2 "If the actual length of the address is
847 greater than the length of the supplied sockaddr structure, the
848 stored address will be truncated." We play it save here so
849 that the path always has a trailing 0 even if it's truncated. */
850 strncpy (sun->sun_path, get_sun_path (),
851 *namelen - sizeof *sun + sizeof sun->sun_path - 1);
853 *namelen = sizeof *sun - sizeof sun->sun_path
854 + strlen (sun->sun_path) + 1;
859 res = ::getsockname (get_socket (), name, namelen);
861 set_winsock_errno ();
868 fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
870 int res = ::getpeername (get_socket (), name, namelen);
872 set_winsock_errno ();
878 fhandler_socket::prepare (HANDLE &event, long event_mask)
882 if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT)
884 debug_printf ("WSACreateEvent, %E");
887 if (WSAEventSelect (get_socket (), event, event_mask) == SOCKET_ERROR)
889 debug_printf ("WSAEventSelect, %E");
896 fhandler_socket::wait (HANDLE event, int flags)
898 int ret = SOCKET_ERROR;
900 WSAEVENT ev[2] = { event, signal_arrived };
901 WSANETWORKEVENTS evts;
903 switch (WSAWaitForMultipleEvents (2, ev, FALSE, 10, FALSE))
905 case WSA_WAIT_TIMEOUT:
908 case WSA_WAIT_EVENT_0:
909 if (!WSAEnumNetworkEvents (get_socket (), event, &evts))
911 if (!evts.lNetworkEvents)
916 if (evts.lNetworkEvents & FD_OOB)
918 if (evts.iErrorCode[FD_OOB_BIT])
919 wsa_err = evts.iErrorCode[FD_OOB_BIT];
920 else if (flags & MSG_OOB)
925 WSASetLastError (WSAEINTR);
929 if (evts.lNetworkEvents & FD_READ)
931 if (evts.iErrorCode[FD_READ_BIT])
932 wsa_err = evts.iErrorCode[FD_READ_BIT];
936 else if (evts.lNetworkEvents & FD_WRITE)
938 if (evts.iErrorCode[FD_WRITE_BIT])
939 wsa_err = evts.iErrorCode[FD_WRITE_BIT];
943 if (evts.lNetworkEvents & FD_CLOSE)
948 if (evts.iErrorCode[FD_CLOSE_BIT])
949 wsa_err = evts.iErrorCode[FD_CLOSE_BIT];
955 WSASetLastError (wsa_err);
958 case WSA_WAIT_EVENT_0 + 1:
959 WSASetLastError (WSAEINTR);
962 WSASetLastError (WSAEFAULT);
969 fhandler_socket::release (HANDLE event)
971 int last_err = WSAGetLastError ();
972 /* KB 168349: NT4 fails if the event parameter is not NULL. */
973 WSAEventSelect (get_socket (), NULL, 0);
974 WSACloseEvent (event);
975 unsigned long non_block = 0;
976 if (ioctlsocket (get_socket (), FIONBIO, &non_block))
977 debug_printf ("return to blocking failed: %d", WSAGetLastError ());
979 WSASetLastError (last_err);
983 fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
990 msg_iov: (struct iovec *) iov, // const_cast
996 return recvmsg (&msg, 0, tot);
1000 fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
1001 struct sockaddr *from, int *fromlen)
1003 int res = SOCKET_ERROR;
1006 flags &= MSG_WINMASK;
1007 if (!winsock2_active)
1008 ret = res = ::recvfrom (get_socket (),
1009 (char *) ptr, len, flags,
1013 WSABUF wsabuf = { len, (char *) ptr };
1015 if (is_nonblocking () || closed () || async_io ())
1016 res = WSARecvFrom (get_socket (), &wsabuf, 1, (ret = 0, &ret),
1017 (DWORD *) &flags, from, fromlen, NULL, NULL);
1021 if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
1025 DWORD lflags = (DWORD) flags;
1026 res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, &lflags,
1027 from, fromlen, NULL, NULL);
1029 while (res == SOCKET_ERROR
1030 && WSAGetLastError () == WSAEWOULDBLOCK
1032 && !(res = wait (evt, flags)));
1038 if (res == SOCKET_ERROR)
1040 /* According to SUSv3, errno isn't set in that case and no error
1041 condition is returned. */
1042 if (WSAGetLastError () == WSAEMSGSIZE)
1045 set_winsock_errno ();
1054 fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
1056 if (get_addr_family () == AF_LOCAL)
1058 /* On AF_LOCAL sockets the (fixed-size) name of the shared memory
1059 area used for descriptor passing is transmitted first.
1060 If this string is empty, no descriptors are passed and we can
1061 go ahead recv'ing the normal data blocks. Otherwise start
1062 special handling for descriptor passing. */
1066 struct iovec *const iov = msg->msg_iov;
1067 const int iovcnt = msg->msg_iovlen;
1069 struct sockaddr *from = (struct sockaddr *) msg->msg_name;
1070 int *fromlen = from ? &msg->msg_namelen : NULL;
1072 int res = SOCKET_ERROR;
1074 if (!winsock2_active)
1077 res = recvfrom (iov->iov_base, iov->iov_len, flags, from, fromlen);
1080 if (tot == -1) // i.e. if not pre-calculated by the caller.
1083 const struct iovec *iovptr = iov + iovcnt;
1087 tot += iovptr->iov_len;
1089 while (iovptr != iov);
1092 char *buf = (char *) alloca (tot);
1101 res = recvfrom (buf, tot, flags, from, fromlen);
1103 const struct iovec *iovptr = iov;
1108 const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
1109 memcpy (iovptr->iov_base, buf, frag);
1119 WSABUF wsabuf[iovcnt];
1120 unsigned long len = 0L;
1123 const struct iovec *iovptr = iov + iovcnt;
1124 WSABUF *wsaptr = wsabuf + iovcnt;
1129 len += wsaptr->len = iovptr->iov_len;
1130 wsaptr->buf = (char *) iovptr->iov_base;
1132 while (wsaptr != wsabuf);
1137 if (is_nonblocking () || closed () || async_io ())
1138 res = WSARecvFrom (get_socket (), wsabuf, iovcnt, (ret = 0, &ret),
1139 (DWORD *) &flags, from, fromlen, NULL, NULL);
1143 if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
1147 DWORD lflags = (DWORD) flags;
1148 res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
1149 &lflags, from, fromlen, NULL, NULL);
1151 while (res == SOCKET_ERROR
1152 && WSAGetLastError () == WSAEWOULDBLOCK
1154 && !(res = wait (evt, flags)));
1159 if (res == SOCKET_ERROR)
1161 /* According to SUSv3, errno isn't set in that case and no error
1162 condition is returned. */
1163 if (WSAGetLastError () == WSAEMSGSIZE)
1166 set_winsock_errno ();
1176 fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
1183 msg_iov: (struct iovec *) iov, // const_cast
1185 msg_accrights: NULL,
1189 return sendmsg (&msg, 0, tot);
1193 fhandler_socket::sendto (const void *ptr, size_t len, int flags,
1194 const struct sockaddr *to, int tolen)
1196 struct sockaddr_in sin;
1198 if (to && !get_inet_addr (to, tolen, &sin, &tolen))
1199 return SOCKET_ERROR;
1201 int res = SOCKET_ERROR;
1204 if (!winsock2_active)
1205 ret = res = ::sendto (get_socket (), (const char *) ptr, len,
1206 flags & MSG_WINMASK,
1207 (to ? (const struct sockaddr *) &sin : NULL), tolen);
1210 WSABUF wsabuf = { len, (char *) ptr };
1212 if (is_nonblocking () || closed () || async_io ())
1213 res = WSASendTo (get_socket (), &wsabuf, 1, (ret = 0, &ret),
1214 flags & MSG_WINMASK,
1215 (to ? (const struct sockaddr *) &sin : NULL), tolen,
1220 if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
1224 res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
1225 flags & MSG_WINMASK,
1226 (to ? (const struct sockaddr *) &sin : NULL),
1229 while (res == SOCKET_ERROR
1230 && WSAGetLastError () == WSAEWOULDBLOCK
1231 && !(res = wait (evt, 0))
1238 if (res == SOCKET_ERROR)
1239 set_winsock_errno ();
1243 /* Special handling for EPIPE and SIGPIPE.
1245 EPIPE is generated if the local end has been shut down on a connection
1246 oriented socket. In this case the process will also receive a SIGPIPE
1247 unless MSG_NOSIGNAL is set. */
1248 if (res == SOCKET_ERROR && get_errno () == ESHUTDOWN
1249 && get_socket_type () == SOCK_STREAM)
1252 if (! (flags & MSG_NOSIGNAL))
1260 fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
1262 if (get_addr_family () == AF_LOCAL)
1264 /* For AF_LOCAL/AF_UNIX sockets, if descriptors are given, start
1265 the special handling for descriptor passing. Otherwise just
1266 transmit an empty string to tell the receiver that no
1267 descriptor passing is done. */
1271 struct iovec *const iov = msg->msg_iov;
1272 const int iovcnt = msg->msg_iovlen;
1274 int res = SOCKET_ERROR;
1276 if (!winsock2_active)
1279 res = sendto (iov->iov_base, iov->iov_len, flags,
1280 (struct sockaddr *) msg->msg_name,
1284 if (tot == -1) // i.e. if not pre-calculated by the caller.
1287 const struct iovec *iovptr = iov + iovcnt;
1291 tot += iovptr->iov_len;
1293 while (iovptr != iov);
1296 char *const buf = (char *) alloca (tot);
1306 const struct iovec *iovptr = iov;
1311 const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
1312 memcpy (bufptr, iovptr->iov_base, frag);
1318 res = sendto (buf, tot, flags,
1319 (struct sockaddr *) msg->msg_name,
1326 WSABUF wsabuf[iovcnt];
1329 const struct iovec *iovptr = iov + iovcnt;
1330 WSABUF *wsaptr = wsabuf + iovcnt;
1335 wsaptr->len = iovptr->iov_len;
1336 wsaptr->buf = (char *) iovptr->iov_base;
1338 while (wsaptr != wsabuf);
1343 if (is_nonblocking () || closed () || async_io ())
1344 res = WSASendTo (get_socket (), wsabuf, iovcnt, (ret = 0, &ret),
1345 flags, (struct sockaddr *) msg->msg_name,
1346 msg->msg_namelen, NULL, NULL);
1350 if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
1354 res = WSASendTo (get_socket (), wsabuf, iovcnt,
1356 (struct sockaddr *) msg->msg_name,
1357 msg->msg_namelen, NULL, NULL);
1359 while (res == SOCKET_ERROR
1360 && WSAGetLastError () == WSAEWOULDBLOCK
1361 && !(res = wait (evt, 0))
1367 if (res == SOCKET_ERROR)
1368 set_winsock_errno ();
1373 /* Special handling for EPIPE and SIGPIPE.
1375 EPIPE is generated if the local end has been shut down on a connection
1376 oriented socket. In this case the process will also receive a SIGPIPE
1377 unless MSG_NOSIGNAL is set. */
1378 if (res == SOCKET_ERROR && get_errno () == ESHUTDOWN
1379 && get_socket_type () == SOCK_STREAM)
1382 if (! (flags & MSG_NOSIGNAL))
1390 fhandler_socket::shutdown (int how)
1392 int res = ::shutdown (get_socket (), how);
1395 set_winsock_errno ();
1400 saw_shutdown_read (true);
1403 saw_shutdown_write (true);
1406 saw_shutdown_read (true);
1407 saw_shutdown_write (true);
1414 fhandler_socket::close ()
1418 /* HACK to allow a graceful shutdown even if shutdown() hasn't been
1419 called by the application. Note that this isn't the ultimate
1420 solution but it helps in many cases. */
1421 struct linger linger;
1423 linger.l_linger = 240; /* secs. default 2MSL value according to MSDN. */
1424 setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
1425 (const char *)&linger, sizeof linger);
1427 while ((res = closesocket (get_socket ())) != 0)
1429 if (WSAGetLastError () != WSAEWOULDBLOCK)
1431 set_winsock_errno ();
1435 if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
1441 WSASetLastError (0);
1444 debug_printf ("%d = fhandler_socket::close()", res);
1449 fhandler_socket::ioctl (unsigned int cmd, void *p)
1451 extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */
1453 struct ifconf ifc, *ifcp;
1454 struct ifreq *ifr, *ifrp;
1459 ifcp = (struct ifconf *) p;
1465 res = get_ifconf (ifcp, cmd);
1467 debug_printf ("error in get_ifconf");
1470 ifr = (struct ifreq *) p;
1476 ifr->ifr_flags = IFF_NOTRAILERS | IFF_UP | IFF_RUNNING;
1477 if (!strncmp(ifr->ifr_name, "lo", 2)
1478 || ntohl (((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr)
1480 ifr->ifr_flags |= IFF_LOOPBACK;
1482 ifr->ifr_flags |= IFF_BROADCAST;
1485 case SIOCGIFBRDADDR:
1486 case SIOCGIFNETMASK:
1493 ifc.ifc_buf = (char *) alloca (2048);
1495 ifr = (struct ifreq *) p;
1498 debug_printf ("ifr == NULL");
1503 res = get_ifconf (&ifc, cmd);
1506 debug_printf ("error in get_ifconf");
1510 debug_printf (" name: %s", ifr->ifr_name);
1511 for (ifrp = ifc.ifc_req;
1512 (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
1515 debug_printf ("testname: %s", ifrp->ifr_name);
1516 if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
1521 ifr->ifr_addr = ifrp->ifr_addr;
1523 case SIOCGIFBRDADDR:
1524 ifr->ifr_broadaddr = ifrp->ifr_broadaddr;
1526 case SIOCGIFNETMASK:
1527 ifr->ifr_netmask = ifrp->ifr_netmask;
1530 ifr->ifr_hwaddr = ifrp->ifr_hwaddr;
1533 ifr->ifr_metric = ifrp->ifr_metric;
1536 ifr->ifr_mtu = ifrp->ifr_mtu;
1542 if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
1550 res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
1551 *(int *) p ? ASYNC_MASK : 0);
1552 syscall_printf ("Async I/O on socket %s",
1553 *(int *) p ? "started" : "cancelled");
1554 async_io (*(int *) p != 0);
1557 res = ioctlsocket (get_socket (), FIONREAD, (unsigned long *) p);
1558 if (res == SOCKET_ERROR)
1559 set_winsock_errno ();
1562 /* We must cancel WSAAsyncSelect (if any) before setting socket to
1565 if (cmd == FIONBIO && async_io () && *(int *) p == 0)
1566 WSAAsyncSelect (get_socket (), winmsg, 0, 0);
1567 res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);
1568 if (res == SOCKET_ERROR)
1569 set_winsock_errno ();
1572 syscall_printf ("socket is now %sblocking",
1573 *(int *) p ? "non" : "");
1574 /* Start AsyncSelect if async socket unblocked */
1575 if (*(int *) p && async_io ())
1576 WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
1578 set_nonblocking (*(int *) p);
1582 syscall_printf ("%d = ioctl_socket (%x, %x)", res, cmd, p);
1587 fhandler_socket::fcntl (int cmd, void *arg)
1590 int request, current;
1596 /* Urgh! Bad hack! */
1597 pid_t pid = (pid_t) arg;
1598 owner (pid == getpid ());
1599 debug_printf ("owner set to %d", owner ());
1604 /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
1605 Set only the flag that has been passed in. If both are set, just
1606 record O_NONBLOCK. */
1607 int new_flags = (int) arg & O_NONBLOCK_MASK;
1608 if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
1609 new_flags = O_NONBLOCK;
1610 current = get_flags () & O_NONBLOCK_MASK;
1611 request = new_flags ? 1 : 0;
1612 if (!!current != !!new_flags && (res = ioctl (FIONBIO, &request)))
1614 set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags);
1618 res = fhandler_base::fcntl (cmd, arg);
1625 fhandler_socket::set_close_on_exec (bool val)
1627 if (!winsock2_active) /* < Winsock 2.0 */
1628 set_no_inheritance (get_handle (), val);
1629 close_on_exec (val);
1630 debug_printf ("set close_on_exec for %s to %d", get_name (), val);
1634 fhandler_socket::set_sun_path (const char *path)
1636 sun_path = path ? cstrdup (path) : NULL;
1640 fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid)
1642 if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
1647 if (connect_state () != connected)
1649 set_errno (ENOTCONN);
1652 if (sec_peer_pid == (pid_t) 0)
1654 set_errno (ENOTCONN); /* Usually when calling getpeereid on
1655 accepting (instead of accepted) socket. */
1659 if (!check_null_invalid_struct (pid))
1660 *pid = sec_peer_pid;
1661 if (!check_null_invalid_struct (euid))
1662 *euid = sec_peer_uid;
1663 if (!check_null_invalid_struct (egid))
1664 *egid = sec_peer_gid;