📄 plumbing.c
字号:
/* ********************************************************************** * * <copyright> * * BBN Technologies, a Verizon Company * 10 Moulton Street * Cambridge, MA 02138 * (617) 873-8000 * * Copyright (C) BBNT Solutions LLC. All rights reserved. * * </copyright> * ********************************************************************** * * $Source: /cvs/distapps/openmap/src/cserver/toolLib/src/plumbing.c,v $ * $RCSfile: plumbing.c,v $ * $Revision: 1.2 $ * $Date: 2004/01/26 19:07:10 $ * $Author: dietrick $ * * ********************************************************************** *//* SYSTEM HEADER FILES */#ifdef _AIX#include <sys/select.h>#endif#include <sys/time.h>#include <sys/resource.h>#include <sys/types.h>#include <errno.h>#include <stdio.h> #ifdef c_plusplus#include <sysent.h>#endif/* TOOL HEADER FILES */#include "compat.h"#define DEBUG_ME "DEBUG_TOOLLIB"#include "debugging.h"#include "style.h"#include "error_hand.h"#include "free_mgr.h"#include "sockets.h"/* LOCAL HEADER FILES */#include "plumbing.h"DebugVariable(plumbing, "plumbing", 0x01);#ifdef TK#include <tk.h>#endif/*------------------------------------------------------------------------ * * Deal with another event loop... * *------------------------------------------------------------------------*/typedef enum{ EventMode_Plumbing, EventMode_Tk} EventMode;/* Default the event mode to Normal */EventMode eventMode = EventMode_Plumbing;/*------------------------------------------------------------------------ * * File Descriptor support * * These functions take care of hooking callback functions up to * file descriptor events. * *------------------------------------------------------------------------*//* * From sys/types.h */#define MaxFds FD_SETSIZE#define LegalFd(fd) ((fd) >= 0 && (fd) < MaxFds)static int nFds = 0;static int maxFd = 0;static fd_set readFds;static fd_set writeFds;static int initialized = 0;#define TraceData (0x01)typedef struct _fdSupport{ int fd; FdCBProc callback; const char *callbackName; char *clientData; int flag;} FdSupport;static FdSupport ifds[MaxFds];static FdSupport ofds[MaxFds];static char peekBuf[16 * 1024];static Bool keepLooping = True;void StopLoopOnFds(){ keepLooping = False;}/* ------------------------------------------------------------------------ * * LoopOnFds Continuously loops on select() of the active * file descriptors * * RETURNS: -1 on failure * 0 if someone called StopLoopOnFds() * * ------------------------------------------------------------------------ */LoopOnFds(){ int result = 0; int status; int fd; int nBytes; int none_read; struct rlimit rlimit; struct timeval *forEver = (struct timeval *) 0; fd_set rFds; fd_set wFds; if(initialized == 0) return(-1); /* * Assuming that no one expands the dtable size within the program! */#ifdef RLIMIT_NOFILE getrlimit(RLIMIT_NOFILE, &rlimit);#else rlimit.rlim_cur = getdtablesize();#endif maxFd = rlimit.rlim_cur; /* * Turn the keepLooping flag on. If someone calls StopLoopOnFds(), * we'll stop looping and fall out of here. */ keepLooping = True; while(keepLooping && nFds > 0) { /* * Copy the master set into the local set since select(2) * will be modifying the ones we pass in to it. */ rFds = readFds; wFds = writeFds; #ifdef __hpux result = select(maxFd, (int*)&rFds, (int*)&wFds, (int *) 0, forEver);#else result = select(maxFd, &rFds, &wFds, (fd_set *) 0, forEver);#endif /* * returning from select may be the result of an interrupted * system call. */ if(result < 0) { switch(errno) { case EINTR: break; case EBADF: WeedOutBadFds(); break; default: break; } continue; } if(result < 0) { WARNING_PERROR("Error in select call"); return(ErrorReturn); } none_read = 1; for(fd = 0; result > 0 && fd < maxFd; fd++) { if(FD_ISSET(fd, &rFds)) { none_read = 0; if(ifds[fd].callback != (FdCBProc) 0) { if(Debug(plumbing)) { nBytes = socket_count(fd); sprintf(msgBuf, "Calling %s(%d...) ( %05d bytes )", ifds[fd].callbackName, fd, nBytes); DEBUG_MESSAGE(msgBuf); if(ifds[fd].flag & TraceData) { if(nBytes > sizeof(peekBuf)) nBytes = sizeof(peekBuf); socket_peek(fd, peekBuf, nBytes); PrintTrace(fd, peekBuf, nBytes, 'I'); } } status = (*(ifds[fd].callback)) (fd, ifds[fd].clientData); if(status == ErrorReturn) { DisconnectInputFd(fd); DisconnectOutputFd(fd); } } else { sprintf(msgBuf, "Uncaught Read Select on fd %d", fd); WARNING_MESSAGE(msgBuf); } result--; } if(FD_ISSET(fd, &wFds)) { if (none_read) { if(ofds[fd].callback != (FdCBProc) 0) { if(Debug(plumbing)) { sprintf(msgBuf, "Calling %s(%d...)", ofds[fd].callbackName, fd); DEBUG_MESSAGE(msgBuf); } status = (*(ofds[fd].callback)) (fd, ofds[fd].clientData); if(status == ErrorReturn) { DisconnectInputFd(fd); DisconnectOutputFd(fd); } } else { sprintf(msgBuf, "Uncaught Write Select on fd %d", fd); WARNING_MESSAGE(msgBuf); } } result--; } } } return(result);}int PrintTrace( int fd, char *buf, int nBytes, char direction){ int i; if(initialized == 0) InitFds(); printf("Trace (%c) fd %02d:", direction, fd); for(i = 0; i < nBytes; i++) { /* SUPPRESS 112 *//* CodeCenter Retrieving x from y object is z */ printf("%02x ", (buf[i] & 0xFF)); } printf("\n"); return(nBytes);}/* ------------------------------------------------------------------------ * * InitFds Init the file descriptor handling stuff. * * RETURNS: -1 on failure * * ------------------------------------------------------------------------ */int InitFds(){ int fd; if(initialized != 0) return(NormalReturn); initialized = 1; maxFd = 0; nFds = 0; FD_ZERO(&readFds); FD_ZERO(&writeFds); for(fd = 0; fd < MaxFds; fd++) { ifds[fd].fd = -1; ifds[fd].callback = (FdCBProc) 0; ifds[fd].callbackName = "No Callback Defined"; ifds[fd].clientData = (char *) 0; ifds[fd].flag = 0; ofds[fd].fd = -1; ofds[fd].callback = (FdCBProc) 0; ofds[fd].callbackName = "No Callback Defined"; ofds[fd].clientData = (char *) 0; ofds[fd].flag = 0; } return(0);}int InitTkFds (){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -