/*@ XNamedPipeServer::DisConnect(void) @group open/close @remarks Frees a pipe when a client has stoped data-transfer ( if GetState() returns XNPIPE_STATE_CLOSING). After DisConnect() you can call Connect() to wait for the next client or Close(). */ LONG XNamedPipeServer::DisConnect(void) { ULONG res = 0; if (isOpen) res = DosDisConnectNPipe(handle); return res; }
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 ); } } }
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); }
void /*_Optlink*/ Fs_ClientWork(void *param) { int i,rc, threadNum,id,idd; int ncmd,data; // char PipeName[256]; char str[512]; char buf[MAX_PIPE_BUF], bufout[MAX_PIPE_BUF]; _control87(EM_UNDERFLOW,EM_UNDERFLOW); int bla = 0; while(__lxchg(&LSthreads.semaphore, LOCKED)) DosSleep(1); //int volatile * a, int b) { /*printf("FIXME: builtin.h:%s (%d, %d)\n", __func__, *a, b);*/ //DosEnterCritSec(); /* int ret = 1; while(ret) { ret = 1; if(LSthreads.semaphore == 0 && LOCKED == 1) { LSthreads.semaphore = LOCKED; ret = 0; } if(LSthreads.semaphore == 1 && LOCKED == 0) { ret = 1; } for(double di=0; di>100; di++) di++; } */ //DosExitCritSec(); //return ret; threadNum = LSthreads.next_free; LSthreads.state[threadNum] = -1; if(LSthreads.n < threadNum) LSthreads.n = threadNum; debug(0, 2) ("Fs_ClientWork%i: Pipe creating (%i)\n",threadNum,LSthreads.thread_id[threadNum]); // 2 fflush(stdout); ThreadStart++; DosSleep(1); __lxchg(&LSthreads.semaphore, UNLOCKED); do { DosSleep(1); } while(ThreadStart != 3); // if(param) // threadNum = * ((int *)param); DosSleep(1); FreePM_pipe[threadNum] = new NPipe(FREEPM_BASE_PIPE_NAME,SERVER_MODE,FREEPMS_MAX_NUM_THREADS,threadNum); rc = FreePM_pipe[threadNum]->Create(); if(rc == ERROR_TOO_MANY_OPEN_FILES) { rc = OS2SetRelMaxFH(8); rc = FreePM_pipe[threadNum]->Create(); } if(rc) { snprintf(str,256, "Error pipe creating %s rc=%i",FreePM_pipe[threadNum]->name,rc); if(rc == ERROR_INVALID_PARAMETER) strcat(str,"(INVALID PARAMETER)"); else if (rc == ERROR_PIPE_BUSY) strcat(str,"(PIPE_BUSY)"); if (rc == ERROR_PIPE_BUSY) { debug(0, 0) ("WARNING: Fs_ClientWork: %s\n",str); goto ENDTHREAD; } _fatal_common(str); } LSthreads.state[threadNum] = 0; debug(0, 2) ("Fs_ClientWork%i: Pipe create %s %x %x\n",threadNum,FreePM_pipe[threadNum]->name, threadNum ,FreePM_pipe[threadNum]->Hpipe); M_CONNECT: rc = FreePM_pipe[threadNum]->Connect(); if(rc) { debug(0, 0) ("WARNING: Error connecting pipe %s: %s\n",FreePM_pipe[threadNum]->name,xstdio_strerror()); goto ENDTHREAD; } debug(0, 2) ("Fs_ClientWork%i: Connecting pipe: %s Ok\n",threadNum,FreePM_pipe[threadNum]->name); LSthreads.state[threadNum] = 1; rc = FreePM_pipe[threadNum]->HandShake(); if(rc) { debug(0, 0) ("WARNING: Error HandShake pipe %s: %s\n",FreePM_pipe[threadNum]->name,xstdio_strerror()); rc = DosDisConnectNPipe(FreePM_pipe[threadNum]->Hpipe); goto M_CONNECT; } debug(0, 2) ("Fs_ClientWork%i: HandShake pipe: %s Ok\n",threadNum,FreePM_pipe[threadNum]->name); /***********/ for(i = 0; i < FREEPMS_MAX_NUM_THREADS; i++) { // debug(0, 0) ("(%i %i)",i,LSthreads.thread_id[i]); if(LSthreads.thread_id[i] == -1) { break; } } idd = LSthreads.next_free; // debug(0, 0) ("idd=%i",idd); ThreadStart = 1; LSthreads.state[threadNum] = 2; id = _beginthread(Fs_ClientWork,NULL, THREAD_STACK_SIZE,&idd); do { DosSleep(1); } while(ThreadStart == 1); while(__lxchg(&LSthreads.semaphore, LOCKED)) DosSleep(1); LSthreads.Nclients++; // число живых клиентов LSthreads.working = 1; // =0 на старте, =1 после появления первого живого клиента (защелка) LSthreads.num++; LSthreads.thread_id[LSthreads.next_free] = id; for(i = 0; i < FREEPMS_MAX_NUM_THREADS; i++) { // l = (i + LSthreads.next_free)%MAX_NUM_THREADS; // debug(0, 0) ("[%i %i]",i,LSthreads.thread_id[i]); if(LSthreads.thread_id[i] == -1) { LSthreads.next_free = i; break; } } ThreadStart = 3; __lxchg(&LSthreads.semaphore, UNLOCKED); DosSleep(1); debug(0, 2)("Fs_ClientWork%i: Pipe working %s\n", threadNum, FreePM_pipe[threadNum]->name); /*****************/ do { LSthreads.state[threadNum] = 3; rc = _F_RecvCmdFromClient((void *)FreePM_pipe[threadNum], &ncmd,&data); if(rc) { if(rc == -1) { rc = FreePM_pipe[threadNum]->QueryState(); if(rc == ERROR_BAD_PIPE || rc == ERROR_PIPE_NOT_CONNECTED) break; // клиент подох ?? } debug(0, 9)("WARNING: Fs_ClientWork: RecvCmdFromClient error %x %s\n", rc, xstdio_strerror()); goto ENDTHREAD; } LSthreads.state[threadNum] = 1; LSthreads.state[threadNum] = 4; debug(0, 9)("Fs_ClientWork: Get ncmd %x %x\n",ncmd, data); // handle the command handler((void *)FreePM_pipe[threadNum], ncmd, data, threadNum); } while(ncmd); /*****************/ ENDTHREAD: LSthreads.state[threadNum]= 5; debug(0, 2) ("Fs_ClientWork%i: Pipe Closing %s %x %x\n",threadNum,FreePM_pipe[threadNum]->name, threadNum ,FreePM_pipe[threadNum]->Hpipe); // DosSleep(3000); // rc = DosDisConnectNPipe(FreePM_pipe[threadNum].Hpipe); // rc += DosClose(FreePM_pipe[threadNum].Hpipe); rc = FreePM_pipe[threadNum]->Close(); debug(0, 2) ("Fs_ClientWork%i: Pipe Close %s, Thread %i, ThId=%i, rc=%x\n", threadNum,FreePM_pipe[threadNum]->name, LSthreads.thread_id[threadNum],rc); fflush(stdout); //todo: call timeout_handler to kill windows with closed habs while(__lxchg(&LSthreads.semaphore, LOCKED)) DosSleep(1); // sgLogError("End thread %i\n",threadNum); LSthreads.num--; LSthreads.thread_id[threadNum] = -1; LSthreads.state[threadNum] = -1; if(LSthreads.thread_id[LSthreads.next_free] != -1 || LSthreads.next_free > threadNum) LSthreads.next_free = threadNum; if(LSthreads.n < threadNum) LSthreads.n = threadNum; for(i=0; i < FREEPMS_MAX_NUM_THREADS; i++) { // l = (i + LSthreads.next_free)%MAX_NUM_THREADS; // debug(0, 0) ("[%i %i]",i,LSthreads.thread_id[i]); if(LSthreads.thread_id[i] == -1) { LSthreads.next_free = i; break; } } LSthreads.Nclients--; // число живых клиентов __lxchg(&LSthreads.semaphore, UNLOCKED); DosSleep(1); }
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; } } }
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; }