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

📄 xlibint.c

📁 ftam等标准协议服务器和客户端的源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * $XConsortium: XlibInt.c,v 11.90 88/09/30 17:25:18 jim Exp $ */#include "copyright.h"/* Copyright    Massachusetts Institute of Technology    1985, 1986, 1987 *//* *	XlibInternal.c - Internal support routines for the C subroutine *	interface library (Xlib) to the X Window System Protocol V11.0. */#define NEED_EVENTS#define NEED_REPLIES#include <stdio.h>#include "Xlibint.h"#ifdef ISOCONN#include <isode/psap.h>#include <isode/tsap.h>#include <isode/isoservent.h>#endif /* ISOCONN */#ifdef CRAY/* * Cray UniCOS does not have readv and writev so we emulate */#include <sys/socket.h>static int readv (fd, iov, iovcnt)int fd;struct iovec *iov;int iovcnt;{	struct msghdr hdr;	hdr.msg_iov = iov;	hdr.msg_iovlen = iovcnt;	hdr.msg_accrights = 0;	hdr.msg_accrightslen = 0;	hdr.msg_name = 0;	hdr.msg_namelen = 0;	return (recvmsg (fd, &hdr, 0));}static int writev (fd, iov, iovcnt)int fd;struct iovec *iov;int iovcnt;{	struct msghdr hdr;	hdr.msg_iov = iov;	hdr.msg_iovlen = iovcnt;	hdr.msg_accrights = 0;	hdr.msg_accrightslen = 0;	hdr.msg_name = 0;	hdr.msg_namelen = 0;	return (sendmsg (fd, &hdr, 0));}#endif /* CRAY */#ifdef ISOCONN/* * Need these Convenience routines to map IO to T-service  * XXX * Should map error returns in td->td_reason into * errno's appropriately... *//* * Check if any bytes queued that could be read... */TBytesReadable(fd, ptr)int fd;long *ptr;{	struct TSAPdisconnect tds;        struct TSAPdisconnect *td = &tds;	int ret = TSelectOctets (fd, ptr, td);	if (ret == NOTOK) {		    fprintf(stderr, "Client TBytesReadable: %s\n", 			TErrString(td->td_reason));	}	return ret;}/* * need followinf for arg mismatch */UBytesReadable(fd, ptr)int fd;long *ptr;{	return ioctl(fd, FIONREAD, ptr);}/*  * Simple read from transport cx, client */TReadFromServer(fd, data, size)int fd;unsigned size;char *data;{	char *aptr = data;	struct TSAPdisconnect tds;	struct TSAPdisconnect *td = &tds;static struct TSAPdata txs;static struct TSAPdata *tx = &txs;static struct qbuf *qb;static char *qptr;static int ingot, qcpy, result = 0;	int q2data, ret;#ifdef ISODEBUG	if (isodexbug) {		fprintf(stderr, "TReadFromServer %d want %d (%d buffered)\n", 			fd, size, result);	}#endif /* ISODEBUG */	if (result == 0) {		if ((ret = TReadRequest(fd, tx, OK, td)) == NOTOK) {#ifdef ISODEBUG		    if (errno == EWOULDBLOCK) {			fprintf(stderr, "Client TReadReq would block: %s\n", 				TErrString(td->td_reason));			if (!DR_FATAL(td->td_reason))				errno = EWOULDBLOCK;			else				errno = EBADF;			return ret;		    }		    if (isodexbug)			    fprintf(stderr, "Client TReadReq: %s\n", 				TErrString(td->td_reason));#endif /* ISODEBUG *//* * map problems here - eg fTimeOut... */		    if (td->td_reason == DR_TIMER)			errno = EWOULDBLOCK;		    return ret;		}		result = tx->tx_cc;		qb = &(tx->tx_qbuf);		qptr = qb->qb_data;#ifdef ISODEBUG		if (isodexbug)			fprintf(stderr, "TReadRequest want %d got %d\n", 				size, result);#endif	} #ifdef ISODEBUG	else {		if (isodexbug)			fprintf(stderr, "TReadFromServer want %d buffered %d\n",				 size, result);	}#endif/* * Buffer it */        ingot = 0;        aptr = data;	for(ingot = 0, aptr = data, q2data = min(size, result); 		ingot<q2data;		aptr += qcpy, ingot+= qcpy) {	    int aleft = q2data - ingot;	    if (qb->qb_len > aleft) {		    qcpy = aleft;		    bcopy(qptr, aptr, qcpy);		    qptr += aleft;	    } else {		    qcpy = qb->qb_len;		    bcopy(qb->qb_data, aptr, qcpy);		    if ((qb = qb->qb_forw) == NULL)			break;		    qptr = qb->qb_data;	    }        }	if ((result -= ingot) <= 0) {		result = 0;		TXFREE(tx);	}	return ingot;}/* * Simple write on transport descriptor client */TWriteToServer(fd, data, size)int fd;unsigned size;char *data;{	struct TSAPdisconnect tds;        struct TSAPdisconnect *td = &tds;#ifdef ISODEBUG	if (isodexbug)		fprintf(stderr, "TWriteToServer %d: %d\n", fd, size);#endif	if (TDataRequest(fd, data, size, td) == NOTOK) {		if (errno != EWOULDBLOCK)			fprintf(stderr, "Client TDataReq: %s\n", 				TErrString(td->td_reason));		return -1;	} else		return size;}/* * This is really disgusting, as we do 2 copies - one qbuf into data, * one data into iovecs...should really do something utterly neater or * ask mtr to provide another T-Service interface for pre-alloced * bufs - ideally iovec style * * or change the structure of X to do async... */TReadvFromServer(fd, iov, iovcnt)int fd, iovcnt;struct iovec *iov;{	int i, size, result, left, bcp; 	char *data, *dp;	struct iovec *iovp;	for(i=0, size = 0, iovp = iov; i < iovcnt; i++, iovp++)		size += iovp->iov_len;#ifdef ISODEBUG	if (isodexbug)		fprintf(stderr, "TReadvFromServer %d, want %d\n", fd, size);#endif	if ((data = Xmalloc(size)) == NULL) {#ifdef ISODEBUG	    if (isodexbug)		    fprintf(stderr, "TReadvFromServer, malloc failed\n");#endif/* * Could map to EWOULDBLOCK...? */	    return(-1);	}/* * Note, TReadFromServer is written to *NOT* return more than size */	if ((result = TReadFromServer(fd, data, size)) == NOTOK) {	    if (errno != EWOULDBLOCK)		    fprintf(stderr, "TReadvReq err\n");	    return(-1);	}	left = result;	dp = data;	while (left > 0) {	    bcp = iov->iov_len;	    if (bcp > left )		bcp = left;	    bcopy(dp, iov->iov_base, bcp);	    if (bcp < left)		iov++;	    dp += bcp;	    left -= bcp;	}	Xfree(data);	return result;}/* * scatter gather write to transport descriptor */TWritevToServer(fd, iov, iovcnt)int fd, iovcnt;struct iovec *iov;{	struct TSAPdisconnect tds;	struct TSAPdisconnect *td = &tds;	struct udvec uv[64], *uvp;	int i, ret, tot = 0;/* * Yuck needs dynamicising, or else rely on * iov's being same as uv's */	if (iovcnt >= 64) {		fprintf(stderr, "Very Bad News i am afraid\n");		return -99;	}	for (i=0, uvp = uv; i<iovcnt; uvp++, iov++, i++) {		uvp->uv_base = iov->iov_base;		uvp->uv_len = iov->iov_len;		tot += uvp->uv_len;	}#ifdef ISODEBUG	if (isodexbug)		fprintf(stderr, "TWritevToServer %d: %d\n",fd, tot);#endif	uv[iovcnt].uv_base = NULLCP;	uv[iovcnt].uv_len = 0;	if ((ret = TWriteRequest(fd, uv, td)) == NOTOK) {	    if (errno != EWOULDBLOCK)		    fprintf(stderr, "Client TReadReq: %s\n", TErrString(td->td_reason));	    return -1;		}	return tot;}TDiscFromServer(fd)int fd;{	struct TSAPdisconnect tds;        struct TSAPdisconnect *td = &tds;        if (TDiscRequest(fd, NULLCP, 0, td) == NOTOK)                fprintf(stderr, "TDR failed %s\n", TErrString(td->td_reason));}#endif /* ISOCONN *//* * The following routines are internal routines used by Xlib for protocol * packet transmission and reception. * * XIOError(Display *) will be called if any sort of system call error occurs. * This is assumed to be a fatal condition, i.e., XIOError should not return. * * XError(Display *, XErrorEvent *) will be called whenever an X_Error event is * received.  This is not assumed to be a fatal condition, i.e., it is * acceptable for this procedure to return.  However, XError should NOT * perform any operations (directly or indirectly) on the DISPLAY. * * Routines declared with a return type of 'Status' return 0 on failure, * and non 0 on success.  Routines with no declared return type don't  * return anything.  Whenever possible routines that create objects return * the object they have created. */_XQEvent *_qfree = NULL;			/* NULL _XQEvent. */static int padlength[4] = {0, 3, 2, 1};    /* lookup table for adding padding bytes to data that is read from    	or written to the X socket.  */static xReq _dummy_request = {	0, 0, 0};/* * _XFlush - Flush the X request buffer.  If the buffer is empty, no * action is taken.  This routine correctly handles incremental writes. * This routine may have to be reworked if int < long. */_XFlush (dpy)	register Display *dpy;{	register long size, todo;	register int write_stat;	register char *bufindex;	size = todo = dpy->bufptr - dpy->buffer;	bufindex = dpy->bufptr = dpy->buffer;	/*	 * While write has not written the entire buffer, keep looping	 * until the entire buffer is written.  bufindex will be incremented	 * and size decremented as buffer is written out.	 */	while (size) {	    errno = 0;	    write_stat = WriteToServer(dpy->fd, bufindex, (int) todo);	    if (write_stat >= 0) {		size -= write_stat;		todo = size;		bufindex += write_stat;#ifdef EWOULDBLOCK	    } else if (errno == EWOULDBLOCK) {		_XWaitForWritable(dpy);#endif#ifdef SUNSYSV	    } else if (errno == 0) {		_XWaitForWritable(dpy);#endif#ifdef EMSGSIZE	    } else if (errno == EMSGSIZE) {		todo >>= 1;#endif	    } else {		/* Write failed! */		/* errno set by write system call. */		(*_XIOErrorFunction)(dpy);	    }	}	dpy->last_req = (char *)&_dummy_request;}int_XEventsQueued (dpy, mode)    register Display *dpy;    int mode;{	register int len;	int pend;	char buf[BUFSIZE];	register xReply *rep;		if (mode == QueuedAfterFlush)	    _XFlush(dpy);	if (BytesReadable(dpy->fd, (char *) &pend) < 0)	    (*_XIOErrorFunction)(dpy);	if ((len = pend) < SIZEOF(xReply))	    return(dpy->qlen);	/* _XFlush can enqueue events */	else if (len > BUFSIZE)	    len = BUFSIZE;	len /= SIZEOF(xReply);	pend = len * SIZEOF(xReply);	_XRead (dpy, buf, (long) pend);	/* no space between comma and type or else macro will die */	STARTITERATE (rep,xReply, buf, (len > 0), len--) {	    if (rep->generic.type == X_Error)		_XError(dpy, (xError *)rep);	    else   /* must be an event packet */		_XEnq(dpy, (xEvent *) rep);	}	ENDITERATE	return(dpy->qlen);}/* _XReadEvents - Flush the output queue, * then read as many events as possible (but at least 1) and enqueue them */_XReadEvents(dpy)	register Display *dpy;{	char buf[BUFSIZE];	long pend_not_register; /* because can't "&" a register variable */	register long pend;	register xEvent *ev;	Bool not_yet_flushed = True;	do {	    /* find out how much data can be read */	    if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0)	    	(*_XIOErrorFunction)(dpy);	    pend = pend_not_register;	    /* must read at least one xEvent; if none is pending, then	       we'll just flush and block waiting for it */	    if (pend < SIZEOF(xEvent)) {	    	pend = SIZEOF(xEvent);		/* don't flush until we block the first time */		if (not_yet_flushed) {		    int qlen = dpy->qlen;		    _XFlush (dpy);		    if (qlen != dpy->qlen) return;		    not_yet_flushed = False;		}	    }			    /* but we won't read more than the max buffer size */	    if (pend > BUFSIZE)	    	pend = BUFSIZE;	    /* round down to an integral number of XReps */	    pend = (pend / SIZEOF(xEvent)) * SIZEOF(xEvent);	    _XRead (dpy, buf, pend);	    /* no space between comma and type or else macro will die */	    STARTITERATE (ev,xEvent, buf, (pend > 0),			  pend -= SIZEOF(xEvent)) {		if (ev->u.u.type == X_Error)		    _XError (dpy, (xError *) ev);		else  /* it's an event packet; enqueue it */		    _XEnq (dpy, ev);	    }	    ENDITERATE	} while (dpy->head == NULL);}/*  * _XRead - Read bytes from the socket taking into account incomplete * reads.  This routine may have to be reworked if int < long. */_XRead (dpy, data, size)	register Display *dpy;	register char *data;	register long size;{	register long bytes_read;	if (size == 0) return;	errno = 0;	while ((bytes_read = ReadFromServer(dpy->fd, data, (int)size))		!= size) {	    	if (bytes_read > 0) {		    size -= bytes_read;		    data += bytes_read;		    }#ifdef EWOULDBLOCK		else if (errno == EWOULDBLOCK) {		    _XWaitForReadable(dpy);		    errno = 0;		}#endif		#ifdef SUNSYSV		else if (errno == 0) {		    _XWaitForReadable(dpy);		}#endif		else if (bytes_read == 0) {		    /* Read failed because of end of file! */		    errno = EPIPE;		    (*_XIOErrorFunction)(dpy);		    }		else  /* bytes_read is less than 0; presumably -1 */ {		    /* If it's a system call interrupt, it's not an error. */		    if (errno != EINTR)		    	(*_XIOErrorFunction)(dpy);		    }	    	 }}#ifdef WORD64/* * XXX This is a *really* stupid way of doing this.... */#define PACKBUFFERSIZE 4096/* * _XRead32 - Read bytes from the socket unpacking each 32 bits *            into a long (64 bits on a CRAY computer). *  */static _doXRead32 (dpy, data, size, packbuffer)        register Display *dpy;        register long *data;        register long size;	register char *packbuffer;{ long *lpack,*lp; long mask32 = 0x00000000ffffffff; long maskw, nwords, i, bits;        _XReadPad (dpy, packbuffer, size);        lp = data;        lpack = (long *) packbuffer;        nwords = size >> 2;        bits = 32;        for(i=0;i<nwords;i++){            maskw = mask32 << bits;           *lp++ = ( *lpack & maskw ) >> bits;            bits = bits ^32;            if(bits){               lpack++;            }        }}_XRead32 (dpy, data, len)    Display *dpy;    long *data;    long len;{    char packbuffer[PACKBUFFERSIZE];

⌨️ 快捷键说明

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