1 /* $XFree86: xc/lib/xtrans/Xtransos2.c,v 3.5 1997/01/28 10:53:32 dawes Exp $ */
4 * (c) Copyright 1996 by Sebastien Marineau and Holger Veit
5 * <marineau@genie.uottawa.ca>
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * Except as contained in this notice, the name of Sebastien Marineau or Holger Veit shall not be
27 * used in advertising or otherwise to promote the sale, use or other dealings
28 * in this Software without prior written authorization from Holger Veit or Sebastien Marineau.
32 /* Implementation of the OS/2 local pipe transport layer */
34 #define INCL_DOSNMPIPES
35 #define INCL_DOSPROCESS
36 #define INCL_DOSERRORS
37 #define INCL_DOSFILEMGR
44 BOOL init_server_pipes();
47 /*************************************************************************
49 *************************************************************************/
53 TRANS(Os2OpenClient)(thistrans, protocol, host, port)
54 Xtransport *thistrans;
61 ULONG action,byteWritten,State;
62 char pipename[256],clientname[256];
63 char server_string[256];
64 struct sockaddr *addr_name;
65 unsigned char pipe_len;
67 static int unique_id=0;
70 PRMSG(2,"Os2OpenClient(%s,%s,%s)\n",protocol,host,port);
72 /* test, whether the host is really local, i.e. either
75 if (strcmp(protocol,"os2") && strcmp(protocol,"local")) {
77 "Os2OpenClient: Cannot connect to non-local host %s\n",
82 /* make the pipename */
85 if( *port == '/' ) { /* A full pathname */
86 (void) sprintf(pipename, "\\PIPE\\X\\%s,", port);
88 (void) sprintf(pipename, "%s%s", "\\PIPE\\X\\xf86.", port);
91 (void) sprintf(pipename, "\\PIPE\\X\\xfree86"); }
93 PRMSG(5, "Os2OpenClient: Creating pipe %s\n",pipename, 0,0 );
95 /* make a connection entry */
96 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) {
97 PRMSG(1,"Os2OpenClient: calloc(1,%d) failed\n",
98 sizeof(struct _XtransConnInfo),0,0 );
102 /* open the pipe. Try ten times before giving up at 500ms intervals*/
105 rc = DosOpen(pipename,&hServer, &action, 0,
106 FILE_NORMAL, FILE_OPEN,
107 OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE,
111 PRMSG(1,"Os2OpenClient: Open server pipe %s failed, rc=%d\n",
113 PRMSG(1,"\tProbable causes: either the XServer is not running, or has not started properly,\n",
115 PRMSG(1,"\tor the DISPLAY variable is set incorrectly.\n",
124 /* OK, now we are talking to the server. Generate a unique pipe name and pass it to
125 * the server. Make the pipe and wait for server to connect */
127 sprintf(clientname,"\\PIPE\\X\\%d.%d",getpid(),unique_id++);
129 rc = DosCreateNPipe (clientname, &hfd,
130 NP_NOINHERIT | NP_ACCESS_DUPLEX,
131 1 | NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE,
134 PRMSG(1, "Os2OpenClient: Unable to create pipe %s\n", pipename,0,0 );
137 DosWrite(hServer,&pipe_len,1,&byteWritten);
143 /* Connect to the pipe. */
145 rc = DosConnectNPipe (hfd);
146 if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
148 PRMSG(1, "Os2OpenClient: Unable to connect to pipe %s\n", pipename,0,0 );
155 /* Now write name to server on hServer */
156 server_string[0]=(char) strlen(clientname)+1;
157 strcpy(&server_string[1],clientname);
158 rc = DosWrite(hServer,server_string,(ULONG)server_string[0]+1,&byteWritten);
159 if(rc != 0){ /* Could not write to server pipe? */
160 PRMSG(1, "Os2OpenClient: Error writing to server pipe, handle=%d, rc=%d, w=%d\n",
161 hServer,rc,byteWritten );
168 PRMSG (5, "Os2OpenCLient: Wrote pipename %s to server; len %d written %d \n",
169 &server_string[1],server_string[0]+1,byteWritten);
172 /* The server will respond by opening the pipe. Wait for that for 30 secs */
175 DosSleep(50); /* Give it time to catch up but minimize race condition*/
176 rc = DosConnectNPipe(hfd);
177 while((rc == ERROR_PIPE_NOT_CONNECTED)&&(i++<60)) {
179 rc = DosConnectNPipe(hfd);
182 if(rc != 0){ /* Server has not responded! */
183 PRMSG(1, "Os2OpenClient: Timeout on wait for server response, handle=%d, rc=%d\n",hServer,rc,0 );
184 PRMSG(1, "\tProbable cause: the XServer has exited or crashed while the connection was being established\n",0,0,0 );
185 PRMSG(1, "\tor the XServer is too busy to respond.\n",0,0,0 );
192 /* OK, the server has connected! Fill-in the info and return */
196 /* Last check: make sure client is connected! */
198 rc = DosQueryNPHState(hfd,&State);
199 if(rc != 0){ /* Client is not connected! */
200 PRMSG(1, "Os2OpenClient: Client pipe does not appear connected. rc=%d, h=%d\n",rc,hfd,0 );
201 PRMSG(1, "\tProbable cause: the XServer has just exited.\n",0,0,0 );
207 namelen=sizeof(struct sockaddr);
208 if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
210 PRMSG (1, "Os2OpenClient: Can't allocate space for the addr\n",
216 ciptr->addrlen = namelen;
217 ((struct sockaddr *)ciptr->addr)->sa_family = AF_UNIX;
218 strcpy(((struct sockaddr *)ciptr->addr)->sa_data, "local");
220 if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
222 PRMSG (1, "Os2OpenCLient: Can't allocate space for the addr\n",
229 ciptr->peeraddrlen = namelen;
230 ((struct sockaddr *)ciptr->peeraddr)->sa_family = AF_UNIX;
231 strcpy (((struct sockaddr *)ciptr->peeraddr)->sa_data,"local");
233 PRMSG (5, "Os2OpenCLient: Filled in struct: len %d %d name %s\n",
234 ciptr->addrlen,ciptr->peeraddrlen,((struct sockaddr *)ciptr->peeraddr)->sa_data);
238 ciptr->family=AF_UNIX;
239 if((ciptr->fd=_imphandle(hfd))<0){
240 PRMSG(1, "Os2OpenClient: Could not import the pipe handle into EMX\n",0,0,0 );
241 PRMSG(1, "\tProbable cause: EMX has run out of free file handles.\n",0,0,0 );
244 xfree(ciptr->peeraddr);
248 PRMSG(5, "Os2OpenClient: pipe handle %d EMX handle %d\n",ciptr->index,ciptr->fd,0 );
249 fcntl(ciptr->fd,F_SETFL,O_NDELAY);
250 fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC);
253 #endif /* TRANS_CLIENT */
256 static XtransConnInfo
257 TRANS(Os2OpenServer)(thistrans, protocol, host, port)
258 Xtransport *thistrans;
267 struct sockaddr *addr_name;
268 XtransConnInfo ciptr;
272 if (! init_server_pipes()) return(NULL);
275 PRMSG(2,"Os2OpenServer(%s,%s,%s)\n",protocol,host,port);
277 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
279 PRMSG(1,"Os2OpenServer: xcalloc(1,%d) failed\n",
280 sizeof(struct _XtransConnInfo),0,0 );
285 if (port && *port ) {
286 if( *port == '/' ) { /* A full pathname */
287 (void) sprintf(pipename, "\\PIPE\\X\\%s", port);
289 (void) sprintf(pipename, "%s%s", "\\PIPE\\X\\xf86.", port);
292 (void) sprintf(pipename, "\\PIPE\\X\\xfree86");
295 PRMSG(5, "Os2OpenServer: Creating pipe %s\n",pipename, 0,0 );
297 rc = DosCreateNPipe (pipename, &hfd,
298 NP_NOINHERIT | NP_ACCESS_INBOUND,
299 1 | NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE,
302 PRMSG(1, "Os2OpenServer: Unable to create pipe %s, rc=%d\n", pipename,rc,0 );
303 PRMSG(1, "\tProbable cause: there is already another XServer running on display :%s\n",port,0,0 );
309 /* Connect to the pipe. */
311 rc = DosConnectNPipe (hfd);
312 if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
314 PRMSG(1, "Os2OpenServer: Unable to connect to pipe %s\n", pipename,0,0 );
320 /* Pipe is now connected and waiting for client connect */
322 /*** Put in info ***/
324 namelen=sizeof(struct sockaddr);
325 if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
327 PRMSG (1, "Os2OpenServer: Can't allocate space for the addr\n",
333 ciptr->addrlen = namelen;
334 ((struct sockaddr *)ciptr->addr)->sa_family = AF_UNIX;
335 strcpy (((struct sockaddr *)ciptr->addr)->sa_data, "local");
337 if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
339 PRMSG (1, "Os2OpenServer: Can't allocate space for the addr\n",
347 ciptr->peeraddrlen = namelen;
348 ((struct sockaddr *)ciptr->peeraddr)->sa_family = AF_UNIX;
349 strcpy(((struct sockaddr *)ciptr->peeraddr)->sa_data,"local");
351 PRMSG (5, "Os2OpenServer: Filled in struct: len %d %d name %s\n",
352 ciptr->addrlen,ciptr->peeraddrlen,((struct sockaddr *)ciptr->peeraddr)->sa_data);
354 ciptr->index=hfd; /* Save this for later use in this unused member of struct */
355 ciptr->flags=1; /* Listener */
356 ciptr->family=AF_UNIX;
358 if((ciptr->fd=_imphandle(hfd))<0){
361 xfree(ciptr->peeraddr);
365 PRMSG(5, "Os2OpenServer: Pipe handle %d EMX handle %d",ciptr->index,ciptr->fd,0 );
368 /* Attach the pipe sem to the pipe. Use handle index as key */
369 rc = DosSetNPipeSem(ciptr->fd, (HSEM)hPipeSem, ciptr->fd);
371 PRMSG(1, "Os2OpenCOTSServer: Could not attach sem %d to pipe %d, rc=%d\n",
372 hPipeSem,ciptr->fd,rc);
375 xfree(ciptr->peeraddr);
381 fcntl(ciptr->fd,F_SETFL,O_NDELAY);
382 fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC);
385 #endif /* TRANS_SERVER */
388 static XtransConnInfo
389 TRANS(Os2OpenCLTSClient)(thistrans, protocol, host, port)
390 Xtransport *thistrans;
395 PRMSG(2,"Os2OpenCLTSClient(%s,%s,%s)\n",protocol,host,port);
396 return TRANS(Os2OpenClient)(thistrans, protocol, host, port);
398 #endif /* TRANS_CLIENT */
401 static XtransConnInfo
402 TRANS(Os2OpenCOTSClient)(thistrans, protocol, host, port)
403 Xtransport *thistrans;
408 PRMSG(2,"Os2OpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
409 return TRANS(Os2OpenClient)(thistrans, protocol, host, port);
411 #endif /* TRANS_CLIENT */
415 static XtransConnInfo
416 TRANS(Os2OpenCLTSServer)(thistrans, protocol, host, port)
417 Xtransport *thistrans;
422 PRMSG(2,"Os2OpenCLTSServer(%s,%s,%s)\n",protocol,host,port);
423 return TRANS(Os2OpenServer)(thistrans, protocol, host, port);
425 #endif /* TRANS_SERVER */
429 static XtransConnInfo
430 TRANS(Os2OpenCOTSServer)(thistrans, protocol, host, port)
431 Xtransport *thistrans;
436 PRMSG(2,"Os2OpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
437 return TRANS(Os2OpenServer)(thistrans, protocol, host, port);
439 #endif /* TRANS_SERVER */
443 static XtransConnInfo
444 TRANS(Os2ReopenCOTSServer)(thistrans, fd, port)
445 Xtransport *thistrans;
450 XtransConnInfo ciptr;
454 PRMSG(2,"Os2ReopenCOTSServer(%d,%s)\n", fd, port, 0);
456 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
458 PRMSG(1,"Os2ReopenCOTSServer: xcalloc(1,%d) failed\n",
459 sizeof(struct _XtransConnInfo),0,0 );
463 strcpy(addr_name,"local");
464 namelen=sizeof(addr_name);
465 if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
467 PRMSG (1, "Os2ReopenCOTSServer: Can't allocate space for the addr\n",
473 ciptr->addrlen = namelen;
474 memcpy (ciptr->addr, addr_name, ciptr->addrlen);
475 if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
477 PRMSG (1, "Os2ReopenCOTSServer: Can't allocate space for the addr\n",
483 ciptr->peeraddrlen = namelen;
484 memcpy (ciptr->peeraddr,addr_name, ciptr->addrlen);
487 ciptr->family=AF_UNIX;
489 PRMSG(1,"Os2ReopenCOTSServer: Filled-in info for handle %d on port %s.\n", fd, port, 0);
494 static XtransConnInfo
495 TRANS(Os2ReopenCLTSServer)(thistrans, fd, port)
496 Xtransport *thistrans;
500 PRMSG(2,"Os2ReopenCLTSServer(%d,%s)\n", fd, port, 0);
501 return TRANS(Os2ReopenCOTSServer)(thistrans, fd, port);
506 TRANS(Os2SetOption)(ciptr, option, arg)
507 XtransConnInfo ciptr;
511 PRMSG(2,"Os2SetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
518 TRANS(Os2CreateListener)(ciptr, port)
519 XtransConnInfo ciptr;
522 PRMSG(2,"Os2CreateListener(%x->%d,%s)\n",ciptr,ciptr->fd,port);
526 static XtransConnInfo
527 TRANS(Os2Accept)(ciptr, status)
528 XtransConnInfo ciptr;
531 XtransConnInfo newciptr;
533 unsigned char length;
535 char clientname[256];
536 struct sockaddr *addr_name;
541 PRMSG(2,"Os2Accept(%x->%d)\n", ciptr, ciptr->fd,0);
542 if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL )
544 PRMSG(1,"Os2Accept: xcalloc(1,%d) failed\n",
545 sizeof(struct _XtransConnInfo),0,0 );
546 *status = TRANS_ACCEPT_BAD_MALLOC;
550 /* Read in length of client pipe name. If fails, then reset server pipe */
551 if((in=read(ciptr->fd,&length,1))<=0){
552 PRMSG(2,"Os2Accept: Error reading incoming connection, in=%d, error=%d\n",
554 *status = TRANS_ACCEPT_MISC_ERROR;
556 rc = DosDisConnectNPipe(ciptr->fd);
557 rc = DosConnectNPipe (ciptr->fd);
558 if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
560 PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
564 PRMSG(5, "Os2Accept: Bytes to read for name: %d\n",length,0,0 );
567 /* Check length for valid length ?? */
569 /* Now read in length bytes from pipe for client pipe name */
570 if((in=read(ciptr->fd,clientname,length))<=0){
571 PRMSG(2,"Os2Accept: Error reading incoming connection, in=%d, error=%d\n",
573 *status = TRANS_ACCEPT_MISC_ERROR;
575 rc = DosDisConnectNPipe(ciptr->fd);
576 rc = DosConnectNPipe (ciptr->fd);
577 if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
579 PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
583 clientname[length]='\0';
584 PRMSG(5, "Os2Accept: Server name %s length %d\n",clientname,length,0 );
587 /* Now we have the client pipe name. Open it with DosOpen */
589 rc = DosOpen(clientname,&hClient, &action, 0,
590 FILE_NORMAL, FILE_OPEN,
591 OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE,
594 PRMSG(5, "Os2Accept: Open pipe %s, handle = %d, rc=%d\n",clientname,hClient,rc );
597 PRMSG(1,"Os2Accept: Open pipe %s to client failed, rc=%d\n",
599 PRMSG(1, "\tProbable cause: the client has exited or timed-out.\n",0,0,0 );
601 rc = DosDisConnectNPipe(ciptr->fd);
602 rc = DosConnectNPipe (ciptr->fd);
603 if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
605 PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
610 rc = DosSetNPHState (hClient, NP_NOWAIT | NP_READMODE_BYTE);
613 PRMSG(1,"Os2Accept: Could not set pipe %s to non-blocking mode, rc=%d\n",
616 rc = DosDisConnectNPipe(ciptr->fd);
617 rc = DosConnectNPipe (ciptr->fd);
618 if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
620 PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
625 /* OK, we seem to be well connected to client. Now disconnect server pipe and put again in listen */
627 rc = DosDisConnectNPipe(ciptr->fd);
628 rc = DosConnectNPipe (ciptr->fd);
629 PRMSG(5, "Os2Accept: Reconnecting server pipe %d, rc = %d\n",ciptr->fd,rc,0 );
631 if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED)
633 PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 );
634 } /* Consider this non-fatal for present connection */
636 /* And finally fill-in info in newciptr */
638 namelen=sizeof(struct sockaddr);
639 if ((newciptr->addr = (char *) xalloc (namelen)) == NULL)
641 PRMSG (1, "Os2Accept: Can't allocate space for the addr\n",
648 newciptr->addrlen = namelen;
649 ((struct sockaddr *)newciptr->addr)->sa_family = AF_UNIX;
650 strcpy (((struct sockaddr *)newciptr->addr)->sa_data, "local");
652 if ((newciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
654 PRMSG (1, "Os2Accept: Can't allocate space for the addr\n",
662 newciptr->peeraddrlen = namelen;
663 ((struct sockaddr *)newciptr->peeraddr)->sa_family = AF_UNIX;
664 strcpy (((struct sockaddr *)newciptr->peeraddr)->sa_data, "local");
666 PRMSG (5, "Os2Accept: Filled in struct: len %d %d name %s\n",
667 newciptr->addrlen,newciptr->peeraddrlen,newciptr->peeraddr);
670 newciptr->index=hClient;
671 newciptr->family=AF_UNIX;
672 if((newciptr->fd=_imphandle(hClient))<0){
673 PRMSG(1,"Os2Accept: Could not import pipe %d into EMX, errno=%d\n",
675 PRMSG(1, "\tProbable cause: EMX has run out of file handles.\n",0,0,0 );
677 xfree(newciptr->addr);
678 xfree(newciptr->peeraddr);
682 PRMSG(5, "Os2Accept: Pipe handle %d EMX handle %d",newciptr->index,newciptr->fd,0 );
685 /* Attach the pipe sem to the pipe. Use handle index as key */
686 rc = DosSetNPipeSem(newciptr->fd, (HSEM)hPipeSem, newciptr->fd);
688 PRMSG(1, "Os2OpenCOTSServer: Could not attach sem %d to pipe %d, rc=%d\n",
689 hPipeSem,newciptr->fd,rc);
690 DosClose(newciptr->fd);
691 xfree(newciptr->addr);
692 xfree(newciptr->peeraddr);
698 fcntl(ciptr->fd,F_SETFL,O_NDELAY);
699 fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC);
704 #endif /* TRANS_SERVER */
709 TRANS(Os2Connect)(ciptr, host, port)
710 XtransConnInfo ciptr;
714 PRMSG(2,"Os2Connect(%x->%d,%s)\n", ciptr, ciptr->fd, port);
718 #endif /* TRANS_CLIENT */
721 TRANS(Os2BytesReadable)(ciptr, pend )
722 XtransConnInfo ciptr;
723 BytesReadable_t *pend;
725 ULONG rc, state, nread;
729 PRMSG(2,"Os2BytesReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend);
731 rc = DosPeekNPipe (ciptr->fd, &buffer, 0, &nread, &avail, &state);
738 if (state == NP_STATE_CLOSING)
745 *pend = avail.cbpipe;
750 TRANS(Os2Read)(ciptr, buf, size)
751 XtransConnInfo ciptr;
758 PRMSG(2,"Os2Read(%d,%x,%d)\n", ciptr->fd, buf, size );
760 rc = DosRead(ciptr->fd, buf, size, &ulRead);
764 else if ((rc == 232) || (rc == 231)){
772 else if ((rc == 109) || (rc == 230) || (rc == 233)){
777 PRMSG(2,"Os2Read: Unknown return code from DosRead, fd %d rc=%d\n", ciptr->fd,rc,0 );
785 TRANS(Os2Write)(ciptr, buf, size)
786 XtransConnInfo ciptr;
793 PRMSG(2,"Os2Write(%d,%x,%d)\n", ciptr->fd, buf, size );
794 rc = DosWrite(ciptr->fd, buf, size, &nWritten);
802 else if ((rc == 39) || (rc == 112)){
806 else if ((rc == 109) || (rc == 230) || (rc == 233)){
815 PRMSG(2,"(Os2Write)Unknown return code from DosWrite, fd %d rc=%d\n", ciptr->fd,rc,0 );
823 TRANS(Os2Readv)(ciptr, buf, size)
824 XtransConnInfo ciptr;
829 PRMSG(2,"Os2Readv(%d,%x,%d)\n", ciptr->fd, buf, size );
830 ret = READV(ciptr,buf,size);
831 if ((ret <0) && (errno == EINVAL)) errno = EPIPE;
836 TRANS(Os2Writev)(ciptr, buf, size)
837 XtransConnInfo ciptr;
842 PRMSG(2,"Os2Writev(%d,%x,%d)\n", ciptr->fd, buf, size );
843 ret = WRITEV(ciptr,buf,size);
844 if ((ret <0) && (errno == EINVAL)) errno = EPIPE;
845 if ((ret <0) && (errno == ENOSPC)) errno = EAGAIN;
850 TRANS(Os2Disconnect)(ciptr)
851 XtransConnInfo ciptr;
853 PRMSG(2,"Os2Disconnect(%x->%d)\n", ciptr, ciptr->fd, 0);
858 TRANS(Os2Close)(ciptr)
859 XtransConnInfo ciptr;
862 PRMSG(2,"Os2Close(%x->%d)\n", ciptr, ciptr->fd ,0);
863 ret=close(ciptr->fd);
868 TRANS(Os2CloseForCloning)(ciptr)
869 XtransConnInfo ciptr;
873 PRMSG(2,"Os2CloseForCloning(%x->%d)\n", ciptr, ciptr->fd ,0);
874 ret=close(ciptr->fd);
879 Xtransport TRANS(OS2LocalFuncs) = {
880 /* Local Interface */
884 TRANS(Os2OpenCOTSClient),
885 #endif /* TRANS_CLIENT */
887 TRANS(Os2OpenCOTSServer),
888 #endif /* TRANS_SERVER */
890 TRANS(Os2OpenCLTSClient),
891 #endif /* TRANS_CLIENT */
893 TRANS(Os2OpenCLTSServer),
894 #endif /* TRANS_SERVER */
896 TRANS(Os2ReopenCOTSServer),
897 TRANS(Os2ReopenCLTSServer),
901 TRANS(Os2CreateListener),
902 NULL, /* ResetListener */
904 #endif /* TRANS_SERVER */
907 #endif /* TRANS_CLIENT */
908 TRANS(Os2BytesReadable),
913 TRANS(Os2Disconnect),
915 TRANS(Os2CloseForCloning),
919 /* This function is used in the server to initialize the semaphore used with pipes */
921 BOOL init_server_pipes()
923 static BOOL first_time=TRUE;
927 rc = DosCreateEventSem(NULL, &hPipeSem,DC_SEM_SHARED,FALSE);
929 PRMSG(1,"Os2OpenListener (init_server_pipes): Could not create pipe semaphore, rc=%d\n",