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

📄 bsdsock.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
/* FILENAME: bsdsock.c
 *
 * Copyright 2000 InterNiche Technologies Inc.  All rights reserved.
 *
 * BSD sockets porting aid
 *
 * MODULE: misclib
 * ROUTINES: bsd_accept(), bsd_getpeername(), bsd_getsockname(),
 *           bsd_getsockopt(), bsd_inet_aton(), bsd_inet_ntoa(),
 *           bsd_recvfrom(), bsd_select(), bsd_setsockopt(), 
 *           bsd_i_sockoptlen()
 * PORTABLE: yes
 */

#include "ipport.h"

#ifdef BSD_SOCKETS

#include <stdarg.h>

#include "netbuf.h"
#include "net.h"

#ifdef IP_MULTICAST
#include "ip.h"
#endif

#include "bsdsock.h"

#include "sockvar.h"


/* FUNCTION: bsd_accept()
 *
 * Accept a connection on a socket
 *
 * PARAM1: s; IN - socket descriptor for the listening socket
 * PARAM2: addr; OUT - ptr to buffer for return of accepted peer's address;
 *               may be NULL if return of address is not requested
 * PARAM3: addrlen; IN/OUT - ptr to int; on entry, specifies the length
 *                  in bytes of addr; on successful return, specifies the
 *                  length of the returned address; may be NULL if 
 *                  addr is also NULL
 * RETURNS: A socket descriptor if successful, -1 if an error occurred.  
 *          The error is available via bsd_errno(s).
 */
BSD_SOCKET
bsd_accept(BSD_SOCKET s,
           struct sockaddr * addr, int * addrlen)
{
   struct socket * so;
   struct sockaddr laddr;
   int laddrlen = 0;
   long lret;

   so = LONG2SO(s);
   SOC_CHECK(so);

   /* if we were given a buffer for the peer's address, also get the
    * buffer's length 
    */
   if (addr != NULL)
   {
      if (addrlen == NULL)
      {
         so->so_error = EFAULT;
         return -1;
      }
      laddrlen = *addrlen;
   }

   lret = t_accept(s, &laddr);

   /* if we were successful, and we were given a buffer for the peer's
    * address: copy the peer's address back into the buffer, but limit
    * the copy to the lesser of the buffer's length and sizeof(struct
    * sockaddr_in), which is all that t_accept() can return as a peer
    * address.  
    */
   if ((lret != -1) && (addr != NULL))
   {
      if (laddrlen > sizeof(struct sockaddr_in))
         laddrlen = sizeof(struct sockaddr_in);
      MEMCPY(addr, &laddr, laddrlen);
      *addrlen = laddrlen;
   }

   return lret;
}

/* FUNCTION: bsd_getpeername()
 *
 * Get the name of the connected peer
 *
 * PARAM1: s; IN - socket descriptor 
 * PARAM2: name; OUT - ptr to buffer for return of peer's address
 * PARAM3: addrlen; IN/OUT - ptr to int; on entry, specifies the length
 *                  in bytes of name; on successful return, specifies the
 *                  length of the returned name
 * RETURNS: 0 if successful, -1 if an error occurred.  The error is
 *          available via bsd_errno(s).
 */
int
bsd_getpeername(BSD_SOCKET s,
                struct sockaddr * name, int * namelen)
{
   struct socket * so;
   struct sockaddr lname;
   int lnamelen;
   int lret;

   so = LONG2SO(s);
   SOC_CHECK(so);

   /* if the buffer length is bogus, fail */
   if (namelen == NULL)
   {
      so->so_error = EFAULT;
      return -1;
   }
   lnamelen = *namelen;

   lret = t_getpeername(s, &lname);

   /* if we were successful: copy the peer's address back into the
    * buffer, but limit the copy to the lesser of the buffer's length
    * and sizeof(struct sockaddr_in), which is all that
    * t_getpeername() can return as a peer address, and pass the
    * copied length back to the caller.  
    */
   if (lret != -1)
   {
      if (lnamelen > sizeof(struct sockaddr_in))
         lnamelen = sizeof(struct sockaddr_in);
      MEMCPY(name, &lname, lnamelen);
      *namelen = lnamelen;
   }

   return lret;
}

/* FUNCTION: bsd_getsockname()
 *
 * Gets the name of the socket.
 *
 * PARAM1: s; IN - socket descriptor 
 * PARAM2: name; OUT - ptr to buffer for return of peer's address
 * PARAM3: addrlen; IN/OUT - ptr to int; on entry, specifies the length
 *                  in bytes of name; on successful return, specifies the
 *                  length of the returned name
 * RETURNS: 0 if successful, -1 if an error occurred.  The error is
 *          available via bsd_errno(s).
 */
int
bsd_getsockname(BSD_SOCKET s,
                struct sockaddr * name, int * namelen)
{
   struct socket * so;
   struct sockaddr lname;
   int lnamelen;
   int lret;

   so = LONG2SO(s);
   SOC_CHECK(so);

   /* if the buffer length is bogus, fail */
   if (namelen == NULL)
   {
      so->so_error = EFAULT;
      return -1;
   }
   lnamelen = *namelen;

   lret = t_getsockname(s, &lname);

   /* if we were successful: copy the peer's address back into the
    * buffer, but limit the copy to the lesser of the buffer's length
    * and sizeof(struct sockaddr_in), which is all that
    * t_getpeername() can return as a peer address, and pass the
    * copied length back to the caller.  
    */
   if (lret != -1)
   {
      if (lnamelen > sizeof(struct sockaddr_in))
         lnamelen = sizeof(struct sockaddr_in);
      MEMCPY(name, &lname, lnamelen);
      *namelen = lnamelen;
   }

   return lret;
}

/* FUNCTION: bsd_i_sockoptlen()
 *
 * Get the minimum length of a named socket option
 *
 * PARAM1: level; IN - the level of the option
 * PARAM2: name; IN - the name of the option
 * RETURNS: minimum length of the named socket option, in bytes
 */
int 
bsd_i_sockoptlen(int level,
                 int name)
{
   USE_ARG(level);

   switch (name)
   {
   case SO_BIO:
   case SO_NBIO:
      /* these don't use an option value */
      return 0;
   case SO_LINGER:
      /* this option is a struct linger */
      return sizeof(struct linger);
   case SO_RCVTIMEO:
   case SO_SNDTIMEO:
      /* these options are type short */
      return sizeof(short);
   case SO_KEEPALIVE:
   case SO_DONTROUTE:
   case SO_BROADCAST:
   case SO_REUSEADDR:
   case SO_OOBINLINE:
   case SO_SNDBUF:
   case SO_RCVBUF:
   case SO_NONBLOCK:
   case SO_ERROR:
   case SO_TYPE:
      /* these options are type int */
      return sizeof(int);
#ifdef TCP_ZEROCOPY
   case SO_CALLBACK:
      /* this option is a pointer to a function returning int */
      return sizeof(int (*)());
#endif /* TCP_ZEROCOPY */
#ifdef IP_MULTICAST
   case IP_MULTICAST_IF:
      /* this option is type ip_addr */
      return sizeof(ip_addr);
   case IP_MULTICAST_TTL:
   case IP_MULTICAST_LOOP:
      /* these options are type u_char */
      return sizeof(u_char);
   case IP_ADD_MEMBERSHIP:
   case IP_DROP_MEMBERSHIP:
      /* these options are struct ip_mreq */
      return sizeof(struct ip_mreq);
#endif /* IP_MULTICAST */
   default:
      /* we don't know what type these options are */
      return 0;
   }
   
}

/* FUNCTION: bsd_getsockopt()
 *
 * Get a socket option value
 *
 * PARAM1: s; IN - socket descriptor 
 * PARAM2: level; IN - the level of the option to get
 * PARAM3: name; IN - the name of the option to get
 * PARAM4: opt; OUT - ptr to buffer for return of option value; may be
 *              NULL
 * PARAM5: optlen; IN/OUT - ptr to int; on entry, specifies the length
 *                 in bytes of opt; on successful return, specifies the
 *                 length of the returned option; may be NULL if opt is
 *                 also NULL
 * RETURNS: 0 if successful, -1 if an error occurred.  The error is
 *          available via bsd_errno(s).
 */
int
bsd_getsockopt(BSD_SOCKET s,
               int level,
               int name,
               void * opt, int * optlen)
{
   struct socket * so;
   int loptlen;
   int e;

   so = LONG2SO(s);
   SOC_CHECK(so);

   /* make sure supplied option value is big enough for the 
    * named option, else fail w/error EFAULT
    */
   loptlen = bsd_i_sockoptlen(level, name);
   if ((optlen == NULL) || (*optlen < loptlen))
   {
      so->so_error = EFAULT;
      return -1;
   }

   e = t_getsockopt(s, name, opt);

   /* if it worked, copy the option length back for the caller's use */
   if (e == 0)
   {
      *optlen = loptlen;
   }

   return e;
   

⌨️ 快捷键说明

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