⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fhandler_socket.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
	   stored address will be truncated."  We play it save here so	   that the path always has a trailing 0 even if it's truncated. */	strncpy (sun->sun_path, get_sun_path (),		 *namelen - sizeof *sun + sizeof sun->sun_path - 1);      *namelen = sizeof *sun - sizeof sun->sun_path		 + strlen (sun->sun_path) + 1;      res = 0;    }  else    {      res = ::getsockname (get_socket (), name, namelen);      if (res)	set_winsock_errno ();    }  return res;}intfhandler_socket::getpeername (struct sockaddr *name, int *namelen){  int res = ::getpeername (get_socket (), name, namelen);  if (res)    set_winsock_errno ();  return res;}intfhandler_socket::readv (const struct iovec *const iov, const int iovcnt,			ssize_t tot){  struct msghdr msg =    {      msg_name:		NULL,      msg_namelen:	0,      msg_iov:		(struct iovec *) iov, // const_cast      msg_iovlen:	iovcnt,      msg_accrights:	NULL,      msg_accrightslen:	0    };  return recvmsg (&msg, 0, tot);}intfhandler_socket::recvfrom (void *ptr, size_t len, int flags,			   struct sockaddr *from, int *fromlen){  int res;  DWORD ret;  flags &= MSG_WINMASK;  if (!winsock2_active)    ret = res = ::recvfrom (get_socket (),			    (char *) ptr, len, flags,			    from, fromlen);  else    {      WSABUF wsabuf = { len, (char *) ptr };      if (is_nonblocking ())	res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, (DWORD *) &flags,			   from, fromlen,			   NULL, NULL);      else	{	  wsock_event wsock_evt;	  res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, (DWORD *) &flags,			     from, fromlen,			     wsock_evt.prepare (), NULL);	  if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING)	    ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags);	}    }  if (res == SOCKET_ERROR)    {      res = -1;      set_winsock_errno ();    }  else    res = ret;  return res;}intfhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot){  if (get_addr_family () == AF_LOCAL)    {      /* On AF_LOCAL sockets the (fixed-size) name of the shared memory	 area used for descriptor passing is transmitted first.	 If this string is empty, no descriptors are passed and we can	 go ahead recv'ing the normal data blocks.  Otherwise start	 special handling for descriptor passing. */      /*TODO*/    }  struct iovec *const iov = msg->msg_iov;  const int iovcnt = msg->msg_iovlen;  struct sockaddr *from = (struct sockaddr *) msg->msg_name;  int *fromlen = from ? &msg->msg_namelen : NULL;  int res;  if (!winsock2_active)    {      if (iovcnt == 1)	res = recvfrom (iov->iov_base, iov->iov_len, flags,			from, fromlen);      else	{	  if (tot == -1)	// i.e. if not pre-calculated by the caller.	    {	      tot = 0;	      const struct iovec *iovptr = iov + iovcnt;	      do		{		  iovptr -= 1;		  tot += iovptr->iov_len;		}	      while (iovptr != iov);	    }	  char *buf = (char *) alloca (tot);	  if (!buf)	    {	      set_errno (ENOMEM);	      res = -1;	    }	  else	    {	      res = recvfrom (buf, tot, flags,			      from, fromlen);	      const struct iovec *iovptr = iov;	      int nbytes = res;	      while (nbytes > 0)		{		  const int frag = min (nbytes, (ssize_t) iovptr->iov_len);		  memcpy (iovptr->iov_base, buf, frag);		  buf += frag;		  iovptr += 1;		  nbytes -= frag;		}	    }	}    }  else    {      WSABUF wsabuf[iovcnt];      {	const struct iovec *iovptr = iov + iovcnt;	WSABUF *wsaptr = wsabuf + iovcnt;	do	  {	    iovptr -= 1;	    wsaptr -= 1;	    wsaptr->len = iovptr->iov_len;	    wsaptr->buf = (char *) iovptr->iov_base;	  }	while (wsaptr != wsabuf);      }      DWORD ret;      if (is_nonblocking ())	res = WSARecvFrom (get_socket (),			   wsabuf, iovcnt, &ret, (DWORD *) &flags,			   from, fromlen,			   NULL, NULL);      else	{	  wsock_event wsock_evt;	  res = WSARecvFrom (get_socket (),			     wsabuf, iovcnt, &ret, (DWORD *) &flags,			     from, fromlen,			     wsock_evt.prepare (), NULL);	  if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING)	    ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags);	}      if (res == SOCKET_ERROR)	{	  res = -1;	  set_winsock_errno ();	}      else	res = ret;    }  return res;}intfhandler_socket::writev (const struct iovec *const iov, const int iovcnt,			 ssize_t tot){  struct msghdr msg =    {      msg_name:		NULL,      msg_namelen:	0,      msg_iov:		(struct iovec *) iov, // const_cast      msg_iovlen:	iovcnt,      msg_accrights:	NULL,      msg_accrightslen:	0    };  return sendmsg (&msg, 0, tot);}intfhandler_socket::sendto (const void *ptr, size_t len, int flags,			 const struct sockaddr *to, int tolen){  sockaddr_in sin;  if (to && !get_inet_addr (to, tolen, &sin, &tolen))    return -1;  int res;  DWORD ret;  if (!winsock2_active)    ret = res = ::sendto (get_socket (), (const char *) ptr, len,			  flags & MSG_WINMASK,			  (to ? (const struct sockaddr *) &sin : NULL), tolen);  else    {      WSABUF wsabuf = { len, (char *) ptr };      if (is_nonblocking ())	res = WSASendTo (get_socket (), &wsabuf, 1, &ret,			 flags & MSG_WINMASK,			 (to ? (const struct sockaddr *) &sin : NULL), tolen,			 NULL, NULL);      else	{	  wsock_event wsock_evt;	  res = WSASendTo (get_socket (), &wsabuf, 1, &ret,			   flags & MSG_WINMASK,			   (to ? (const struct sockaddr *) &sin : NULL), tolen,			   wsock_evt.prepare (), NULL);	  if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING)	    ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags);	}    }  if (res == SOCKET_ERROR)    {      res = -1;      set_winsock_errno ();    }  else    res = ret;  /* Special handling for SIGPIPE */  if (res == -1 && get_errno () == ESHUTDOWN)    {      set_errno (EPIPE);      if (! (flags & MSG_NOSIGNAL))	raise (SIGPIPE);    }  return res;}intfhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot){  if (get_addr_family () == AF_LOCAL)    {      /* For AF_LOCAL/AF_UNIX sockets, if descriptors are given, start	 the special handling for descriptor passing.  Otherwise just	 transmit an empty string to tell the receiver that no	 descriptor passing is done. */      /*TODO*/    }  struct iovec *const iov = msg->msg_iov;  const int iovcnt = msg->msg_iovlen;  int res;  if (!winsock2_active)    {      if (iovcnt == 1)	res = sendto (iov->iov_base, iov->iov_len, flags,		      (struct sockaddr *) msg->msg_name,		      msg->msg_namelen);      else	{	  if (tot == -1)	// i.e. if not pre-calculated by the caller.	    {	      tot = 0;	      const struct iovec *iovptr = iov + iovcnt;	      do		{		  iovptr -= 1;		  tot += iovptr->iov_len;		}	      while (iovptr != iov);	    }	  char *const buf = (char *) alloca (tot);	  if (!buf)	    {	      set_errno (ENOMEM);	      res = -1;	    }	  else	    {	      char *bufptr = buf;	      const struct iovec *iovptr = iov;	      int nbytes = tot;	      while (nbytes != 0)		{		  const int frag = min (nbytes, (ssize_t) iovptr->iov_len);		  memcpy (bufptr, iovptr->iov_base, frag);		  bufptr += frag;		  iovptr += 1;		  nbytes -= frag;		}	      res = sendto (buf, tot, flags,			    (struct sockaddr *) msg->msg_name,			    msg->msg_namelen);	    }	}    }  else    {      WSABUF wsabuf[iovcnt];      {	const struct iovec *iovptr = iov + iovcnt;	WSABUF *wsaptr = wsabuf + iovcnt;	do	  {	    iovptr -= 1;	    wsaptr -= 1;	    wsaptr->len = iovptr->iov_len;	    wsaptr->buf = (char *) iovptr->iov_base;	  }	while (wsaptr != wsabuf);      }      DWORD ret;      if (is_nonblocking ())	res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret, flags,			 (struct sockaddr *) msg->msg_name,			 msg->msg_namelen,			 NULL, NULL);      else	{	  wsock_event wsock_evt;	  res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret, flags,			   (struct sockaddr *) msg->msg_name,			   msg->msg_namelen,			   wsock_evt.prepare (), NULL);	  if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING)	    ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags);	}      if (res == SOCKET_ERROR)	{	  res = -1;	  set_winsock_errno ();	}      else	res = ret;    }  return res;}intfhandler_socket::shutdown (int how){  int res = ::shutdown (get_socket (), how);  if (res)    set_winsock_errno ();  else    switch (how)      {      case SHUT_RD:	set_shutdown_read ();	break;      case SHUT_WR:	set_shutdown_write ();	break;      case SHUT_RDWR:	set_shutdown_read ();	set_shutdown_write ();	break;      }  return res;}intfhandler_socket::close (){  int res = 0;  /* HACK to allow a graceful shutdown even if shutdown() hasn't been     called by the application. Note that this isn't the ultimate     solution but it helps in many cases. */  struct linger linger;  linger.l_onoff = 1;  linger.l_linger = 240; /* seconds. default 2MSL value according to MSDN. */  setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,	      (const char *)&linger, sizeof linger);  while ((res = closesocket (get_socket ())) != 0)    {      if (WSAGetLastError () != WSAEWOULDBLOCK)	{	  set_winsock_errno ();	  res = -1;	  break;	}      if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)	{	  set_errno (EINTR);	  res = -1;	  break;	}      WSASetLastError (0);    }  close_secret_event ();  debug_printf ("%d = fhandler_socket::close()", res);  return res;}#define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)intfhandler_socket::ioctl (unsigned int cmd, void *p){  extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */  int res;  struct ifconf ifc, *ifcp;  struct ifreq *ifr, *ifrp;  switch (cmd)    {    case SIOCGIFCONF:      ifcp = (struct ifconf *) p;      if (!ifcp)	{	  set_errno (EINVAL);	  return -1;	}      res = get_ifconf (ifcp, cmd);      if (res)	debug_printf ("error in get_ifconf");      break;    case SIOCGIFFLAGS:      ifr = (struct ifreq *) p;      if (ifr == 0)	{	  set_errno (EINVAL);	  return -1;	}      ifr->ifr_flags = IFF_NOTRAILERS | IFF_UP | IFF_RUNNING;      if (!strncmp(ifr->ifr_name, "lo", 2)          || ntohl (((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr)	  == INADDR_LOOPBACK)	ifr->ifr_flags |= IFF_LOOPBACK;      else	ifr->ifr_flags |= IFF_BROADCAST;      res = 0;      break;    case SIOCGIFBRDADDR:    case SIOCGIFNETMASK:    case SIOCGIFADDR:    case SIOCGIFHWADDR:    case SIOCGIFMETRIC:    case SIOCGIFMTU:      {	ifc.ifc_len = 2048;	ifc.ifc_buf = (char *) alloca (2048);	ifr = (struct ifreq *) p;	if (ifr == 0)	  {	    debug_printf ("ifr == NULL");	    set_errno (EINVAL);	    return -1;	  }	res = get_ifconf (&ifc, cmd);	if (res)	  {	    debug_printf ("error in get_ifconf");	    break;	  }	debug_printf ("    name: %s", ifr->ifr_name);	for (ifrp = ifc.ifc_req;	     (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;	     ++ifrp)	  {	    debug_printf ("testname: %s", ifrp->ifr_name);	    if (! strcmp (ifrp->ifr_name, ifr->ifr_name))	      {		switch (cmd)		  {		  case SIOCGIFADDR:		    ifr->ifr_addr = ifrp->ifr_addr;		    break;		  case SIOCGIFBRDADDR:		    ifr->ifr_broadaddr = ifrp->ifr_broadaddr;		    break;		  case SIOCGIFNETMASK:		    ifr->ifr_netmask = ifrp->ifr_netmask;		    break;		  case SIOCGIFHWADDR:		    ifr->ifr_hwaddr = ifrp->ifr_hwaddr;		    break;		  case SIOCGIFMETRIC:		    ifr->ifr_metric = ifrp->ifr_metric;		    break;		  case SIOCGIFMTU:		    ifr->ifr_mtu = ifrp->ifr_mtu;		    break;		  }		break;	      }	  }	if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)	  {	    set_errno (EINVAL);	    return -1;	  }	break;      }    case FIOASYNC:      res = WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO,	      *(int *) p ? ASYNC_MASK : 0);      syscall_printf ("Async I/O on socket %s",	      *(int *) p ? "started" : "cancelled");      set_async (*(int *) p);      break;    default:      /* We must cancel WSAAsyncSelect (if any) before setting socket to       * blocking mode       */      if (cmd == FIONBIO && *(int *) p == 0)	WSAAsyncSelect (get_socket (), gethwnd (), 0, 0);      res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);      if (res == SOCKET_ERROR)	  set_winsock_errno ();      if (cmd == FIONBIO)	{	  syscall_printf ("socket is now %sblocking",			    *(int *) p ? "non" : "");	  /* Start AsyncSelect if async socket unblocked */	  if (*(int *) p && get_async ())	    WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, ASYNC_MASK);	  set_nonblocking (*(int *) p);	}      break;    }  syscall_printf ("%d = ioctl_socket (%x, %x)", res, cmd, p);  return res;}intfhandler_socket::fcntl (int cmd, void *arg){  int res = 0;  int request, current;  switch (cmd)    {    case F_SETFL:      {	/* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.	   Set only the flag that has been passed in.  If both are set, just	   record O_NONBLOCK.   */	int new_flags = (int) arg & O_NONBLOCK_MASK;	if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))	  new_flags = O_NONBLOCK;	current = get_flags () & O_NONBLOCK_MASK;	request = new_flags ? 1 : 0;	if (!!current != !!new_flags && (res = ioctl (FIONBIO, &request)))	  break;	set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags);	break;      }    default:      res = fhandler_base::fcntl (cmd, arg);      break;    }  return res;}voidfhandler_socket::set_close_on_exec (int val){  if (!winsock2_active) /* < Winsock 2.0 */    set_inheritance (get_handle (), val);  set_close_on_exec_flag (val);  debug_printf ("set close_on_exec for %s to %d", get_name (), val);}voidfhandler_socket::set_sun_path (const char *path){  sun_path = path ? cstrdup (path) : NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -