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

📄 io.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif	    client->req_len = needed;	    needed <<= 2;	}	if (gotnow < needed)	{	    /* Still don't have enough; punt. */	    YieldControlNoInput();	    return 0;	}    }    if (needed == 0)    {#ifdef BIGREQS	if (client->big_requests)	    needed = sizeof(xBigReq);	else#endif	    needed = sizeof(xReq);    }    oci->lenLastReq = needed;    /*     *  Check to see if client has at least one whole request in the     *  buffer beyond the request we're returning to the caller.     *  If there is only a partial request, treat like buffer     *  is empty so that select() will be called again and other clients     *  can get into the queue.        */    gotnow -= needed;    if (gotnow >= sizeof(xReq))     {	request = (xReq *)(oci->bufptr + needed);	if (gotnow >= (result = (get_req_len(request, client) << 2))#ifdef BIGREQS	    && (result ||		(client->big_requests &&		 (gotnow >= sizeof(xBigReq) &&		  gotnow >= (get_big_req_len(request, client) << 2))))#endif	    )	    FD_SET(fd, &ClientsWithInput);	else	    YieldControlNoInput();    }    else    {	if (!gotnow)	    AvailableInput = oc;	YieldControlNoInput();    }    if (++timesThisConnection >= MAX_TIMES_PER)	YieldControl();#ifdef BIGREQS    if (move_header)    {	request = (xReq *)oci->bufptr;	oci->bufptr += (sizeof(xBigReq) - sizeof(xReq));	*(xReq *)oci->bufptr = *request;	oci->lenLastReq -= (sizeof(xBigReq) - sizeof(xReq));	client->req_len -= (sizeof(xBigReq) - sizeof(xReq)) >> 2;    }#endif    client->requestBuffer = (pointer)oci->bufptr;    return needed;}/***************************************************************** * InsertFakeRequest *    Splice a consed up (possibly partial) request in as the next request. * **********************/BoolInsertFakeRequest(client, data, count)    ClientPtr client;    char *data;    int count;{    OsCommPtr oc = (OsCommPtr)client->osPrivate;    register ConnectionInputPtr oci = oc->input;    int fd = oc->fd;    register int gotnow, moveup;    if (AvailableInput)    {	if (AvailableInput != oc)	{	    register ConnectionInputPtr aci = AvailableInput->input;	    if (aci->size > BUFWATERMARK)	    {		xfree(aci->buffer);		xfree(aci);	    }	    else	    {		aci->next = FreeInputs;		FreeInputs = aci;	    }	    AvailableInput->input = (ConnectionInputPtr)NULL;	}	AvailableInput = (OsCommPtr)NULL;    }    if (!oci)    {	if (oci = FreeInputs)	    FreeInputs = oci->next;	else if (!(oci = AllocateInputBuffer()))	    return FALSE;	oc->input = oci;    }    oci->bufptr += oci->lenLastReq;    oci->lenLastReq = 0;    gotnow = oci->bufcnt + oci->buffer - oci->bufptr;    if ((gotnow + count) > oci->size)    {	char *ibuf;	ibuf = (char *)xrealloc(oci->buffer, gotnow + count);	if (!ibuf)	    return(FALSE);	oci->size = gotnow + count;	oci->buffer = ibuf;	oci->bufptr = ibuf + oci->bufcnt - gotnow;    }    moveup = count - (oci->bufptr - oci->buffer);    if (moveup > 0)    {	if (gotnow > 0)	    memmove(oci->bufptr + moveup, oci->bufptr, gotnow);	oci->bufptr += moveup;	oci->bufcnt += moveup;    }    memmove(oci->bufptr - count, data, count);    oci->bufptr -= count;    gotnow += count;    if ((gotnow >= sizeof(xReq)) &&	(gotnow >= (int)(get_req_len((xReq *)oci->bufptr, client) << 2)))	FD_SET(fd, &ClientsWithInput);    else	YieldControlNoInput();    return(TRUE);}/***************************************************************** * ResetRequestFromClient *    Reset to reexecute the current request, and yield. * **********************/ResetCurrentRequest(client)    ClientPtr client;{    OsCommPtr oc = (OsCommPtr)client->osPrivate;    register ConnectionInputPtr oci = oc->input;    int fd = oc->fd;    register xReq *request;    int gotnow, needed;#ifdef LBX    Bool part;    LbxClientPtr lbxClient = LbxClient(client);    if (lbxClient) {	LbxSetForBlock(lbxClient);	if (!oci) {	    AppendFakeRequest(client,			      client->requestBuffer, client->req_len << 2);	    return;	}    }#endif    if (AvailableInput == oc)	AvailableInput = (OsCommPtr)NULL;    oci->lenLastReq = 0;    gotnow = oci->bufcnt + oci->buffer - oci->bufptr;    if (gotnow < sizeof(xReq))    {	YieldControlNoInput();    }    else    {	request = (xReq *)oci->bufptr;	needed = get_req_len(request, client);#ifdef BIGREQS	if (!needed && client->big_requests)	{	    oci->bufptr -= sizeof(xBigReq) - sizeof(xReq);	    *(xReq *)oci->bufptr = *request;	    ((xBigReq *)oci->bufptr)->length = client->req_len;	    if (client->swapped)	    {		char n;		swapl(&((xBigReq *)oci->bufptr)->length, n);	    }	}#endif	if (gotnow >= (needed << 2))	{	    if (FD_ISSET(fd, &AllClients))	    {		FD_SET(fd, &ClientsWithInput);	    }	    else	    {		FD_SET(fd, &IgnoredClientsWithInput);	    }	    YieldControl();	}	else	    YieldControlNoInput();    }}/***************************************************************** *  PeekNextRequest and SkipRequests were implemented to support DBE  *  idioms, but can certainly be used outside of DBE.  There are two  *  related macros in os.h, ReqLen and CastxReq.  See the porting  *  layer document for more details. * **********************//***************************************************************** *  PeekNextRequest *      lets you look ahead at the unexecuted requests in a  *      client's request buffer. * *      Note: this implementation of PeekNextRequest ignores the *      readmore parameter. * **********************/xReqPtrPeekNextRequest(req, client, readmore)    xReqPtr req;	/* request we're starting from */    ClientPtr client;	/* client whose requests we're skipping */    Bool readmore;	/* attempt to read more if next request isn't there? */{    register ConnectionInputPtr oci = ((OsCommPtr)client->osPrivate)->input;    xReqPtr pnextreq;    int needed, gotnow, reqlen;    if (!oci) return NULL;    if (!req)    {	/* caller wants the request after the one currently being executed */	pnextreq = (xReqPtr)	    (((CARD32 *)client->requestBuffer) + client->req_len);    }    else    {	/* caller wants the request after the one specified by req */	reqlen = get_req_len(req, client);#ifdef BIGREQS	if (!reqlen) reqlen = get_big_req_len(req, client);#endif	pnextreq = (xReqPtr)(((char *)req) + (reqlen << 2));    }    /* see how much of the next request we have available */    gotnow = oci->bufcnt - (((char *)pnextreq) - oci->buffer);    if (gotnow < sizeof(xReq))	return NULL;    needed = get_req_len(pnextreq, client) << 2;#ifdef BIGREQS    if (!needed)    {	/* it's a big request */	if (gotnow < sizeof(xBigReq))	    return NULL;	needed = get_big_req_len(pnextreq, client) << 2;    }#endif    /* if we have less than we need, return NULL */    return (gotnow < needed) ? NULL : pnextreq;}/***************************************************************** *  SkipRequests  *      lets you skip over some of the requests in a client's *      request buffer.  Presumably the caller has used PeekNextRequest *      to examine the requests being skipped and has performed whatever  *      actions they dictate. * **********************/CallbackListPtr SkippedRequestsCallback = NULL;voidSkipRequests(req, client, numskipped)    xReqPtr req;	/* last request being skipped */    ClientPtr client;   /* client whose requests we're skipping */    int numskipped;	/* how many requests we're skipping */{    OsCommPtr oc = (OsCommPtr)client->osPrivate;    register ConnectionInputPtr oci = oc->input;    int reqlen;    /* see if anyone wants to snoop the skipped requests */    if (SkippedRequestsCallback)    {	SkippedRequestInfoRec skipinfo;	skipinfo.req = req;	skipinfo.client = client;	skipinfo.numskipped = numskipped;	CallCallbacks(&SkippedRequestsCallback, &skipinfo);    }    /* adjust the sequence number */    client->sequence += numskipped;    /* twiddle the oci to skip over the requests */    reqlen = get_req_len(req, client);#ifdef BIGREQS    if (!reqlen) reqlen = get_big_req_len(req, client);#endif    reqlen <<= 2;    oci->bufptr = (char *)req;    oci->lenLastReq = reqlen;    /* see if any requests left in the buffer */    if ( ((char *)req + reqlen) == (oci->buffer + oci->bufcnt) )    {	/* no requests; mark input buffer as available and client	 * as having no input	 */	int fd = oc->fd;	AvailableInput = oc;	YieldControlNoInput();    }}    /* lookup table for adding padding bytes to data that is read from    	or written to the X socket.  */static int padlength[4] = {0, 3, 2, 1}; /******************** * FlushClient() *    If the client isn't keeping up with us, then we try to continue *    buffering the data and set the apropriate bit in ClientsWritable *    (which is used by WaitFor in the select).  If the connection yields *    a permanent error, or we can't allocate any more space, we then *    close the connection. * **********************/int#ifdef LBXStandardFlushClient(who, oc, extraBuf, extraCount)#elseFlushClient(who, oc, extraBuf, extraCount)#endif    ClientPtr who;    OsCommPtr oc;    char *extraBuf;    int extraCount; /* do not modify... returned below */{    register ConnectionOutputPtr oco = oc->output;    int connection = oc->fd;    XtransConnInfo trans_conn = oc->trans_conn;    struct iovec iov[3];    static char padBuffer[3];    long written;    long padsize;    long notWritten;    long todo;    if (!oco)	return 0;    written = 0;    padsize = padlength[extraCount & 3];    notWritten = oco->count + extraCount + padsize;    todo = notWritten;    while (notWritten) {	long before = written;	/* amount of whole thing written */	long remain = todo;	/* amount to try this time, <= notWritten */	int i = 0;	long len;	/* You could be very general here and have "in" and "out" iovecs	 * and write a loop without using a macro, but what the heck.  This	 * translates to:	 *	 *     how much of this piece is new?	 *     if more new then we are trying this time, clamp	 *     if nothing new	 *         then bump down amount already written, for next piece	 *         else put new stuff in iovec, will need all of next piece	 *	 * Note that todo had better be at least 1 or else we'll end up	 * writing 0 iovecs.	 */#define InsertIOV(pointer, length) \	len = (length) - before; \	if (len > remain) \	    len = remain; \	if (len <= 0) { \	    before = (-len); \	} else { \	    iov[i].iov_len = len; \	    iov[i].iov_base = (pointer) + before; \	    i++; \	    remain -= len; \	    before = 0; \	}	InsertIOV ((char *)oco->buf, oco->count)	InsertIOV (extraBuf, extraCount)

⌨️ 快捷键说明

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