?? xtransos2.c
字號:
/* $XFree86: xc/lib/xtrans/Xtransos2.c,v 3.5 1997/01/28 10:53:32 dawes Exp $ *//* * (c) Copyright 1996 by Sebastien Marineau and Holger Veit * <marineau@genie.uottawa.ca> * <Holger.Veit@gmd.de> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Sebastien Marineau or Holger Veit shall not be * used in advertising or otherwise to promote the sale, use or other dealings * in this Software without prior written authorization from Holger Veit or Sebastien Marineau. * *//* Implementation of the OS/2 local pipe transport layer */#define INCL_DOSNMPIPES#define INCL_DOSPROCESS#define INCL_DOSERRORS#define INCL_DOSFILEMGR#undef BYTE#undef BOOL#include <os2.h>#ifdef XSERV_textern HEV hPipeSem;BOOL init_server_pipes();#endif/************************************************************************* * Independent Layer *************************************************************************/#ifdef TRANS_CLIENTstatic XtransConnInfoTRANS(Os2OpenClient)(thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ APIRET rc; HFILE hfd,hServer; ULONG action,byteWritten,State; char pipename[256],clientname[256]; char server_string[256]; struct sockaddr *addr_name; unsigned char pipe_len; XtransConnInfo ciptr; static int unique_id=0; int i,namelen,try; PRMSG(2,"Os2OpenClient(%s,%s,%s)\n",protocol,host,port); /* test, whether the host is really local, i.e. either * "os2" or "local" */ if (strcmp(protocol,"os2") && strcmp(protocol,"local")) { PRMSG (1, "Os2OpenClient: Cannot connect to non-local host %s\n", host, 0, 0); return NULL; } /* make the pipename */ if (port && *port ) { if( *port == '/' ) { /* A full pathname */ (void) sprintf(pipename, "\\PIPE\\X\\%s,", port); } else { (void) sprintf(pipename, "%s%s", "\\PIPE\\X\\xf86.", port); } } else { (void) sprintf(pipename, "\\PIPE\\X\\xfree86"); } PRMSG(5, "Os2OpenClient: Creating pipe %s\n",pipename, 0,0 ); /* make a connection entry */ if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) { PRMSG(1,"Os2OpenClient: calloc(1,%d) failed\n", sizeof(struct _XtransConnInfo),0,0 ); return NULL; } /* open the pipe. Try ten times before giving up at 500ms intervals*/ try = 0; do { rc = DosOpen(pipename,&hServer, &action, 0, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE, (PEAOP2)NULL); if(rc == 0) break; if (try >=10) { PRMSG(1,"Os2OpenClient: Open server pipe %s failed, rc=%d\n", pipename,rc,0 ); PRMSG(1,"\tProbable causes: either the XServer is not running, or has not started properly,\n", 0,0,0 ); PRMSG(1,"\tor the DISPLAY variable is set incorrectly.\n", 0,0,0 ); xfree(ciptr); return NULL; } try ++; DosSleep(500); } while (rc != 0);/* OK, now we are talking to the server. Generate a unique pipe name and pass it to * the server. Make the pipe and wait for server to connect */ sprintf(clientname,"\\PIPE\\X\\%d.%d",getpid(),unique_id++); rc = DosCreateNPipe (clientname, &hfd, NP_NOINHERIT | NP_ACCESS_DUPLEX, 1 | NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE, 16384, 16384, 0); if (rc != 0){ PRMSG(1, "Os2OpenClient: Unable to create pipe %s\n", pipename,0,0 ); DosClose(hfd); pipe_len=0; DosWrite(hServer,&pipe_len,1,&byteWritten); DosClose(hServer); xfree(ciptr); return(NULL); } /* Connect to the pipe. */ rc = DosConnectNPipe (hfd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2OpenClient: Unable to connect to pipe %s\n", pipename,0,0 ); DosClose (hfd); DosClose(hServer); xfree(ciptr); return (NULL); }/* Now write name to server on hServer */ server_string[0]=(char) strlen(clientname)+1; strcpy(&server_string[1],clientname); rc = DosWrite(hServer,server_string,(ULONG)server_string[0]+1,&byteWritten); if(rc != 0){ /* Could not write to server pipe? */ PRMSG(1, "Os2OpenClient: Error writing to server pipe, handle=%d, rc=%d, w=%d\n", hServer,rc,byteWritten ); DosClose(hServer); DosClose(hfd); xfree(ciptr); return(NULL); } PRMSG (5, "Os2OpenCLient: Wrote pipename %s to server; len %d written %d \n", &server_string[1],server_string[0]+1,byteWritten);/* The server will respond by opening the pipe. Wait for that for 30 secs */ i=0; DosSleep(50); /* Give it time to catch up but minimize race condition*/ rc = DosConnectNPipe(hfd); while((rc == ERROR_PIPE_NOT_CONNECTED)&&(i++<60)) { DosSleep(500); rc = DosConnectNPipe(hfd); } if(rc != 0){ /* Server has not responded! */ PRMSG(1, "Os2OpenClient: Timeout on wait for server response, handle=%d, rc=%d\n",hServer,rc,0 ); PRMSG(1, "\tProbable cause: the XServer has exited or crashed while the connection was being established\n",0,0,0 ); PRMSG(1, "\tor the XServer is too busy to respond.\n",0,0,0 ); DosClose(hServer); DosClose(hfd); xfree(ciptr); return(NULL); }/* OK, the server has connected! Fill-in the info and return */ DosClose(hServer);/* Last check: make sure client is connected! */ rc = DosQueryNPHState(hfd,&State); if(rc != 0){ /* Client is not connected! */ PRMSG(1, "Os2OpenClient: Client pipe does not appear connected. rc=%d, h=%d\n",rc,hfd,0 ); PRMSG(1, "\tProbable cause: the XServer has just exited.\n",0,0,0 ); DosClose(hfd); xfree(ciptr); return(NULL); } namelen=sizeof(struct sockaddr); if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2OpenClient: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hfd); xfree(ciptr); return(NULL); } ciptr->addrlen = namelen; ((struct sockaddr *)ciptr->addr)->sa_family = AF_UNIX; strcpy(((struct sockaddr *)ciptr->addr)->sa_data, "local"); if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2OpenCLient: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hfd); xfree(ciptr->addr); xfree(ciptr); return(NULL); } ciptr->peeraddrlen = namelen; ((struct sockaddr *)ciptr->peeraddr)->sa_family = AF_UNIX; strcpy (((struct sockaddr *)ciptr->peeraddr)->sa_data,"local"); PRMSG (5, "Os2OpenCLient: Filled in struct: len %d %d name %s\n", ciptr->addrlen,ciptr->peeraddrlen,((struct sockaddr *)ciptr->peeraddr)->sa_data); ciptr->index=hfd; ciptr->family=AF_UNIX; if((ciptr->fd=_imphandle(hfd))<0){ PRMSG(1, "Os2OpenClient: Could not import the pipe handle into EMX\n",0,0,0 ); PRMSG(1, "\tProbable cause: EMX has run out of free file handles.\n",0,0,0 ); DosClose(hfd); xfree(ciptr->addr); xfree(ciptr->peeraddr); xfree(ciptr); return(NULL); } PRMSG(5, "Os2OpenClient: pipe handle %d EMX handle %d\n",ciptr->index,ciptr->fd,0 ); fcntl(ciptr->fd,F_SETFL,O_NDELAY); fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC); return ciptr;}#endif /* TRANS_CLIENT */#ifdef TRANS_SERVERstatic XtransConnInfoTRANS(Os2OpenServer)(thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ APIRET rc; HFILE hfd; ULONG action; char pipename[256]; struct sockaddr *addr_name; XtransConnInfo ciptr; int namelen;#ifdef XSERV_t if (! init_server_pipes()) return(NULL);#endif PRMSG(2,"Os2OpenServer(%s,%s,%s)\n",protocol,host,port); if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) { PRMSG(1,"Os2OpenServer: xcalloc(1,%d) failed\n", sizeof(struct _XtransConnInfo),0,0 ); return NULL; } if (port && *port ) { if( *port == '/' ) { /* A full pathname */ (void) sprintf(pipename, "\\PIPE\\X\\%s", port); } else { (void) sprintf(pipename, "%s%s", "\\PIPE\\X\\xf86.", port); } } else { (void) sprintf(pipename, "\\PIPE\\X\\xfree86"); } PRMSG(5, "Os2OpenServer: Creating pipe %s\n",pipename, 0,0 ); rc = DosCreateNPipe (pipename, &hfd, NP_NOINHERIT | NP_ACCESS_INBOUND, 1 | NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE, 0, 8192, 0); if (rc != 0){ PRMSG(1, "Os2OpenServer: Unable to create pipe %s, rc=%d\n", pipename,rc,0 ); PRMSG(1, "\tProbable cause: there is already another XServer running on display :%s\n",port,0,0 ); DosClose(hfd); xfree(ciptr); return(NULL); } /* Connect to the pipe. */ rc = DosConnectNPipe (hfd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2OpenServer: Unable to connect to pipe %s\n", pipename,0,0 ); DosClose (hfd); xfree(ciptr); return (NULL); }/* Pipe is now connected and waiting for client connect *//*** Put in info ***/ namelen=sizeof(struct sockaddr); if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2OpenServer: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hfd); xfree(ciptr); return(NULL); } ciptr->addrlen = namelen; ((struct sockaddr *)ciptr->addr)->sa_family = AF_UNIX; strcpy (((struct sockaddr *)ciptr->addr)->sa_data, "local"); if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2OpenServer: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hfd); xfree(ciptr->addr); xfree(ciptr); return(NULL); } ciptr->peeraddrlen = namelen; ((struct sockaddr *)ciptr->peeraddr)->sa_family = AF_UNIX; strcpy(((struct sockaddr *)ciptr->peeraddr)->sa_data,"local"); PRMSG (5, "Os2OpenServer: Filled in struct: len %d %d name %s\n", ciptr->addrlen,ciptr->peeraddrlen,((struct sockaddr *)ciptr->peeraddr)->sa_data); ciptr->index=hfd; /* Save this for later use in this unused member of struct */ ciptr->flags=1; /* Listener */ ciptr->family=AF_UNIX; if((ciptr->fd=_imphandle(hfd))<0){ DosClose(hfd); xfree(ciptr->addr); xfree(ciptr->peeraddr); xfree(ciptr); return(NULL); } PRMSG(5, "Os2OpenServer: Pipe handle %d EMX handle %d",ciptr->index,ciptr->fd,0 );#ifdef XSERV_t/* Attach the pipe sem to the pipe. Use handle index as key */ rc = DosSetNPipeSem(ciptr->fd, (HSEM)hPipeSem, ciptr->fd); if (rc){ PRMSG(1, "Os2OpenCOTSServer: Could not attach sem %d to pipe %d, rc=%d\n", hPipeSem,ciptr->fd,rc); DosClose(ciptr->fd); xfree(ciptr->addr); xfree(ciptr->peeraddr); xfree(ciptr); return(NULL); }#endif fcntl(ciptr->fd,F_SETFL,O_NDELAY); fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC); return(ciptr);}#endif /* TRANS_SERVER */#ifdef TRANS_CLIENTstatic XtransConnInfoTRANS(Os2OpenCLTSClient)(thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ PRMSG(2,"Os2OpenCLTSClient(%s,%s,%s)\n",protocol,host,port); return TRANS(Os2OpenClient)(thistrans, protocol, host, port);}#endif /* TRANS_CLIENT */#ifdef TRANS_CLIENTstatic XtransConnInfoTRANS(Os2OpenCOTSClient)(thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ PRMSG(2,"Os2OpenCOTSClient(%s,%s,%s)\n",protocol,host,port); return TRANS(Os2OpenClient)(thistrans, protocol, host, port);}#endif /* TRANS_CLIENT */#ifdef TRANS_SERVERstatic XtransConnInfoTRANS(Os2OpenCLTSServer)(thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ PRMSG(2,"Os2OpenCLTSServer(%s,%s,%s)\n",protocol,host,port); return TRANS(Os2OpenServer)(thistrans, protocol, host, port);}#endif /* TRANS_SERVER */#ifdef TRANS_SERVERstatic XtransConnInfoTRANS(Os2OpenCOTSServer)(thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ PRMSG(2,"Os2OpenCOTSServer(%s,%s,%s)\n",protocol,host,port); return TRANS(Os2OpenServer)(thistrans, protocol, host, port);}#endif /* TRANS_SERVER */#ifdef TRANS_REOPENstatic XtransConnInfoTRANS(Os2ReopenCOTSServer)(thistrans, fd, port)Xtransport *thistrans;int fd;char *port;{ XtransConnInfo ciptr; char addr_name[256]; int namelen; PRMSG(2,"Os2ReopenCOTSServer(%d,%s)\n", fd, port, 0); if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) { PRMSG(1,"Os2ReopenCOTSServer: xcalloc(1,%d) failed\n", sizeof(struct _XtransConnInfo),0,0 ); return NULL; } strcpy(addr_name,"local"); namelen=sizeof(addr_name); if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2ReopenCOTSServer: Can't allocate space for the addr\n", 0, 0, 0); xfree(ciptr);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -