📄 smaskwait.c
字号:
/* Smaskwait.c: this file contains code which allows one to wait until data * is present given a mask */#include <stdio.h>#include "xtdio.h"#define SSLNEEDTIME#include "sockets.h"/* --------------------------------------------------------------------- * Local Variables: */static int waitall = 0; static fd_set mask; /* mask last-used by Smaskwait, etc */static struct timeval *timeptr = NULL;static struct timeval timewait;static fd_set rmask; /* set by Smaskwait */static int first = 1; /* --------------------------------------------------------------------- * Local Prototypes: *//* --------------------------------------------------------------------- * Source Code: *//* Smaskwait: this function waits until some Socket specified to the * Smaskset() function receives something. * * Returns: < 0: error * ==0: timeout * > 0: communication data awaiting * * NOTE: THE MASK IS NOT RESET TO ZERO - THE MASK IS RETAINED!!! */#ifdef __PROTOTYPE__int Smaskwait()#elseint Smaskwait()#endif{fd_set wmask; /* write mask */fd_set emask; /* error mask */short result;FD_ZERO(&wmask);FD_ZERO(&emask);/* test if something is available for reading on the socket. This form * will block (sleep) until something arrives */rmask = mask;result = select(waitall, &rmask,&wmask,&emask,timeptr);if(result < 0) { /* error */ return result; }/* result > 0: socket has something waiting * result == 0: timeout */return result;}/* --------------------------------------------------------------------- *//* Smaskset: this function sets up the mask * A null skt clears the mask */#ifdef __PROTOTYPE__void Smaskset(Socket *skt)#elsevoid Smaskset(skt)Socket *skt;#endif{if(first) { FD_ZERO(&mask); first= 0; }if(skt) { FD_SET(skt->skt,&mask); if(skt->skt >= waitall) waitall= skt->skt + 1; }else { waitall= 0; FD_ZERO(&mask); }}/* --------------------------------------------------------------------- *//* Smaskfdset: this function sets up the mask with a "file descriptor" * which may be associated with devices other than Sockets */#ifdef __PROTOTYPE__void Smaskfdset(int fd)#elsevoid Smaskfdset(fd)int fd;#endif{if(first) { FD_ZERO(&mask); first= 0; }if(0 <= fd && fd < FD_SETSIZE) { /* fd must be a legal file descriptor */ FD_SET(fd,&mask); if(fd >= waitall) waitall= fd + 1; }}/* --------------------------------------------------------------------- *//* Smasktime: this function sets up a timeval structure - specifies a * time limit for waiting. Note: if seconds < 0 or useconds < 0, * or seconds == useconds == 0, then there will be no timeout waiting. */#ifdef __PROTOTYPE__void Smasktime(long seconds,long useconds)#elsevoid Smasktime(seconds,useconds)long seconds; /* time in seconds */long useconds; /* time in micro-seconds */#endif{if(seconds < 0 || useconds < 0 || (seconds == 0 && useconds == 0)) { /* no timeout (ie. infinite wait) */ timewait.tv_sec = 0L; timewait.tv_usec= 0L; timeptr = (struct timeval *) NULL; }else { /* set up specified timeout */ timewait.tv_sec = seconds; timewait.tv_usec= useconds; timeptr = &timewait; }}/* --------------------------------------------------------------------- *//* Smasktest: this function allows one to test if any Socket in the * mask has something on it * Returns: < 0: error * ==0: timeout * > 0: communication data awaiting */int Smasktest(){int ret;struct timeval timewait_hold;struct timeval *timeptr_hold=NULL;/* save current time info */timewait_hold = timewait;timeptr_hold = timeptr;/* set up for new time info */timewait.tv_sec = 0L;timewait.tv_usec= 0L;timeptr = &timewait;ret= Smaskwait();/* restore time info */timewait= timewait_hold;timeptr = timeptr_hold;return ret;}/* --------------------------------------------------------------------- *//* Smaskunset: this function sets up the mask * A null skt clears the mask */#ifdef __PROTOTYPE__void Smaskunset(Socket *skt)#elsevoid Smaskunset(skt)Socket *skt;#endif{if(skt) { FD_CLR(skt->skt,&mask); }else { waitall= 0; FD_ZERO(&mask); }}/* --------------------------------------------------------------------- *//* Smaskunfdset: this function sets up the mask * A null skt clears the mask */#ifdef __PROTOTYPE__void Smaskunfdset(int fd)#elsevoid Smaskunfdset(fd)int fd;#endif{if(fd) FD_CLR(fd,&mask);else { waitall= 0; FD_ZERO(&mask); }}/* --------------------------------------------------------------------- *//* Smaskget: this function returns the current mask */#ifdef __PROTOTYPE__Smask Smaskget()#elseSmask Smaskget()#endif{Smask smask;smask.mask = mask;smask.waitall= waitall;return smask;}/* --------------------------------------------------------------------- *//* Smaskuse: this function sets up the mask with the provided mask */#ifdef __PROTOTYPE__void Smaskuse(Smask usermask)#elsevoid Smaskuse(usermask)Smask usermask;#endif{mask = usermask.mask;waitall= usermask.waitall;}/* --------------------------------------------------------------------- */typedef struct MaskStack_str MaskStack;struct MaskStack_str { Smask mask; MaskStack *nxt,*prv; };static MaskStack *mshd=NULL,*mstl=NULL;/* Smaskpush: this function pushes the current mask down on a stack * ALSO: the current mask is *cleared*!!! */void Smaskpush(){MaskStack *m;/* allocate */m= (MaskStack *) malloc(sizeof(MaskStack));/* link */if(mstl) mstl->nxt= m;else mshd = m;m->prv= mstl;mstl = m;/* initialize */mstl->mask.mask = mask;mstl->mask.waitall= waitall;Smaskset((Socket *) NULL);}/* --------------------------------------------------------------------- *//* Smaskpop: this function pops the stack (or, if the stack is empty, * it will set the current mask to null) */void Smaskpop(){if(mstl) { MaskStack *old=mstl; Smaskuse(mstl->mask); /* delink current tail */ if(mstl->prv) mstl->prv->nxt= NULL; else mshd = NULL; mstl= mstl->prv; free((char *) old); }else Smaskset((Socket *) NULL);}/* --------------------------------------------------------------------- *//* Smaskisset: this function tests if a specific Socket is read-ready. * Assumption: function is called after a Smaskwait() so that the * rmask has been set up. */#ifdef __PROTOTYPE__int Smaskisset(Socket *skt)#elseint Smaskisset(skt)Socket *skt;#endif{int ret;ret= FD_ISSET(skt->skt,&rmask);return ret;}/* --------------------------------------------------------------------- *//* Smaskfdisset: this function tests if a specific file descriptor is * read-ready */#ifdef __PROTOTYPE__int Smaskfdisset(int fd)#elseint Smaskfdisset(fd)int fd;#endif{int ret;ret= FD_ISSET(fd,&rmask);return ret;}/* --------------------------------------------------------------------- *//* --------------------------------------------------------------------- * vim: ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -