?? xtransam.c
字號:
/* $XConsortium: Xtransam.c,v 1.4 94/04/17 20:23:01 mor Exp $ *//* $XFree86: xc/lib/xtrans/Xtransam.c,v 3.1 1996/05/10 06:55:45 dawes Exp $ *//*Copyright (c) 1994 X ConsortiumPermission is hereby granted, free of charge, to any person obtaininga copy of this software and associated documentation files (the"Software"), to deal in the Software without restriction, includingwithout limitation the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell copies of the Software, and topermit persons to whom the Software is furnished to do so, subject tothe following conditions:The above copyright notice and this permission notice shall be includedin all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OROTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of the X Consortium shallnot be used in advertising or otherwise to promote the sale, use orother dealings in this Software without prior written authorizationfrom the X Consortium.*//* Copyright (c) 1994 Vrije Universiteit Amsterdam, Netherlands * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name Vrije Universiteit not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. The Vrije Universiteit * makes no representations about the suitability of this software for * any purpose. It is provided "as is" without express or implied warranty. * * THE VRIJE UNIVERSITEIT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL THE VRIJE UNIVERSITEIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *//* * This is the Amoeba implementation of the X Transport service layer */#define event am_event_t#define interval am_interval_t#define port am_port_t#include <amoeba.h>#include <semaphore.h>#include <cmdreg.h>#include <stdcom.h>#include <stderr.h>#include <vc.h>#include <circbuf.h>#include <exception.h>#include <module/signals.h>#include <ampolicy.h>#include <stdlib.h>#include <stdio.h>#include <exception.h>#include <fault.h>#include <signal.h>#include <ctype.h>#include <module/name.h>#include <server/x11/Xamoeba.h>#include <server/ip/hton.h>#include <server/ip/types.h>#include <server/ip/gen/in.h>#include <server/ip/gen/tcp.h>#include <server/ip/tcpip.h>#include <server/ip/tcp_io.h>#include <server/ip/gen/tcp_io.h>#include <server/ip/gen/netdb.h>#include <server/ip/gen/inet.h>#undef event#undef interval#undef portextern char *strdup();/* a new family for Amoeba RPC connections */#define AF_AMOEBA 33#define FamilyAmoeba 33#define MAX_TCPIP_RETRY 4#define CIRCBUFSIZE 4096 /* was 1024 *//* * Amoeba channel description: */typedef struct _XAmChanDesc { int state; /* current state of connection */ int type; /* type of connection */ int status; /* status used by server */ signum signal; /* signal to kill TCP/IP reader */ semaphore *sema; /* select semaphore */ struct vc *virtcirc; /* virtual circuit for Amoeba RPC */ struct circbuf *circbuf; /* circular buffer for TCP/IP */ capability chancap; /* TCP/IP channel capability */ XtransConnInfo conninfo; /* back pointer to the connect info */} XAmChanDesc;/* Amoeba channel descriptor states */#define ACDS_FREE 0 /* unused */#define ACDS_USED 1 /* intermediate state */#define ACDS_CLOSED 2 /* just closed *//* Amoeba channel types */#define ACDT_TCPIP 1 /* TCP/IP connection */#define ACDT_VIRTCIRC 2 /* Amoeba virtual circuit connection */#ifdef XSERV_t#include "dix.h" /* clients[] needed by AmFindReadyClients */#define Error(list) ErrorF list#define Fatal(list) FatalError list#else#define Error(list) printf list#define Fatal(list) { printf list; exit(1); }#endif#define dbprintf(list) /* printf list */#define doprintf(list) printf list /**//* * First: utility functions. */#if defined(XSERV_t) || defined(FS_t)static semaphore main_sema;/* The X-server consists of one main thread, running the non re-entrant * X code, and a number of auxilary threads that take care of reading * the input streams, and input devices. The following set of routines * wake up the main thread when it has something to do. */voidInitMainThread(){ sema_init(&main_sema, 0);}voidWakeUpMainThread(){ sema_up(&main_sema);}intSleepMainThread(timeout)am_interval_t timeout;{ dbprintf(("Sleeping main thread timeout %d\n", timeout)); return (sema_trydown(&main_sema, timeout) == 0) ? 0 : -1;}static int init_waiters;static semaphore init_sema;voidAmInitWaitFor(){ init_waiters = 0; sema_init(&init_sema, 0);}/* * Force caller thread to wait until main has finished the initialization. */voidWaitForInitialization(){ init_waiters++; dbprintf(("Waiting for initialization (%d)\n", init_waiters)); sema_down(&init_sema);}voidWakeupInitWaiters(){ /* wakeup threads in initial sleep */ if (init_waiters > 0) { dbprintf(("%d waiters wait for something ...\n", init_waiters)); while (init_waiters-- > 0) { sema_up(&init_sema); } }}#endif /* XSERV_t || FS_t */#define THREAD_STACK_SIZE (8*1024)/* * Amoeba connection information is stored in, so called, * channel descriptors. Channel descriptors are identified * by their index in the table below. */static XAmChanDesc XAmChanDescriptors[OPEN_MAX];static void XAmCleanUpChanDesc(); /* forward *//* * Cleanup connection descriptors on a signal */static voidXAmSignalCleanUpChanDesc(sig) int sig;{ XAmCleanUpChanDesc(); _exit(sig | 0x80);}/* * Cleanup connection descriptors */static voidXAmCleanUpChanDesc(){ register int i; for (i = 0; i < OPEN_MAX; i++) { switch (XAmChanDescriptors[i].type) { case ACDT_TCPIP: /* The Amoeba TCP/IP server is capability based, i.e. * it uses capabilities to identify connections. Since a * capability is only destroyed when it has aged too much * or is explicitly deleted, the connection it identifies * will tend to exist for some while even if the client is * already gone. To force connections to close this loop * destroys all open TCP/IP connection. This loop us auto- * matically executed when exit() is called. */ std_destroy(&XAmChanDescriptors[i].chancap); break; case ACDT_VIRTCIRC: /* Close the virtual circuit asynchronously, or otherwise * we may hang for a minute under some (?) conditions. */ vc_close(XAmChanDescriptors[i].virtcirc, VC_BOTH | VC_ASYNC); break; } XAmChanDescriptors[i].state = ACDS_FREE; }}/* * Allocate a channel descriptor */static XAmChanDesc *XAmAllocChanDesc(){ register int i;#ifndef XSERV_t static int initialized = 0; /* * Since the TCP/IP server is capability based its connections exists * even if the owner process is long gone. To overcome this nuisance, * a sweep is made over the connection descriptors when exit() is * called or when an un-catched (by application program) signal is * received. */ if (!initialized) { initialized = 1; atexit(XAmCleanUpChanDesc); if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, XAmSignalCleanUpChanDesc); if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, XAmSignalCleanUpChanDesc); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, XAmSignalCleanUpChanDesc); if (signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, XAmSignalCleanUpChanDesc); }#endif for (i = 0; i < OPEN_MAX; i++) { if (XAmChanDescriptors[i].state == ACDS_FREE) { XAmChanDescriptors[i].state = ACDS_USED; XAmChanDescriptors[i].conninfo = NULL; return &XAmChanDescriptors[i]; } } return NULL;}/* * Convert ``file descriptor'' to channel descriptor */static XAmChanDesc *XAmFdToChanDesc(fd) int fd;{ if (fd >= 0 && fd < OPEN_MAX) { return &XAmChanDescriptors[fd]; } else { return NULL; }}/* * Convert channel descriptor to ``file descriptor'' */static intXAmChanDescToFd(chandesc) XAmChanDesc *chandesc;{ return chandesc - XAmChanDescriptors;}/* * Free channel descriptor */static voidXAmFreeChanDesc(chandesc) XAmChanDesc *chandesc;{ if (chandesc->sema) { xfree(chandesc->sema); chandesc->sema = NULL; } chandesc->state = ACDS_FREE;}static void XAmReaderThread();static intMakeAmConnection(phostname, idisplay, familyp, saddrlenp, saddrp) char *phostname; int idisplay; int *familyp; /* RETURN */ int *saddrlenp; /* RETURN */ char **saddrp; /* RETURN */{ capability xservercap; char xserverpath[256]; XAmChanDesc *chandesc; errstat err; /* Amoeba requires a server hostname */ if (phostname == NULL || *phostname == '\0') { fprintf(stderr, "MakeAmConnection: Display name expected\n"); return -1; } /* allocate channel descriptor */ chandesc = XAmAllocChanDesc(); if (chandesc == NULL) { fprintf(stderr, "MakeAmConnection: Out of channel capabilities\n"); return -1; } /* * There are two possible way to make a connection on Amoeba. Either * through an Amoeba RPC or a TCP/IP connection. Depending on whether * the X server resides on Amoeba, Amoeba RPC's are used. Otherwise * it uses a TCP/IP connection. */ (void)sprintf(xserverpath, "%s/%s:%d", DEF_XSVRDIR, phostname, idisplay); if ((err = name_lookup(xserverpath, &xservercap)) == STD_OK) { am_port_t vccaps[2]; bufsize size; errstat err; header hdr; /* Amoeba virtual circuit connection */ chandesc->type = ACDT_VIRTCIRC; /* get the two connection ports from the X-server */ hdr.h_command = AX_CONNECT; hdr.h_port = xservercap.cap_port; hdr.h_priv = xservercap.cap_priv; size = trans(&hdr, NILBUF, 0, &hdr, (char *)vccaps, sizeof(vccaps)); if (ERR_STATUS(size)) { err = ERR_CONVERT(size); } else { err = ERR_CONVERT(hdr.h_status); } if (err != STD_OK || size != sizeof(vccaps)) { fprintf(stderr, "Xlib: connect to Amoeba X-server failed (%s)\n", err_why(err)); XAmFreeChanDesc(chandesc); return -1; } /* setup an Amoeba virtual circuit */ chandesc->virtcirc = vc_create(&vccaps[1], &vccaps[0], MAXBUFSIZE, MAXBUFSIZE); if (chandesc->virtcirc == (struct vc *)NULL) { fprintf(stderr, "Xlib: Amoeba virtual circuit create failed\n"); XAmFreeChanDesc(chandesc); return -1; } /* Special Amoeba family type. For Amoeba no additional access control * mechanism exists; when you have the server capability, you have * the access. Just use a fake address. */ *familyp = AF_AMOEBA; *saddrp = strdup("Amoeba"); *saddrlenp = strlen(*saddrp); } else { char tcpname[256]; capability tcpcap; ipaddr_t ipaddr; char *tcpsvr; nwio_tcpcl_t tcpcl; nwio_tcpconf_t tcpconf; XAmChanDesc **param; int result; /* Amoeba TCP/IP connection */ chandesc->type = ACDT_TCPIP; /* lookup up TCP/IP server */ if ((tcpsvr = getenv("TCP_SERVER")) == NULL) { tcpsvr = TCP_SVR_NAME; } if ((err = name_lookup(tcpsvr, &tcpcap)) != STD_OK) { fprintf(stderr, "Xlib: Cannot lookup %s (%s)\n", tcpsvr, err_why(err)); std_destroy(&chandesc->chancap); XAmFreeChanDesc(chandesc); return -1; } /* establish TCP/IP connection */ if ((err = tcpip_open(&tcpcap, &chandesc->chancap)) != STD_OK) { fprintf(stderr, "Xlib: Cannot open TCP/IP server on %s (%s)\n", tcpsvr, tcpip_why(err)); std_destroy(&chandesc->chancap); XAmFreeChanDesc(chandesc); return -1; } /* lookup TCP/IP hostname */ if (isdigit(phostname[0])) { ipaddr = inet_addr(phostname); } else { struct hostent *hp = gethostbyname(phostname); if (hp == NULL) { fprintf(stderr, "Xlib: %s unknown host\n", phostname); return -1; } memcpy(&ipaddr, hp->h_addr, hp->h_length); } /* set remote address/port on the TCP/IP connection */ tcpconf.nwtc_flags = NWTC_SET_RA|NWTC_SET_RP|NWTC_LP_SEL; tcpconf.nwtc_remaddr = ipaddr; tcpconf.nwtc_remport = htons(6000+idisplay); if ((err = tcp_ioc_setconf(&chandesc->chancap, &tcpconf)) != STD_OK) { fprintf(stderr, "Xlib: Cannot configure TCP/IP server (%s)\n", tcpip_why(err)); std_destroy(&chandesc->chancap); XAmFreeChanDesc(chandesc); return -1; } /* make the actual TCP/IP connection */ tcpcl.nwtcl_flags = 0; if ((err = tcp_ioc_connect(&chandesc->chancap, &tcpcl)) != STD_OK) { fprintf(stderr, "Xlib: Cannot make TCP/IP connection (%s)\n", tcpip_why(err)); std_destroy(&chandesc->chancap); XAmFreeChanDesc(chandesc); return -1; } /* start TCP/IP reader thread */ chandesc->signal = sig_uniq(); chandesc->circbuf = cb_alloc(CIRCBUFSIZE); param = (XAmChanDesc **) xalloc(sizeof(XAmChanDesc *)); /* error checking? */ *param = chandesc; result = thread_newthread(XAmReaderThread, THREAD_STACK_SIZE, (char *)param, sizeof(XAmChanDesc *)); if (result == 0) { fprintf(stderr, "Xlib: Cannot start reader thread\n"); std_destroy(&chandesc->chancap); XAmFreeChanDesc(chandesc); return -1; } threadswitch(); /* give reader a try */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -