#include "global.h" #include "mbuf.h" #include "socket.h" #include "usock.h" int so_los(up,protocol) struct usock *up; int protocol; { up->cb.local = (struct loc *) callocw(1,sizeof(struct loc)); up->cb.local->peer = up; /* connect to self */ up->type = TYPE_LOCAL_STREAM; up->cb.local->hiwat = LOCSFLOW; return 0; } int so_lod(up,protocol) struct usock *up; int protocol; { up->cb.local = (struct loc *) callocw(1,sizeof(struct loc)); up->cb.local->peer = up; /* connect to self */ up->type = TYPE_LOCAL_DGRAM; up->cb.local->hiwat = LOCDFLOW; return 0; } int so_lo_recv(up,bpp,from,fromlen) struct usock *up; struct mbuf **bpp; char *from; int *fromlen; { int s; while(up->cb.local != NULLLOC && up->cb.local->q == NULLBUF && up->cb.local->peer != NULLUSOCK){ if(up->noblock){ errno = EWOULDBLOCK; return -1; } else if((errno = pwait(up)) != 0){ return -1; } } if(up->cb.local == NULLLOC){ errno = EBADF; return -1; } if(up->cb.local->q == NULLBUF && up->cb.local->peer == NULLUSOCK){ errno = ENOTCONN; return -1; } /* For datagram sockets, this will return the * first packet on the queue. For stream sockets, * this will return everything. */ *bpp = dequeue(&up->cb.local->q); if(up->cb.local->q == NULLBUF && (up->cb.local->flags & LOC_SHUTDOWN)){ s = up - Usock + SOCKBASE; close_s(s); } psignal(up,0); return len_p(*bpp); } int so_los_send(up,bp,to) struct usock *up; struct mbuf *bp; char *to; { if(up->cb.local->peer == NULLUSOCK){ free_p(bp); errno = ENOTCONN; return -1; } append(&up->cb.local->peer->cb.local->q,bp); psignal(up->cb.local->peer,0); /* If high water mark has been reached, block */ while(up->cb.local->peer != NULLUSOCK && len_p(up->cb.local->peer->cb.local->q) >= up->cb.local->peer->cb.local->hiwat){ if(up->noblock){ errno = EWOULDBLOCK; return -1; } else if((errno = pwait(up->cb.local->peer)) != 0){ return -1; } } if(up->cb.local->peer == NULLUSOCK){ errno = ENOTCONN; return -1; } return 0; } int so_lod_send(up,bp,to) struct usock *up; struct mbuf *bp; char *to; { if(up->cb.local->peer == NULLUSOCK){ free_p(bp); errno = ENOTCONN; return -1; } enqueue(&up->cb.local->peer->cb.local->q,bp); psignal(up->cb.local->peer,0); /* If high water mark has been reached, block */ while(up->cb.local->peer != NULLUSOCK && len_q(up->cb.local->peer->cb.local->q) >= up->cb.local->peer->cb.local->hiwat){ if(up->noblock){ errno = EWOULDBLOCK; return -1; } else if((errno = pwait(up->cb.local->peer)) != 0){ return -1; } } if(up->cb.local->peer == NULLUSOCK){ errno = ENOTCONN; return -1; } return 0; } int so_lod_qlen(up,rtx) struct usock *up; int rtx; { int len; switch(rtx){ case 0: len = len_q(up->cb.local->q); break; case 1: if(up->cb.local->peer != NULLUSOCK) len = len_q(up->cb.local->peer->cb.local->q); break; } return len; } int so_los_qlen(up,rtx) struct usock *up; int rtx; { int len; switch(rtx){ case 0: len = len_p(up->cb.local->q) + len_p(up->ibuf); break; case 1: if(up->cb.local->peer != NULLUSOCK) len = len_p(up->cb.local->peer->cb.local->q) + len_p(up->obuf); break; } return len; } int so_loc_shut(up,how) struct usock *up; int how; { int s; s = up - Usock + SOCKBASE; if(up->cb.local->q == NULLBUF) close_s(s); else up->cb.local->flags = LOC_SHUTDOWN; return 0; } int so_loc_close(up) struct usock *up; { if(up->cb.local->peer != NULLUSOCK){ up->cb.local->peer->cb.local->peer = NULLUSOCK; psignal(up->cb.local->peer,0); } free_q(&up->cb.local->q); free(up->cb.local); return 0; } char * lopsocket(p) struct sockaddr *p; { return ""; } so_loc_stat(up) struct usock *up; { int s; s = up - Usock + SOCKBASE; tprintf("Inqlen: %d packets\n",socklen(s,0)); tprintf("Outqlen: %d packets\n",socklen(s,1)); return 0; }