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

📄 srvnet.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 3 页
字号:
	for ( key=SHMKEY_BASE; key < SHMKEY_BASE+SHMKEY_MAX; key++ ) {
		shmid = shmget(key,req->size,IPC_CREAT|IPC_EXCL|0666);
		if ( shmid == -1 ) {
			if ( errno != EEXIST )
				goto bad;
		} else {
			tmp = shmat(shmid,0,0);
			if ( tmp == (char *)-1 )
				goto bad;
			curclient->shm_cmds = tmp;
			curclient->shm_cmds_shmid = shmid;
			curclient->shm_cmds_size = req->size;
			goto finish;
		}
	}

 bad:
	key = 0;

 finish:
	DPRINTF("Shm: Request key granted=%d\n",key);
	GsWrite(current_fd, &key, sizeof(key));
#else
	/* return no shared memory support*/
	int key = 0;
	GsWrite(current_fd, &key, sizeof(key));
#endif /* HAVE_SHAREDMEM_SUPPORT*/
}

static void 
GrGetFontListWrapper(void *r)
{
	MWFONTLIST **list;
	int num;
	int i, ttlen, mwlen;

	GrGetFontList(&list, &num);

	GsWriteType(current_fd, GrNumGetFontList);

	/* the number of strings comming in */
	GsWrite(current_fd, &num, sizeof(int));

	if(num != -1) {
		for(i = 0; i < num; i++) {
			ttlen = strlen(list[i]->ttname) + 1;
			mwlen = strlen(list[i]->mwname) + 1;

			GsWrite(current_fd, &ttlen, sizeof(int));
			GsWrite(current_fd, list[i]->ttname, ttlen * sizeof(char));

			GsWrite(current_fd, &mwlen, sizeof(int));
			GsWrite(current_fd, list[i]->mwname, mwlen * sizeof(char));
		}
		
		GrFreeFontList(&list, num);
	}
}

void GrShmCmdsFlushWrapper(void *r);

/*
 * Handler functions, ordered by reqType
 */
struct GrFunction {
	void		(*func)(void *);
	GR_FUNC_NAME 	name;
} GrFunctions[] = {
	/*   0 */ {GrOpenWrapper, "GrOpen"},
	/*   1 */ {GrCloseWrapper, "GrClose"},
	/*   2 */ {GrGetScreenInfoWrapper, "GrGetScreenInfo"},
	/*   3 */ {GrNewWindowWrapper, "GrNewWindow"},
	/*   4 */ {GrNewInputWindowWrapper, "GrNewInputWindow"},
	/*   5 */ {GrDestroyWindowWrapper, "GrDestroyWindow"},
	/*   6 */ {GrNewGCWrapper, "GrNewGC"},
	/*   7 */ {GrCopyGCWrapper, "GrCopyGC"},
	/*   8 */ {GrGetGCInfoWrapper, "GrGetGCInfo"},
	/*   9 */ {GrDestroyGCWrapper, "GrDestroyGC"},
	/*  10 */ {GrMapWindowWrapper, "GrMapWindow"},
	/*  11 */ {GrUnmapWindowWrapper, "GrUnmapWindow"},
	/*  12 */ {GrRaiseWindowWrapper, "GrRaiseWindow"},
	/*  13 */ {GrLowerWindowWrapper, "GrLowerWindow"},
	/*  14 */ {GrMoveWindowWrapper, "GrMoveWindow"},
	/*  15 */ {GrResizeWindowWrapper, "GrResizeWindow"},
	/*  16 */ {GrGetWindowInfoWrapper, "GrGetWindowInfo"},
	/*  17 */ {GrGetFontInfoWrapper, "GrGetFontInfo"},
	/*  18 */ {GrSetFocusWrapper, "GrSetFocus"},
	/*  19 */ {GrSetWindowCursorWrapper, "GrSetWindowCursor"},
	/*  20 */ {GrClearAreaWrapper, "GrClearAreaWrapper"},
	/*  21 */ {GrSelectEventsWrapper, "GrSelectEvents"},
	/*  22 */ {GrGetNextEventWrapper, "GrGetNextEvent"},
	/*  23 */ {GrCheckNextEventWrapper, "GrCheckNextEvent"},
	/*  24 */ {GrPeekEventWrapper, "GrPeekEvent"},
	/*  25 */ {GrLineWrapper, "GrLine"},
	/*  26 */ {GrPointWrapper, "GrPoint"},
	/*  27 */ {GrRectWrapper, "GrRect"},
	/*  28 */ {GrFillRectWrapper, "GrFillRect"},
	/*  29 */ {GrPolyWrapper, "GrPoly"},
	/*  30 */ {GrFillPolyWrapper, "GrFillPoly"},
	/*  31 */ {GrEllipseWrapper, "GrEllipse"},
	/*  32 */ {GrFillEllipseWrapper, "GrFillEllipse"},
	/*  33 */ {GrSetGCForegroundWrapper, "GrSetGCForeground"},
	/*  34 */ {GrSetGCBackgroundWrapper, "GrSetGCBackGround"},
	/*  35 */ {GrSetGCUseBackgroundWrapper, "GrSetGCUseBackGround"},
	/*  36 */ {GrSetGCModeWrapper, "GrSetGCMode"},
	/*  37 */ {GrSetGCFontWrapper, "GrSetGCFont"},
	/*  38 */ {GrGetGCTextSizeWrapper, "GrGetGCTextSize"},
	/*  39 */ {GsReadAreaWrapper, "GsReadArea"},
	/*  40 */ {GrAreaWrapper, "GrArea"},
	/*  41 */ {GrBitmapWrapper, "GrBitmap"},
	/*  42 */ {GrTextWrapper, "GrText"},
	/*  43 */ {GrNewCursorWrapper, "GrNewCursor"},
	/*  44 */ {GrMoveCursorWrapper, "GrMoveCursor"},
	/*  45 */ {GrGetSystemPaletteWrapper, "GrGetSystemPalette"},
	/*  46 */ {GrFindColorWrapper, "GrFindColor"},
	/*  47 */ {GrReparentWindowWrapper, "GrReparentWindow"},
	/*  48 */ {GrDrawImageFromFileWrapper, "GrDrawImageFromFile"},
	/*  49 */ {GrLoadImageFromFileWrapper, "GrLoadImageFromFile"},
	/*  50 */ {GrNewPixmapWrapper, "GrNewPixmap"},
	/*  51 */ {GrCopyAreaWrapper, "GrCopyArea"},
	/*  52 */ {GrSetFontSizeWrapper, "GrSetFontSize"},
	/*  53 */ {GrCreateFontWrapper, "GrCreateFont"},
	/*  54 */ {GrDestroyFontWrapper, "GrDestroyFont"},
	/*  55 */ {GrReqShmCmdsWrapper, "GrReqShmCmds"},
	/*  56 */ {GrShmCmdsFlushWrapper, "GrShmCmdsFlush"},
	/*  57 */ {GrSetFontRotationWrapper, "GrSetFontRotation"},
	/*  58 */ {GrSetFontAttrWrapper, "GrSetFontAttr"},
	/*  59 */ {GrSetSystemPaletteWrapper, "GrSetSystemPalette"},
	/*  60 */ {GrInjectEventWrapper, "GrInjectEvent"},
	/*  61 */ {GrNewRegionWrapper, "GrNewRegion"},
	/*  62 */ {GrDestroyRegionWrapper, "GrDestroyRegion"},
	/*  63 */ {GrUnionRectWithRegionWrapper, "GrUnionRectWithRegion"},
	/*  64 */ {GrUnionRegionWrapper, "GrUnionRegion"},
	/*  65 */ {GrIntersectRegionWrapper, "GrIntersectRegion"},
	/*  66 */ {GrSetGCRegionWrapper, "GrSetGCRegion"},
	/*  67 */ {GrSubtractRegionWrapper, "GrSubtractRegion"},
	/*  68 */ {GrXorRegionWrapper, "GrXorRegion"},
	/*  69 */ {GrPointInRegionWrapper, "GrPointInRegion"},
	/*  70 */ {GrRectInRegionWrapper, "GrRectInRegion"},	
	/*  71 */ {GrEmptyRegionWrapper, "GrEmptyRegion"},	
	/*  72 */ {GrEqualRegionWrapper, "GrEqualRegion"},	
	/*  73 */ {GrOffsetRegionWrapper, "GrOffsetRegion"},	
	/*  74 */ {GrGetRegionBoxWrapper, "GrGetRegionBox"},	
	/*  75 */ {GrNewPolygonRegionWrapper, "GrNewPolygonRegion"},	
	/*  76 */ {GrArcWrapper, "GrArc"},
	/*  77 */ {GrArcAngleWrapper, "GrArcAngle"},
	/*  78 */ {GrSetWMPropertiesWrapper, "GrSetWMProperties"},
	/*  79 */ {GrGetWMPropertiesWrapper, "GrGetWMProperties"},
	/*  80 */ {GrCloseWindowWrapper, "GrCloseWindow"},
	/*  81 */ {GrKillWindowWrapper, "GrKillWindow"},
	/*  82 */ {GrDrawImageToFitWrapper, "GrDrawImageToFit"},
	/*  83 */ {GrFreeImageWrapper, "GrFreeImage"},
	/*  84 */ {GrGetImageInfoWrapper, "GrGetImageInfo"},
	/*  85 */ {GrDrawImageBitsWrapper, "GrDrawImageBits"},
 	/*  86 */ {GrPointsWrapper, "GrPoints"},
 	/*  87 */ {GrGetFocusWrapper, "GrGetFocus"},
 	/*  88 */ {GrGetSysColorWrapper, "GrGetSysColor"},
	/*  89 */ {GrSetScreenSaverTimeoutWrapper, "GrSetScreenSaverTimeout"},
	/*  90 */ {GrSetSelectionOwnerWrapper, "GrSetSelectionOwner"},
	/*  91 */ {GrGetSelectionOwnerWrapper, "GrGetSelectionOwner"},
	/*  92 */ {GrRequestClientDataWrapper, "GrRequestClientData"},
	/*  93 */ {GrSendClientDataWrapper, "GrSendClientData"},
	/*  94 */ {GrBellWrapper, "GrBell"},
	/*  95 */ {GrSetBackgroundPixmapWrapper, "GrSetBackgroundPixmap"},
	/*  96 */ {GrDestroyCursorWrapper, "GrDestroyCursor"},
	/*  97 */ {GrQueryTreeWrapper, "GrQueryTree"},
	/*  98 */ {GrCreateTimerWrapper, "GrCreateTimer"},
	/*  99 */ {GrDestroyTimerWrapper, "GrDestroyTimer"},
	/* 100 */ {GrSetPortraitModeWrapper, "GrSetPortraitMode"},
	/* 101 */ {GrImageBufferAllocWrapper, "GrImageBufferAlloc"},
	/* 102 */ {GrImageBufferSendWrapper, "GrImageBufferSend"},
	/* 103 */ {GrLoadImageFromBufferWrapper, "GrLoadImageFromBuffer"},
	/* 104 */ {GrDrawImageFromBufferWrapper, "GrDrawImageFromBuffer"},
	/* 105 */ {GrGetFontListWrapper, "GrGetFontList"},
	/* 106 */ {GrSetGCClipOriginWrapper, "GrSetGCClipOrigin"},
};

void
GrShmCmdsFlushWrapper(void *r)
{
	nxShmCmdsFlushReq *req = r;
	unsigned char 	reply;
#if HAVE_SHAREDMEM_SUPPORT
	nxReq 		*pr;
	int 		length;
	unsigned char 	*do_req, *do_req_last;

	if ( current_shm_cmds == 0 || current_shm_cmds_size < req->size ) {
		/* No or short shm present serverside, bug or mischief */
		EPRINTF("nano-X: Ill behaved client assumes shm ok\n");
		if ( req->reply ) {
			reply = 0;
			GsWrite(current_fd, &reply, 1);
		}
		return;
	}

	do_req = current_shm_cmds;
	do_req_last = current_shm_cmds + req->size;

	while ( do_req < do_req_last ) {
		pr = (nxReq *)do_req;
		length = GetReqAlignedLen(pr);
		if ( pr->reqType < GrTotalNumCalls ) {
			GrFunctions[pr->reqType].func(pr);
		} else {
			EPRINTF("nano-X: Error bad shm function!\n");
		}
		do_req += length;
	}

	if ( req->reply ) {
		reply = 1;
		GsWrite(current_fd, &reply, 1);
	}
#else
	/* no shared memory support*/
	if ( req->reply ) {
		reply = 0;
		GsWrite(current_fd, &reply, 1);
	}
#endif /* HAVE_SHAREDMEM_SUPPORT*/
}

/*
 * This function is used to bind to the named socket which is used to
 * accept connections from the clients.
 */
int 
GsOpenSocket(void)
{
#if ELKS
	struct sockaddr_na sckt;
#ifndef SUN_LEN
#define SUN_LEN(ptr)	(sizeof(sckt))
#endif
#elif __ECOS
	struct sockaddr_in sckt;
#ifndef SUN_LEN
#define SUN_LEN(ptr)	(sizeof(sckt))
#endif
#else
	struct sockaddr_un sckt;
#ifndef SUN_LEN
#define SUN_LEN(ptr)	((size_t) (((struct sockaddr_un *) 0)->sun_path) \
		      		+ strlen ((ptr)->sun_path))
#endif
#endif /* ELKS */

#if ELKS
	if((un_sock = socket(AF_NANO, SOCK_STREAM, 0)) == -1)
		return -1;

	sckt.sun_family = AF_NANO;
	sckt.sun_no = GR_NUMB_SOCKET;
#elif __ECOS
	// Create the socket
	if((un_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	    return -1;

	// Bind to any/all local IP addresses
	memset( &sckt, '\0', sizeof(sckt) );
	sckt.sin_family = AF_INET;
	sckt.sin_len = sizeof(sckt);
	sckt.sin_port = htons(6600);
	sckt.sin_addr.s_addr = INADDR_ANY;
#else
	if (access(GR_NAMED_SOCKET, F_OK) == 0) {
		/* FIXME: should try connecting to see if server is active */
		if(unlink(GR_NAMED_SOCKET))
			return -1;
	}

	/* Create the socket: */
	if((un_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		return -1;

	/* Bind a name to the socket: */
	sckt.sun_family = AF_UNIX;
	strncpy(sckt.sun_path, GR_NAMED_SOCKET, sizeof(sckt.sun_path));
#endif /* ELKS */
	if(bind(un_sock, (struct sockaddr *) &sckt, SUN_LEN(&sckt)) < 0)
		return -1;

	/* Start listening on the socket: */
	if(listen(un_sock, 5) == -1)
		return -1;
	return 1;
}

void
GsCloseSocket(void)
{
	if(un_sock != -1)
		close(un_sock);
	un_sock = -1;
	unlink(GR_NAMED_SOCKET);
}

/*
 * This function is used to accept a connnection from a client.
 */
void
GsAcceptClient(void)
{
	int i;
#if ELKS
	struct sockaddr_na sckt;
#elif __ECOS
	struct sockaddr_in sckt;
#else
	struct sockaddr_un sckt;
#endif
	size_t size = sizeof(sckt);

	if((i = accept(un_sock, (struct sockaddr *) &sckt, &size)) == -1) {
#ifdef __ECOS
            // All ports should do this
		EPRINTF("nano-X: Error accept failed (%s)\n", strerror(errno));
#else
		EPRINTF("nano-X: Error accept failed (%d)\n", errno);
#endif
		return;
	}
	GsAcceptClientFd(i);
}

/*
 * This function accepts a client ID, and searches through the
 * linked list of clients, returning a pointer to the relevant
 * structure or NULL if not found.
 */
GR_CLIENT *
GsFindClient(int fd)
{
	GR_CLIENT *client;

	client = root_client;

	while(client) {
		if(client->id == fd)
			return(client);
		client = client->next;
	}
	
	return 0;
}

/*
 * Destroy windows and eventclient structures used by client.
 * Called by GsDropClient after a client has exited to clean
 * up resources.
 */
void
GsDestroyClientResources(GR_CLIENT * client)
{
	GR_WINDOW     * wp, *nwp;
	GR_PIXMAP     * pp, *npp;
	GR_GC 	      * gp, *ngp;
	GR_REGION     * rp, *nrp;
	GR_FONT       * fp, *nfp;
	GR_IMAGE      * ip, *nip;
	GR_CURSOR     *	cp, *ncp;
	GR_EVENT_CLIENT *ecp, *necp;
	GR_EVENT_CLIENT *pecp = NULL;
	GR_EVENT_LIST	*evp;

printf("Destroy client %d resources\n", client->id);
	/* search window list, destroy windows owned by client*/
	for(wp=listwp; wp; wp=nwp) {
		nwp = wp->next;
		/*
		 * Remove eventclient structures for this client
		 */
		ecp = wp->eventclients;
		while (ecp) {
			necp = ecp->next;
			if (ecp->client == client) {
printf( "  Destroy window %d eventclient mask %08lx\n", wp->id, ecp->eventmask);
				if (ecp == wp->eventclients)
					wp->eventclients = ecp->next;
				else
					pecp->next = ecp->next;
				free(ecp);
			} else
				pecp = ecp;
			ecp = necp;
		}
		if (wp->owner == client) {
printf("  Destroy window %d\n", wp->id);
			GrDestroyWindow(wp->id);
		}
	}

	/* search pixmap list, destroy pixmaps owned by client*/
	for(pp=listpp; pp; pp=npp) {
		npp = pp->next;
		if (pp->owner == client) {
printf("  Destroy pixmap %d\n", pp->id);
			GrDestroyWindow(pp->id);
		}
	}

	/* free gc's owned by client*/
	for(gp=listgcp; gp; gp=ngp) {
		ngp = gp->next;
		if (gp->owner == client) {
printf("  Destroy gc %d\n", gp->id);
			GrDestroyGC(gp->id);
		}
	}

	/* free fonts owned by client*/
	for(fp=listfontp; fp; fp=nfp) {
		nfp = fp->next;
		if (fp->owner == client) {
printf("  Destroy font %d\n", fp->id);
			GrDestroyFont(fp->id);
		}
	}

	/* free regions owned by client*/
	for(rp=listregionp; rp; rp=nrp) {
		nrp = rp->next;
		if (rp->owner == client) {
printf("  Destroy region %d\n", rp->id);
			GrDestroyRegion(rp->id);
		}
	}

	/* free images owned by client*/
	for(ip=listimagep; ip; ip=nip) {
		nip = ip->next;
		if (ip->owner == client) {
printf("  Destroy image %d\n", ip->id);
			GrFreeImage(ip->id);
		}
	}

	/* free cursors owned by client*/
	for(cp=listcursorp; cp; cp=ncp) {
		ncp = cp->next;
		if (cp->owner == client) {
printf("  Destroy cursor %d\n", cp->id);
			GrDestroyCursor(cp->id);
		}
	}

	/* Free events associated with client*/
	evp = client->eventhead;
	while (evp) {
printf("  Destroy event %d\n", evp->event.type);
		client->eventhead = evp->next;
		evp->next = eventfree;
		eventfree = evp;
		evp = client->eventhead;
	}
}

/*
 * Display window, pixmap, gc, font, region lists
 */
void
GsPrintResources(void)
{
	GR_WINDOW *wp;
	GR_PIXMAP *pp;
	GR_GC *gp;
	GR_REGION *rp;
	GR_FONT *fp;
	GR_IMAGE *ip;

	/* window list*/
	printf("Window list:\n");
	for(wp=listwp; wp; wp=wp->next) {
		printf("%d(%d),", wp->id, wp->owner? wp->owner->id: 0);
	}
	printf("\nPixmap list:\n");
	for(pp=listpp; pp; pp=pp->next) {
		printf("%d(%d),", pp->id, pp->owner->id);
	}
	printf("\nGC list:\n");
	for(gp=listgcp; gp; gp=gp->next) {
		printf("%d(%d),", gp->id, gp->owner->id);
	}
	printf("\nFont list:\n");
	for(fp=listfontp; fp; fp=fp->next) {
		printf("%d(%d),", fp->id, fp->owner->id);
	}
	printf("\nRegion list:\n");
	for(rp=listregionp; rp; rp=rp->next) {
		printf("%d(%d),", rp->id, rp->owner->id);
	}
	printf("\nImage list:\n");
	for(ip=listimagep; ip; ip=ip->next) {
		printf("%d(%d),", ip->id, ip->owner->id);
	}
	printf("\n");
}

/*
 * This is used to drop a client when it is detected that the connection to it
 * has been lost.
 */
void
GsDropClient(int fd)
{
	GR_CLIENT *client;

	if((client = GsFindClient(fd))) { /* If it exists */
		close(fd);	/* Close the socket */

		GsDestroyClientResources(client);
		if(client == root_client)
			root_client = client->next;
		/* Link the prev to the next */
		if(client->prev) client->prev->next = client->next;

		/* Link the next to the prev */
		if(client->next) client->next->prev = client->prev;

#if HAVE_SHAREDMEM_SUPPORT
		if ( client->shm_cmds != 0 ) {
			/* Free shared memory */
			shmctl(client->shm_cmds_shmid,IPC_RMID,0);
			shmdt(client->shm_cmds);
		}
#endif
GsPrintResources();
		free(client);	/* Free the structure */

		clipwp = NULL;	/* reset clip window*/
		--connectcount;
	} else EPRINTF("nano-X: trying to drop non-existent client %d.\n", fd);
}

/*
 * This is a wrapper to read() which handles error conditions, and
 * returns 0 for both error conditions and no data.
 */
int
#if ELKS
GsRead(int fd, char *buf, int c)
#else
GsRead(int fd, void *buf, int c)
#endif
{
	int e, n;

	n = 0;

	while(n < c) {
		e = read(fd, (buf + n), (c - n));
		if(e <= 0) {
			if (e == 0)
				EPRINTF("nano-X: client closed socket: %d\n", fd);
			else EPRINTF("nano-X: GsRead failed %d %d: %d\r\n",
			       e, n, errno);
			GsClose(fd);
			return -1;
		}
		n += e;
	}

	return 0;
}

/*
 * This is a wrapper to write().
 */
int GsWrite(int fd, void *buf, int c)
{
	int e, n;

	n = 0;

	while(n < c) {
		e = write(fd, ((char *) buf + n), (c - n));
		if(e <= 0) {
			GsClose(fd);
			return -1;
		}
		n += e;
	}

	return 0;
}

int GsWriteType(int fd, short type)
{
	return GsWrite(fd,&type,sizeof(type));
}

/*
 * This function is used to parse and dispatch requests from the clients.
 * Note that the maximum request size is allocated from the stack
 * in this function.
 */
void
GsHandleClient(int fd)
{
	nxReq *	req;
	long	len;
	char	buf[MAXREQUESTSZ];

	current_fd = fd;
#if HAVE_SHAREDMEM_SUPPORT
	current_shm_cmds = curclient->shm_cmds;
	current_shm_cmds_size = curclient->shm_cmds_size;
#endif
	/* read request header*/
	if(GsRead(fd, buf, sizeof(nxReq)))
		return;

	len = GetReqAlignedLen((nxReq *)&buf[0]);
	if(len > sizeof(nxReq)) {
		if(len > MAXREQUESTSZ) {
			EPRINTF("nano-X: GsHandleClient request too large: %ld > %d\n",
				len, MAXREQUESTSZ);
			exit(1);
		}
		/* read additional request data*/
		if(GsRead(fd, &buf[sizeof(nxReq)], len-sizeof(nxReq)))
			return;
	}
	req = (nxReq *)&buf[0];

	if(req->reqType < GrTotalNumCalls) {
		curfunc = GrFunctions[req->reqType].name;
		/*DPRINTF("HandleClient %s\n", curfunc);*/
		GrFunctions[req->reqType].func(req);
	} else {
		EPRINTF("nano-X: GsHandleClient bad function\n");
	}
}

⌨️ 快捷键说明

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