📄 bsdsocklib.c
字号:
/* bsdSockLib.c - UNIX BSD 4.4 compatible socket library *//* Copyright 1984 - 2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01u,05nov01,vvv fixed compilation warnings01t,15oct01,rae merge from truestack ver 01u, base 01r (SPRs 34005, 30608)01s,10nov00,spm merged from version 01s of tor3_x branch (SPR #30608 fix)01r,29apr99,pul Upgraded NPT phase3 code to tor2.0.001q,16mar99,spm recovered orphaned code from tor2_0_x branch (SPR #25770)01p,02feb99,sgv Added zbufsockrtn routine01o,02dec98,n_s fixed sendmsg and recvmsg. spr 2355201n,10nov98,spm unmapped closed socket file descriptors (SPR #21583)01m,26aug98,n_s added return val check to mBufClGet in accept (). spr #22238.01l,17mar98,vin fixed a nonblocking I/O bug SPR 20542.01k,17mar98,jmb Merge patch by jmb from 03nov97: set small receive buffer which HPSIM is TCP client. (SPR 8709) 01j,17mar98,jmb Merge patch by jmb from 31oct97: Set receive buffer when HPSIM is a TCP server. Work-aroun for MTU mismatch and pty problem in the SLIP connection. (SPR 8709)01i,10dec97,sgv fixed a bug in recvmsg, intialized control and from variables to NULL. 01h,06oct97,sgv fixed sendmsg/recvmsg call, mbufs are not freed when EINVAL is returned01g,06oct97,spm added optional binary compatibility for BSD 4.3 applications01f,25jul97,vin fixed so_accept function call, saved new fd in the socket structure.01e,03dec96,vin changed m_getclr to fit the new declaration.01d,22nov96,vin modified for BSD44.01c,07aug95,dzb NOMANUAL on headers.01b,25jul95,dzb changed to just use DEV_HDR device header.01a,21jul95,dzb created from sockLib.c, ver 04g.*//*This library provides UNIX BSD 4.4 compatible socket calls. These callsmay be used to open, close, read, and write sockets, either on the sameCPU or over a network. The calling sequences of these routines areidentical to UNIX BSD 4.4.ADDRESS FAMILYVxWorks sockets support only the Internet Domain address family; useAF_INET for the <domain> argument in subroutines that require it.There is no support for the UNIX Domain address family.IOCTL FUNCTIONSSockets respond to the following ioctl() functions. These functions aredefined in the header files ioLib.h and ioctl.h..iP "FIONBIO" 18 3Turns on/off non-blocking I/O..CS on = TRUE; status = ioctl (sFd, FIONBIO, &on);.CE.iP "FIONREAD"Reports the number of bytes available to read on the socket. On the returnof ioctl(), <bytesAvailable> has the number of bytes available to readon the socket..CS status = ioctl (sFd, FIONREAD, &bytesAvailable);.CE.iP "SIOCATMARK"Reports whether there is out-of-band data to be read on the socket. Onthe return of ioctl(), <atMark> will be TRUE (1) if there is out-of-banddata, otherwise it will be FALSE (0)..CS status = ioctl (sFd, SIOCATMARK, &atMark);.CEINCLUDE FILES: types.h, bsdSockLib.h, socketvar.hSEE ALSO: netLib,.pG "Network"NOMANUAL*/#include "vxWorks.h"#include "sockFunc.h"#include "bsdSockMap.h" /* map socket routines to bsdxxx() */#include "strLib.h"#include "errnoLib.h"#include "netLib.h"#include "ioLib.h"#include "iosLib.h"#include "tickLib.h"#include "vwModNum.h"#include "net/systm.h"#include "net/mbuf.h"#include "net/protosw.h"#include "net/socketvar.h"#include "net/uio.h"#include "bsdSockLib.h"#include "netinet/in.h"#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#endif /* VIRTUAL_STACK */IMPORT STATUS soo_ioctl (); /* for call into sys_socket.c *//* locals */LOCAL DEV_HDR bsdSockDev; /* BSD-specific device header */LOCAL int bsdSockDrvNum; /* BSD socket driver number */LOCAL char * bsdSockName = "(socket)"; /* file name of BSD sockets *//* globals */BOOL bsdSock43ApiFlag = FALSE; /* Provide backward binary */ /* compatibility for BSD 4.3? */ /* (Set TRUE by default with */ /* BSD43_COMPATIBLE in configAll.h). */IMPORT SOCK_FUNC ** pSockFdMap;/* declare BSD socket interface function table */SOCK_FUNC bsdSockFunc = { (FUNCPTR) sockLibInit, (FUNCPTR) accept, (FUNCPTR) bind, (FUNCPTR) connect, (FUNCPTR) connectWithTimeout, (FUNCPTR) getpeername, (FUNCPTR) getsockname, (FUNCPTR) listen, (FUNCPTR) recv, (FUNCPTR) recvfrom, (FUNCPTR) recvmsg, (FUNCPTR) send, (FUNCPTR) sendto, (FUNCPTR) sendmsg, (FUNCPTR) shutdown, (FUNCPTR) socket, (FUNCPTR) getsockopt, (FUNCPTR) setsockopt, (FUNCPTR) zbufsockrtn };/* forward declarations */LOCAL STATUS bsdSockClose (struct socket *so);LOCAL int bsdSockWrite (struct socket *so, char *buf, int bufLen);LOCAL int bsdSockRead (struct socket *so, caddr_t buf, int bufLen);LOCAL int bsdSockargs (struct mbuf ** aname, caddr_t name, int namelen, int type);LOCAL void bsdSockAddrRevert (struct sockaddr *);#ifdef VIRTUAL_STACKLOCAL STATUS stackInstFromSockVsidSet (int s);#endif /* VIRTUAL_STACK *//********************************************************************************* bsdSockLibInit - install the BSD "socket driver" into the I/O system** bsdSockLibInit must be called once at configuration time before any socket* operations are performed.** RETURNS: a pointer to the BSD socket table, or NULL.** NOMANUAL*/SOCK_FUNC * sockLibInit (void) { if (bsdSockDrvNum > 0) return (&bsdSockFunc); if ((bsdSockDrvNum = iosDrvInstall ((FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) bsdSockClose, (FUNCPTR) bsdSockRead, (FUNCPTR) bsdSockWrite, (FUNCPTR) soo_ioctl)) == ERROR) return (NULL); bsdSockDev.drvNum = bsdSockDrvNum; /* to please I/O system */ bsdSockDev.name = bsdSockName; /* for iosFdSet name optimiz. */ return (&bsdSockFunc); }/********************************************************************************* bsdSocket - open a socket** This routine opens a socket and returns a socket descriptor.* The socket descriptor is passed to the other socket routines to identify the* socket. The socket descriptor is a standard I/O system file descriptor* (fd) and can be used with the close(), read(), write(), and ioctl() routines.** Available socket types include:* .iP SOCK_STREAM 18* connection-based (stream) socket.* .iP SOCK_DGRAM* datagram (UDP) socket.* .iP SOCK_RAW* raw socket.* .LP** RETURNS: A socket descriptor, or ERROR.** NOMANUAL*/int socket ( int domain, /* address family (e.g. AF_INET) */ int type, /* SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW */ int protocol /* socket protocol (usually 0) */ ) { struct socket *so; int fd;#ifndef _WRS_VXWORKS_5_X OBJ_ID fdObject;#endif FAST int spl = splnet (); int status = socreate (domain, &so, type, protocol); splx (spl); if (status) { netErrnoSet (status); return (ERROR); } /* stick the socket into a file descriptor */ if ((fd = iosFdNew ((DEV_HDR *) &bsdSockDev, bsdSockName, (int) so)) == ERROR) { (void)bsdSockClose (so); return (ERROR); }#ifndef _WRS_VXWORKS_5_X /* set ownership of socket semaphores */ fdObject = iosFdObjIdGet (fd); if (fdObject == NULL) { (void)bsdSockClose (so); return (ERROR); } status = objOwnerSet (so->so_timeoSem, fdObject); if (status == ERROR) { (void)bsdSockClose (so); return (ERROR); } status = objOwnerSet (so->so_rcv.sb_Sem, fdObject); if (status == ERROR) { (void)bsdSockClose (so); return (ERROR); } status = objOwnerSet (so->so_snd.sb_Sem, fdObject); if (status == ERROR) { (void)bsdSockClose (so); return (ERROR); }#endif /* _WRS_VXWORKS_5_X */ /* save fd in the socket structure */ so->so_fd = fd;#ifdef VIRTUAL_STACK /* set the vsid in the socket to the current stack */ status = setsockopt (fd, SOL_SOCKET, SO_VSID, (char *)&myStackNum, sizeof (myStackNum)); if (status) { netErrnoSet (status); (void)bsdSockClose (so); return (ERROR); }#endif /* VIRTUAL_STACK */ return (fd); }/********************************************************************************* bsdSockClose - close a socket** bsdSockClose is called by the I/O system to close a socket.**/LOCAL STATUS bsdSockClose ( struct socket *so ) { FAST int ret; FAST int sx; int fd;#ifdef VIRTUAL_STACK /* Check if we are in the correct stack */ if (stackInstFromSockVsidSet (so->so_fd) != OK) return (ERROR);#endif /* VIRTUAL_STACK */ sx = splnet (); fd = so->so_fd; if (so->so_state & SS_NOFDREF) ret = 0; else ret = soclose (so); splx (sx); /* * Remove the mapping installed by the switchboard. Performing this * step here is ugly, but the alternative is worse. */ pSockFdMap [fd] = NULL; return (ret); }/********************************************************************************* bsdBind - bind a name to a socket** This routine associates a network address (also referred to as its "name")* with a specified socket so that other processes can connect or send to it.* When a socket is created with socket(), it belongs to an address family* but has no assigned name.** RETURNS:* OK, or ERROR if there is an invalid socket, the address is either* unavailable or in use, or the socket is already bound.** NOMANUAL*/STATUS bind ( int s, /* socket descriptor */ struct sockaddr *name, /* name to be bound */ int namelen /* length of name */ ) { struct mbuf *nam; int status; struct socket *so; /* extract the socket from the fd */ if ((so = (struct socket *) iosFdValue (s)) == (struct socket *) ERROR) return (ERROR);#ifdef VIRTUAL_STACK if (stackInstFromSockVsidSet (s) != OK) return (ERROR);#endif /* VIRTUAL_STACK */ status = bsdSockargs (&nam, (caddr_t) name, namelen, MT_SONAME); if (status) { netErrnoSet (status); return (ERROR); } status = sobind (so, nam); if (status) { netErrnoSet (status); m_freem (nam); return (ERROR); } m_freem (nam); return (OK); }/********************************************************************************* bsdListen - enable connections to a socket** This routine enables connections to a socket. It also specifies the* maximum number of unaccepted connections that can be pending at one time* (<backlog>). After enabling connections with listen(), connections are* actually accepted by accept().** RETURNS: OK, or ERROR if the socket is invalid or unable to listen.** NOMANUAL*/STATUS listen ( int s, /* socket descriptor */ int backlog /* number of connections to queue */ ) { FAST int status; FAST struct socket *so; /* extract the socket from the fd */ if ((so = (struct socket *) iosFdValue (s)) == (struct socket *) ERROR) return (ERROR);#ifdef VIRTUAL_STACK if (stackInstFromSockVsidSet (s) != OK) return (ERROR);#endif /* VIRTUAL_STACK */ status = solisten (so, backlog); if (status) { netErrnoSet (status); return (ERROR); }#if (CPU == SIMHPPA)/* * Set the size of the receive buffer. * This is the way (without rewriting the user app) to get * data from the master to auto-segment and fit in the pty. */{ int bLen = 660; return (setsockopt (s, SOL_SOCKET, SO_RCVBUF, &bLen, sizeof (bLen)));}#endif return (OK); }/********************************************************************************* bsdAccept - accept a connection from a socket** This routine accepts a connection on a socket, and returns a new socket* created for the connection. The socket must be bound to an address with* bind(), and enabled for connections by a call to listen(). The accept()* routine dequeues the first connection and creates a new socket with the* same properties as <s>. It blocks the caller until a connection is* present, unless the socket is marked as non-blocking.** The parameter <addrlen> should be initialized to the size of the available* buffer pointed to by <addr>. Upon return, <addrlen> contains the size in* bytes of the peer's address stored in <addr>.** RETURNS* A socket descriptor, or ERROR if the call fails.** NOMANUAL*/int accept ( int s, /* socket descriptor */ struct sockaddr *addr, /* peer address */ int *addrlen /* peer address length */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -