void main( int argc, char *argv[] ) { APIRET rc; HFILE h; unsigned long actiontaken; unsigned long sent; char done; if( argc > 1 && (argv[1][0] == 'q' || argv[1][0] == 'Q') ) { rc = DosOpen( PREFIX DEFAULT_NAME, &h, &actiontaken, 0ul, 0, 0x01, 0x41, 0ul ); if( rc == 0 ) { done = LNK_SHUTDOWN; DosWrite( h, &done, sizeof( done ), &sent ); DosClose( h ); } exit( 0 ); } CmdProc = getenv( "COMSPEC" ); if( CmdProc == NULL ) { fprintf( stderr, "Unable to find command processor\n" ); exit( 1 ); } //NYI: need to accept name for link pipe rc = DosCreateNPipe( PREFIX DEFAULT_NAME, &LnkHdl, NP_NOINHERIT | NP_NOWRITEBEHIND | NP_ACCESS_DUPLEX, NP_WAIT | NP_READMODE_MESSAGE | NP_TYPE_MESSAGE | 1, MAX_TRANS, MAX_TRANS, 0 ); if( rc != 0 ) { fprintf( stderr, "Unable to create link pipe\n" ); exit( 1 ); } sprintf( RedirName, PREFIX "%d", getpid() ); rc = DosCreateNPipe( RedirName, &RedirHdl, NP_NOINHERIT | NP_WRITEBEHIND | NP_ACCESS_INBOUND, NP_WAIT | NP_READMODE_BYTE | NP_TYPE_BYTE | 1, MAX_TRANS, MAX_TRANS, 0 ); if( rc != 0 ) { fprintf( stderr, "Unable to create redirection pipe\n" ); exit( 1 ); } DosSetFHState( LnkHdl, OPEN_FLAGS_NOINHERIT ); DosSetFHState( RedirHdl, OPEN_FLAGS_NOINHERIT ); for( ;; ) { rc = DosConnectNPipe( LnkHdl ); if( rc == 0 ) { ProcessConnection(); DosDisConnectNPipe( LnkHdl ); } } }
/* open_subprocess_connection acts like the unix-known function pipe and sets * ep->RedirectedFile if necessary. Just in the latter case ep->data * is set to the filename. * Close the handles with __regina_close later. * Do IO by using Os2_read() and Os2_write(). */ static int Os2_open_subprocess_connection(const tsd_t *TSD, environpart *ep) { #define MAGIC_MAX 2000000 /* Much beyond maximum, see below */ static volatile unsigned BaseIndex = MAGIC_MAX; char buf[40]; unsigned i; unsigned start,run; ULONG rc, openmode, dummy; HPIPE in = (HPIPE) -1, out; /* We have to use named pipes for various reasons. */ openmode = (ep->flags.isinput) ? NP_ACCESS_OUTBOUND : NP_ACCESS_INBOUND; openmode |= NP_NOINHERIT | NP_WRITEBEHIND; /* algorithm: * select a random number, e.g. a mixture of pid, tid and time. * increment this number by a fixed amount until we reach the starting * value again. Do a wrap around and an increment which is a unique prime. * The number 1000000 has the primes 2 and 5. We may use all primes * except 2 and 5; 9901 (which is prime) will give a good distribution. * * We want to be able to create several temporary files at once without * more OS calls than needed. Thus, we have a program wide runner to * ensure a simple distribution without strength. */ if (BaseIndex == MAGIC_MAX) { /* * We have to create (nearly) reentrant code. */ i = (unsigned) getpid() * (unsigned) time(NULL); i %= 1000000; if (!i) i = 1; BaseIndex = i; } if (++BaseIndex >= 1000000) BaseIndex = 1; start = TSD->thread_id; if (start == 0) start = 999999; start *= (unsigned) (clock() + 1); start *= BaseIndex; start %= 1000000; run = start; for (i = 0;i <= 1000000;i++) { sprintf(buf,"%s%06u._rx", "\\pipe\\tmp\\", run ); rc = DosCreateNPipe(buf, &in, openmode, NP_TYPE_BYTE | NP_READMODE_BYTE | NP_NOWAIT | 1, 4096, 4096, 0); /* msec timeout */ if (rc == NO_ERROR) break; if (rc != ERROR_PIPE_BUSY) { errno = EPIPE; return(-1); } /* Check the next possible candidate */ run += 9901; run %= 1000000; if (run == start) /* paranoia check. i <= 1000000 should hit exactly */ break; /* here */ } if (in == (HPIPE) -1) { errno = EPIPE; return(-1); } DosConnectNPipe(in); /* ignore the return */ openmode = (ep->flags.isinput) ? OPEN_ACCESS_READONLY : OPEN_ACCESS_WRITEONLY; openmode |= OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYREADWRITE; rc = DosOpen(buf, &out, &dummy, /* action */ 0ul, /* initial size */ FILE_NORMAL, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, openmode, NULL); /* peaop2 */ if (rc != NO_ERROR) { DosClose(in); errno = EPIPE; /* guess */ return(-1); } /* Now do the final checking, the server end must be connected */ if (DosConnectNPipe(in) != NO_ERROR) { DosClose(out); DosClose(in); errno = EPIPE; /* guess */ return(-1); } /* We always want to have the server's end of the named pipe: */ if (ep->flags.isinput) { ep->hdls[0] = (int) out; ep->hdls[1] = (int) in; } else { ep->hdls[0] = (int) in; ep->hdls[1] = (int) out; } return(0); #undef MAGIC_MAX }
void connectthread( void * parameters ) { struct connectthreadparameters * ctp; unsigned long curmax; HPIPE hpipe; struct messagequeue * msgq; unsigned char maxpipes; char pipename[CCHMAXPATH]; APIRET rc; long req; HEV shutdown; HEV terminated; /* Grab data from parameter block, and signal when done. */ ctp = ( struct connectthreadparameters * ) parameters; maxpipes = ctp->maxpipes; strcpy(pipename,ctp->pipename); shutdown = ctp->shutdown; msgq = ctp->msgq; terminated = ctp->terminated; DosPostEventSem(ctp->initialized); /* Clear the pipe handle ( this is checked for a non-NULLHANDLE ** ** value on thread exit ). */ hpipe = NULLHANDLE; create: /* Create a new instance of the pipe. */ rc = DosCreateNPipe( pipename, &hpipe, NP_NOINHERIT|NP_ACCESS_DUPLEX, NP_NOWAIT|NP_TYPE_BYTE|NP_READMODE_BYTE|maxpipes, inbuffersize, outbuffersize, 0 ); if ( rc != NO_ERROR && rc != ERROR_PIPE_BUSY && rc != ERROR_TOO_MANY_OPEN_FILES ) { /* Some unexpected error has occurred. Notify the ** ** application. */ DosRequestMutexSem(msgq->access,SEM_INDEFINITE_WAIT); *msgq->qtail = malloc( sizeof( struct message ) ); (*msgq->qtail)->id = cterror; (*msgq->qtail)->data.cterrordata.ec = apiret2ec(rc); (*msgq->qtail)->next = NULL; DosPostEventSem(msgq->available); DosReleaseMutexSem(msgq->access); goto completed; } if ( rc == ERROR_PIPE_BUSY ) /* Max pipes created. */ goto busy; if ( rc == ERROR_TOO_MANY_OPEN_FILES ) { req = 1; rc = DosSetRelMaxFH(&req,&curmax); if ( rc == NO_ERROR ) goto create; /* Can trigger a 'max connections reached' message here ... */ goto busy; } connect: /* Connect pipe ( allows client to connect ). */ rc = DosConnectNPipe(hpipe); if ( rc != NO_ERROR && rc != ERROR_PIPE_NOT_CONNECTED && rc != ERROR_BROKEN_PIPE ) { /* Unexpected error ... */ DosRequestMutexSem(msgq->access,SEM_INDEFINITE_WAIT); *msgq->qtail = malloc( sizeof( struct message ) ); (*msgq->qtail)->id = cterror; (*msgq->qtail)->data.cterrordata.ec = apiret2ec(rc); (*msgq->qtail)->next = NULL; DosPostEventSem(msgq->available); DosReleaseMutexSem(msgq->access); DosClose(hpipe); hpipe = NULLHANDLE; goto completed; } if ( rc == ERROR_PIPE_NOT_CONNECTED ) /* No client connected, so wait a while ... */ goto waiting; if ( rc == ERROR_BROKEN_PIPE ) { /* Client connected, but probably immediately closed. */ DosClose(hpipe); hpipe = NULLHANDLE; goto create; } /* Send handle of the newly connected pipe to the application. */ DosRequestMutexSem(msgq->access,SEM_INDEFINITE_WAIT); *msgq->qtail = malloc( sizeof( struct message ) ); (*msgq->qtail)->id = connected; (*msgq->qtail)->data.connecteddata.hpipe = hpipe; (*msgq->qtail)->next = NULL; DosPostEventSem(msgq->available); DosReleaseMutexSem(msgq->access); /* Create a new instance of the pipe for the next client. */ goto create; waiting: /* Wait to see if the application is ready to exit. */ rc = DosWaitEventSem(shutdown,connectpolltimeout); if ( rc != ERROR_TIMEOUT ) goto completed; /* Not shutting down, so wait for a client to connect. */ goto connect; busy: /* Pipe is busy. */ rc = DosWaitEventSem(shutdown,connectpolltimeout); if ( rc != ERROR_TIMEOUT ) goto completed; /* Not shutting down, but in this case, unlike waiting above, go ** ** and create a new pipe. */ goto create; completed: /* Processing completed. */ /* Close pipe if no client had connected. */ if ( hpipe != NULLHANDLE ) DosClose(hpipe); /* Notify application that the thread will not accept more ** ** connections. */ DosRequestMutexSem(msgq->access,SEM_INDEFINITE_WAIT); *msgq->qtail = malloc( sizeof( struct message ) ); (*msgq->qtail)->id = ctclosed; (*msgq->qtail)->next = NULL; DosPostEventSem(msgq->available); DosReleaseMutexSem(msgq->access); /* Shutdown processing completed. Signal owner. */ DosEnterCritSec(); DosPostEventSem(terminated); }
APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in, apr_file_t **out, apr_pool_t *pool) { ULONG filedes[2]; ULONG rc, action; static int id = 0; char pipename[50]; sprintf(pipename, "/pipe/%d.%d", getpid(), id++); rc = DosCreateNPipe(pipename, filedes, NP_ACCESS_INBOUND, NP_NOWAIT|1, 4096, 4096, 0); if (rc) return APR_FROM_OS_ERROR(rc); rc = DosConnectNPipe(filedes[0]); if (rc && rc != ERROR_PIPE_NOT_CONNECTED) { DosClose(filedes[0]); return APR_FROM_OS_ERROR(rc); } rc = DosOpen (pipename, filedes+1, &action, 0, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW, OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE, NULL); if (rc) { DosClose(filedes[0]); return APR_FROM_OS_ERROR(rc); } (*in) = (apr_file_t *)apr_palloc(pool, sizeof(apr_file_t)); rc = DosCreateEventSem(NULL, &(*in)->pipeSem, DC_SEM_SHARED, FALSE); if (rc) { DosClose(filedes[0]); DosClose(filedes[1]); return APR_FROM_OS_ERROR(rc); } rc = DosSetNPipeSem(filedes[0], (HSEM)(*in)->pipeSem, 1); if (!rc) { rc = DosSetNPHState(filedes[0], NP_WAIT); } if (rc) { DosClose(filedes[0]); DosClose(filedes[1]); DosCloseEventSem((*in)->pipeSem); return APR_FROM_OS_ERROR(rc); } (*in)->pool = pool; (*in)->filedes = filedes[0]; (*in)->fname = apr_pstrdup(pool, pipename); (*in)->isopen = TRUE; (*in)->buffered = FALSE; (*in)->flags = APR_FOPEN_READ; (*in)->pipe = 1; (*in)->timeout = -1; (*in)->blocking = BLK_ON; (*in)->ungetchar = -1; apr_pool_cleanup_register(pool, *in, apr_file_cleanup, apr_pool_cleanup_null); (*out) = (apr_file_t *)apr_palloc(pool, sizeof(apr_file_t)); rc = DosCreateEventSem(NULL, &(*out)->pipeSem, DC_SEM_SHARED, FALSE); if (rc) { DosClose(filedes[0]); DosClose(filedes[1]); DosCloseEventSem((*in)->pipeSem); return APR_FROM_OS_ERROR(rc); } rc = DosSetNPipeSem(filedes[1], (HSEM)(*out)->pipeSem, 1); if (rc) { DosClose(filedes[0]); DosClose(filedes[1]); DosCloseEventSem((*in)->pipeSem); DosCloseEventSem((*out)->pipeSem); return APR_FROM_OS_ERROR(rc); } (*out)->pool = pool; (*out)->filedes = filedes[1]; (*out)->fname = apr_pstrdup(pool, pipename); (*out)->isopen = TRUE; (*out)->buffered = FALSE; (*out)->flags = APR_FOPEN_WRITE; (*out)->pipe = 1; (*out)->timeout = -1; (*out)->blocking = BLK_ON; (*out)->ungetchar = -1; apr_pool_cleanup_register(pool, *out, apr_file_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
static int CreatePipeChild(PID& pid, HPIPE& hfPipe, char *Command) { static int PCount = 0; char szPipe[32]; char FailBuf[256]; char *Args; int arglen = 0; char *Prog; RESULTCODES rc_code; ULONG ulAction; // ULONG ulNew; HPIPE hfChildPipe; HFILE hfNewStdOut = (HFILE)-1, hfNewStdErr = (HFILE)-1; HFILE hfStdOut = 1, hfStdErr = 2; int rc; sprintf(szPipe, "\\PIPE\\eFTE%d\\CHILD%d", getpid(), PCount); PCount++; rc = DosCreateNPipe(szPipe, &hfPipe, NP_NOINHERIT | NP_ACCESS_INBOUND, NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE | 1, 0, 4096, 0); if (rc != 0) return -1; rc = DosConnectNPipe(hfPipe); if ((rc != 0) && (rc != ERROR_PIPE_NOT_CONNECTED)) { DosClose(hfPipe); return -1; } rc = DosSetNPHState(hfPipe, NP_WAIT | NP_READMODE_BYTE); if (rc != 0) { DosClose(hfPipe); return -1; } rc = DosOpen(szPipe, &hfChildPipe, &ulAction, 0, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW, OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE, NULL); if (rc != 0) { DosClose(hfPipe); return -1; } // Duplicate handles DosDupHandle(hfStdOut, &hfNewStdOut); DosDupHandle(hfStdErr, &hfNewStdErr); // Close existing handles for current process DosClose(hfStdOut); DosClose(hfStdErr); // Redirect existing handles to new file DosDupHandle(hfChildPipe, &hfStdOut); DosDupHandle(hfChildPipe, &hfStdErr); // Let started program inherit handles from parent Prog = getenv("COMSPEC"); Args = (char *)malloc(strlen(Prog) + 1 + 3 + strlen(Command) + 1 + 1); if (Args == NULL) { DosClose(hfPipe); return -1; } strcpy(Args, Prog); arglen = strlen(Args) + 1; strcpy(Args + arglen, "/c "); arglen += 3; strcpy(Args + arglen, Command); arglen += strlen(Command) + 1; Args[arglen] = '\0'; rc = DosExecPgm(FailBuf, sizeof(FailBuf), EXEC_ASYNCRESULT, // | EXEC_BACKGROUND, Args, 0, &rc_code, Prog); free(Args); // Get back original handles DosDupHandle(hfNewStdOut, &hfStdOut); DosDupHandle(hfNewStdErr, &hfStdErr); // Close the duplicated handles - no longer needed DosClose(hfNewStdOut); DosClose(hfNewStdErr); DosClose(hfChildPipe); // pipe one way, close out write end if (rc != 0) { DosClose(hfPipe); return -1; } pid = rc_code.codeTerminate; // get pid when successful return 0; }
VOID GameThread(VOID *hpTempPipe) { HPIPE hpGamePipe; BOOL fQuit=FALSE; PPIB dummy; PTIB ptibThrdInfo; ULONG ulID; USHORT usMsg, usData, GameBoard[DIVISIONS][DIVISIONS], usTotalMoves=0; /* save pipe handle in own memory */ hpGamePipe = *(HPIPE *)hpTempPipe; /* get thread ID for use in displaying messages */ if((BOOL)DosGetInfoBlocks(&ptibThrdInfo, &dummy)) { ulID = 0; } else { ulID = ptibThrdInfo->tib_ptib2->tib2_ultid; } InitBoard(GameBoard); /* initialize random number generator */ srand((unsigned) ulID); if(!(BOOL)DosConnectNPipe(hpGamePipe)) { while (!fAppExit && !fQuit && !(BOOL)(Pipe_IO(CLIENT, hpGamePipe, &usMsg, &usData, ulID)) && !fAppExit) { switch (usMsg) { case CLIENT_MOVE: /* enter move from message */ *((USHORT *)GameBoard + usData) = CLIENT_NUM; usTotalMoves++; /* test for win if total moves >= DIVISIONS*2-1 */ if (usTotalMoves >= DIVISIONS*2-1 && ((BOOL)(usData=WinTest(GameBoard)) || usTotalMoves == DIVISIONS*DIVISIONS)) { /* notify of win or draw, and break (switch) on return */ if (!usData) { usData = DIVISIONS*DIVISIONS; usMsg = WIN_DRAW; } else { usMsg = WIN_CLIENT; } if ((BOOL)Pipe_IO(SERVER, hpGamePipe, &usMsg, &usData, ulID)) { WinPostMsg(hwndMain, WM_MSG, MPFROMLONG(IDMSG_PIPE_WRITE_FAILED), MPVOID); fQuit = TRUE; break; } /* call InitBoard on win */ InitBoard(GameBoard); usTotalMoves = 0; break; /* switch */ } /* NO BREAK */ case YOU_FIRST: /* get move if there are moves left */ usData = GetMove(GameBoard, usTotalMoves); usTotalMoves++; /* test for win if total moves >= DIVISIONS*2-1 */ if (usTotalMoves >= DIVISIONS*2-1 && ((BOOL)(usMsg=WinTest(GameBoard)) || usTotalMoves == DIVISIONS*DIVISIONS)) { /* write game_won message with winning move */ if (!usMsg) { usMsg = WIN_DRAW; } else { usMsg = WIN_SERVER; } if ((BOOL)Pipe_IO(SERVER, hpGamePipe, &usMsg, &usData, ulID)) { WinPostMsg(hwndMain, WM_MSG, MPFROMLONG(IDMSG_PIPE_WRITE_FAILED), MPVOID); fQuit = TRUE; break; } /* call InitBoard on win */ InitBoard(GameBoard); usTotalMoves = 0; } /* else */ else { /* write move to client */ usMsg = SERVER_MOVE; if ((BOOL)Pipe_IO(SERVER, hpGamePipe, &usMsg, &usData, ulID)) { WinPostMsg(hwndMain, WM_MSG, MPFROMLONG(IDMSG_PIPE_WRITE_FAILED), MPVOID); fQuit = TRUE; } } break; case ERROR_MSG: /* post the error to message queue */ WinPostMsg(hwndMain, WM_MSG, MPFROMSHORT(usData), MPVOID); case CLIENT_QUIT: /* quit while */ fQuit = TRUE; } } DosDisConnectNPipe(hpGamePipe); } DosClose(hpGamePipe); }
static void IPCHelperThread( void *arg ) { libvlc_int_t *libvlc = arg; ULONG ulCmd; int i_argc; char **ppsz_argv; size_t i_len; ULONG cbActual; int i_options; /* Add files to the playlist */ playlist_t *p_playlist; do { DosConnectNPipe( hpipeIPC ); /* Read command */ DosRead( hpipeIPC, &ulCmd, sizeof( ulCmd ), &cbActual ); if( ulCmd == IPC_CMD_QUIT ) continue; /* Read a count of arguments */ DosRead( hpipeIPC, &i_argc, sizeof( i_argc ), &cbActual ); ppsz_argv = malloc( i_argc * sizeof( *ppsz_argv )); for( int i_opt = 0; i_opt < i_argc; i_opt++ ) { /* Read a length of argv */ DosRead( hpipeIPC, &i_len, sizeof( i_len ), &cbActual ); ppsz_argv[ i_opt ] = malloc( i_len ); /* Read argv */ DosRead( hpipeIPC, ppsz_argv[ i_opt ], i_len, &cbActual ); } p_playlist = libvlc_priv(libvlc)->playlist; for( int i_opt = 0; i_opt < i_argc;) { i_options = 0; /* Count the input options */ while( i_opt + i_options + 1 < i_argc && *ppsz_argv[ i_opt + i_options + 1 ] == ':' ) i_options++; if( p_playlist ) { playlist_AddExt( p_playlist, ppsz_argv[ i_opt ], NULL, (( i_opt || ulCmd == IPC_CMD_ENQUEUE ) ? 0 : PLAYLIST_GO ), i_options, ( char const ** ) ( i_options ? &ppsz_argv[ i_opt + 1 ] : NULL ), VLC_INPUT_OPTION_TRUSTED, true ); } for( ; i_options >= 0; i_options-- ) free( ppsz_argv[ i_opt++ ]); } free( ppsz_argv ); } while( !DosDisConnectNPipe( hpipeIPC ) && ulCmd != IPC_CMD_QUIT ); DosClose( hpipeIPC ); hpipeIPC = NULLHANDLE; tidIPCFirst = -1; tidIPCHelper = -1; }
static void ProcessConnection( void ) { char buff[MAX_TRANS]; ULONG bytes_read; unsigned long max; struct _AVAILDATA BytesAvail; ULONG PipeState; APIRET rc; RESULTCODES res; PID dummy; char *dir; for( ;; ) { DosRead( LnkHdl, buff, sizeof( buff ), &bytes_read ); if( bytes_read == 0 ) break; buff[bytes_read] = '\0'; switch( buff[0] ) { case LNK_CWD: rc = 0; dir = &buff[1]; if( isalpha( dir[0] ) && dir[1] == ':' ) { rc = DosSetDefaultDisk( toupper( dir[0] ) - ('A' - 1) ); dir += 2; } if( rc == 0 && dir[0] != '\0' ) { rc = DosSetCurrentDir( dir ); } SendStatus( rc ); break; case LNK_RUN: DosSetNPHState( RedirHdl, NP_NOWAIT | NP_READMODE_BYTE ); DosConnectNPipe( RedirHdl ); DosSetNPHState( RedirHdl, NP_WAIT | NP_READMODE_BYTE ); RunCmd( &buff[1] ); break; case LNK_QUERY: max = *(unsigned long *)&buff[1]; if( max > sizeof( buff ) ) max = sizeof( buff ); --max; rc = DosPeekNPipe(RedirHdl, buff, 0, &bytes_read, &BytesAvail, &PipeState ); if( rc == 0 && BytesAvail.cbpipe != 0 ) { DosRead( RedirHdl, &buff[1], max, &bytes_read ); buff[0] = LNK_OUTPUT; DosWrite( LnkHdl, buff, bytes_read + 1, &bytes_read ); } else { rc = DosWaitChild( DCWA_PROCESS, DCWW_NOWAIT, &res, &dummy, ProcId ); if( rc != ERROR_CHILD_NOT_COMPLETE ) { DosDisConnectNPipe( RedirHdl ); SendStatus( res.codeResult ); ProcId = 0; } else { /* let someone else run */ DosSleep( 1 ); buff[0] = LNK_NOP; DosWrite( LnkHdl, buff, 1, &bytes_read ); } } break; case LNK_CANCEL: DosSendSignalException( ProcId, XCPT_SIGNAL_INTR ); break; case LNK_ABORT: DosKillProcess( DKP_PROCESSTREE, ProcId ); break; case LNK_DONE: return; case LNK_SHUTDOWN: exit( 0 ); break; } } }
/*@ XNamedPipeServer::Connect(void) @group open/close @remarks Wait for a client */ LONG XNamedPipeServer::Connect(void) { return DosConnectNPipe(handle); }
int main(int argc, char **argv) { int c, end = 0, lines = 25; int x, y, h, n, v; FILE *in=NULL; char a; char buf[160]; HPIPE pipe; APIRET rc; char *target; /* Check command line */ if (argc!=2 && argc!=3) { printf("Usage: %s Mirror|Recall|Choice|Term-4|...|Term-7 [number of lines]\n" "Start this before angband.exe\n", argv[0]); exit(1); } if (argc==3) lines = atoi(argv[2]); if (lines <= 0) lines = 25; printf("Looking for Angband... press ^C to abort\n"); target=strdup(argv[1]); for (c=0; c<strlen(target); c++) target[c]=tolower(target[c]); strnfmt(buf, 160, "\\pipe\\angband\\%s", target); do { rc=DosCreateNPipe((PSZ)buf, /* Create pipe */ &pipe, NP_ACCESS_INBOUND, NP_WAIT|NP_TYPE_BYTE|NP_READMODE_BYTE|1, 1, /* No output buffer */ 1, /* No input buffer */ -1); if (rc) /* Pipe not created */ { printf("DosCreateNPipe: rc=%ld, pipe=%ld\n", (long)rc, (long)pipe); break; } do { rc=DosConnectNPipe(pipe); /* Wait for angband to connect */ if (!rc) break; _sleep2(500); /* Sleep for 0.5s */ } while (_read_kbd(0, 0, 0)==-1); /* Until key pressed */ if (rc) break; h=_imphandle(pipe); /* Register handle with io */ setmode(h, O_BINARY); /* Make it binary */ in=fdopen(h, "rb"); /* Register handle with stdio */ } while (0); /* We don't need no stinking exception handling <g> */ if (!in) { printf("Sorry, the pipe connection to Angband could not be established.\n"); exit(1); } printf("Connected.\n"); strnfmt(buf, 160, "mode co80,%d", lines); system(buf); /* Infinite loop */ while (!end) { /* Get command */ c = fgetc(in); switch (c) { case PIP_XTRA: if (!fread(&n, sizeof(x), 1, in) || !fread(&v, sizeof(y), 1, in)) abort(); /* This hack prevents another hack */ printf("Sorry, angband.exe and aclient.exe don't fit together.\n"); exit(1); break; case PIP_CURS: if (!fread(&x, sizeof(x), 1, in) || !fread(&y, sizeof(y), 1, in)) abort(); Term_curs_emx(x, y); break; case PIP_WIPE: if (!fread(&x, sizeof(x), 1, in) || !fread(&y, sizeof(y), 1, in) || !fread(&n, sizeof(n), 1, in)) abort(); Term_wipe_emx(x, y, n); break; case PIP_TEXT: if (!fread(&x, sizeof(x), 1, in) || !fread(&y, sizeof(y), 1, in) || !fread(&n, sizeof(n), 1, in) || !fread(&a, sizeof(a), 1, in) || (n > 160) || !fread(buf, n, 1, in)) abort(); Term_text_emx(x, y, n, a, buf); break; case PIP_INIT: Term_init_emx(NULL); break; case PIP_NUKE: case EOF: default: Term_nuke_emx(NULL); end=1; break; } } return 0; }
static XtransConnInfo TRANS(Os2OpenClient)(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_SERVER static XtransConnInfo TRANS(Os2OpenServer)(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); }
static XtransConnInfo TRANS(Os2Accept)(XtransConnInfo ciptr, int *status) { XtransConnInfo newciptr; HFILE hClient; unsigned char length; ULONG action; char clientname[256]; struct sockaddr *addr_name; int in,namelen; APIRET rc; PRMSG(2,"Os2Accept(%x->%d)\n", ciptr, ciptr->fd,0); if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL ) { PRMSG(1,"Os2Accept: xcalloc(1,%d) failed\n", sizeof(struct _XtransConnInfo),0,0 ); *status = TRANS_ACCEPT_BAD_MALLOC; return NULL; } /* Read in length of client pipe name. If fails, then reset server pipe */ if((in=read(ciptr->fd,&length,1))<=0){ PRMSG(2,"Os2Accept: Error reading incoming connection, in=%d, error=%d\n", in,errno,0 ); *status = TRANS_ACCEPT_MISC_ERROR; xfree(newciptr); rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } return NULL; } PRMSG(5, "Os2Accept: Bytes to read for name: %d\n",length,0,0 ); /* Check length for valid length ?? */ /* Now read in length bytes from pipe for client pipe name */ if((in=read(ciptr->fd,clientname,length))<=0){ PRMSG(2,"Os2Accept: Error reading incoming connection, in=%d, error=%d\n", in,errno,0 ); *status = TRANS_ACCEPT_MISC_ERROR; xfree(newciptr); rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } return NULL; } clientname[length]='\0'; PRMSG(5, "Os2Accept: Server name %s length %d\n",clientname,length,0 ); /* Now we have the client pipe name. Open it with DosOpen */ rc = DosOpen(clientname,&hClient, &action, 0, FILE_NORMAL, FILE_OPEN, OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, (PEAOP2)NULL); PRMSG(5, "Os2Accept: Open pipe %s, handle = %d, rc=%d\n",clientname,hClient,rc ); if (rc) { PRMSG(1,"Os2Accept: Open pipe %s to client failed, rc=%d\n", clientname,rc,0 ); PRMSG(1, "\tProbable cause: the client has exited or timed-out.\n",0,0,0 ); xfree(newciptr); rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } return NULL; } rc = DosSetNPHState (hClient, NP_NOWAIT | NP_READMODE_BYTE); if (rc != 0) { PRMSG(1,"Os2Accept: Could not set pipe %s to non-blocking mode, rc=%d\n", hClient,rc,0 ); xfree(newciptr); rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } return NULL; } /* OK, we seem to be well connected to client. Now disconnect server pipe and put again in listen */ rc = DosDisConnectNPipe(ciptr->fd); rc = DosConnectNPipe (ciptr->fd); PRMSG(5, "Os2Accept: Reconnecting server pipe %d, rc = %d\n",ciptr->fd,rc,0 ); if (rc != 0 && rc != ERROR_PIPE_NOT_CONNECTED) { PRMSG(1, "Os2Accept: Unable to reconnect server pipe %d\n", ciptr->fd,0,0 ); } /* Consider this non-fatal for present connection */ /* And finally fill-in info in newciptr */ namelen=sizeof(struct sockaddr); if ((newciptr->addr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2Accept: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hClient); xfree(newciptr); return(NULL); } newciptr->addrlen = namelen; ((struct sockaddr *)newciptr->addr)->sa_family = AF_UNIX; strcpy (((struct sockaddr *)newciptr->addr)->sa_data, "local"); if ((newciptr->peeraddr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "Os2Accept: Can't allocate space for the addr\n", 0, 0, 0); DosClose(hClient); xfree(ciptr->addr); xfree(newciptr); return(NULL); } newciptr->peeraddrlen = namelen; ((struct sockaddr *)newciptr->peeraddr)->sa_family = AF_UNIX; strcpy (((struct sockaddr *)newciptr->peeraddr)->sa_data, "local"); PRMSG (5, "Os2Accept: Filled in struct: len %d %d name %s\n", newciptr->addrlen,newciptr->peeraddrlen,newciptr->peeraddr); newciptr->index=hClient; newciptr->family=AF_UNIX; if((newciptr->fd=_imphandle(hClient))<0){ PRMSG(1,"Os2Accept: Could not import pipe %d into EMX, errno=%d\n", hClient,errno,0 ); PRMSG(1, "\tProbable cause: EMX has run out of file handles.\n",0,0,0 ); DosClose(hClient); xfree(newciptr->addr); xfree(newciptr->peeraddr); xfree(newciptr); return(NULL); } PRMSG(5, "Os2Accept: Pipe handle %d EMX handle %d",newciptr->index,newciptr->fd,0 ); #ifdef XSERV_t /* Attach the pipe sem to the pipe. Use handle index as key */ rc = DosSetNPipeSem(newciptr->fd, (HSEM)hPipeSem, newciptr->fd); if (rc){ PRMSG(1, "Os2OpenCOTSServer: Could not attach sem %d to pipe %d, rc=%d\n", hPipeSem,newciptr->fd,rc); DosClose(newciptr->fd); xfree(newciptr->addr); xfree(newciptr->peeraddr); xfree(newciptr); return(NULL); } #endif fcntl(ciptr->fd,F_SETFL,O_NDELAY); fcntl(ciptr->fd,F_SETFD,FD_CLOEXEC); *status=0; return newciptr; }