void pvnquit( void ){ u32 i; if( pvnqs ){ u32* qs = (u32*)vmem( pvnqs ); for( i = 0; i < pvnnqs; ++i ){ if( qs[ i ] ) verase( qs[ i ] ); } } if( pvnscks != NULL ){ for( i = 0; i < pvnscksSize; ++i ) closesocket( pvnscks[ i ] ); vsfree( pvnscks ); pvnscks = NULL; } if( pvncons != NULL ){ for( i = 0; i < pvnconsSize; ++i ) closesocket( pvncons[ i ] ); vsfree( pvncons ); pvncons = NULL; } if( pvncbs != NULL ){ vsfree( pvncbs ); pvncbs = NULL; } if( pvnccbs != NULL ){ vsfree( pvnccbs ); pvnccbs = NULL; } if( pvnfids != NULL ){ vsfree( pvnfids ); pvnfids = NULL; } if( pvncids != NULL ){ vsfree( pvncids ); pvncids = NULL; } if( pvntimes != NULL ){ vsfree( pvntimes ); pvntimes = NULL; } pvnfrees = 0; pvnscksSize = pvnconsSize = 0; pvnscksBSize = pvnconsBSize = 1; WSACleanup(); }
void pvnremcon( u32 ind ){ u32 i = ind; u32* qs = (u32*)vmem( pvnqs ); u32 tq = qs[ ind ]; pvnccbs[ ind ]( NULL, 0, pvncids[ i ], vcurTime() ); closesocket( pvncons[ ind ] ); --pvnconsSize; verase( qs[ i ] ); pvnfids[ pvnfrees++ ] = pvncids[ i ]; while( i < pvnconsSize ){ pvncons[ i ] = pvncons[ i + 1 ]; pvnccbs[ i ] = pvnccbs[ i + 1 ]; pvncids[ i ] = pvncids[ i + 1 ]; qs[ i ] = qs[ i + 1 ]; ++i; } qs[ pvnconsSize ] = tq; }
void pvnaddcon( const SOCKET* cs, vncallback vcb ){ if( pvnconsSize >= pvnconsBSize ){ u32 i; SOCKET* ts = vsmalloc( sizeof( SOCKET ) * pvnconsBSize * 2 ); vncallback** tcbs = vsmalloc( sizeof( vncallback* ) * pvnconsBSize * 2 ); u32* tids = vsmalloc( sizeof( u32 ) * pvnconsBSize * 2 ); u32* fids = vsmalloc( sizeof( u32 ) * pvnconsBSize * 2 ); f32* times = vsmalloc( sizeof( f32 ) * pvnconsBSize * 2 ); pvnconsBSize *= 2; for( i = 0; i < pvnconsSize; ++i ){ ts[ i ] = pvncons[ i ]; tcbs[ i ] = pvnccbs[ i ]; tids[ i ] = pvncids[ i ]; fids[ i ] = pvnfids[ i ]; times[ i ] = pvntimes[ i ]; } vsfree( pvncons ); pvncons = ts; vsfree( pvnccbs ); pvnccbs = tcbs; vsfree( pvncids ); pvncids = tids; vsfree( pvnfids ); pvnfids = fids; vsfree( pvntimes ); pvntimes = times; } while( pvnnqs < pvnconsBSize ){ u32 nq = vmalloc( 0 ); vappend( pvnqs, &nq, sizeof( u32 ) ); ++pvnnqs; } pvnccbs[ pvnconsSize ] = vcb; verase( ( (u32*)vmem( pvnqs ) )[ pvnconsSize ] ); if( pvnfrees ) pvncids[ pvnconsSize ] = pvnfids[ --pvnfrees ]; else pvncids[ pvnconsSize ] = pvnconsSize; pvncons[ pvnconsSize ] = *cs; pvntimes[ pvnconsSize ] = vcurTime(); ++pvnconsSize; if( !vcb( NULL, 1, pvncids[ pvnconsSize - 1 ], vcurTime() ) ) pvnremcon( pvnconsSize - 1 ); }
void vntick(){ if( pvnscks != NULL ){ static fd_set rds, wts; u32 i, mfd = 0; struct timeval tv = { 0, 0 }; f32 curt = vcurTime(); mfd = 0; for( i = 0; i < pvnconsSize; ++i ){ if( curt - pvntimes[ i ] > vn_timeout ) pvnremcon( i ); } FD_ZERO( &rds ); for( i = 0; i < pvnscksSize; ++i ){ if( pvnscks[ i ] > mfd ) mfd = pvnscks[ i ]; #pragma warning( push ) #pragma warning( disable: 4127 ) FD_SET( pvnscks[ i ], &rds ); #pragma warning( pop ) } if( mfd ){ pvncheck( "select failed!", select( mfd + 1, &rds, NULL, NULL, &tv ), NULL, NULL ); for( i = 0; i < pvnscksSize; ++i ){ if( FD_ISSET( pvnscks[ i ], &rds ) ){ SOCKET as = accept( pvnscks[ i ], NULL, NULL ); pvncheck( "accept failed", as, NULL, NULL ); pvnaddcon( &as, pvncbs[ i ] ); } } } FD_ZERO( &rds ); FD_ZERO( &wts ); mfd = 0; for( i = 0; i < pvnconsSize; ++i ){ if( pvncons[ i ] > mfd ) mfd = pvncons[ i ]; #pragma warning( push ) #pragma warning( disable: 4127 ) FD_SET( pvncons[ i ], &rds ); FD_SET( pvncons[ i ], &wts ); #pragma warning( pop ) } if( mfd ){ pvncheck( "select failed!", select( mfd + 1, &rds, NULL, NULL, &tv ), NULL, NULL ); for( i = 0; i < pvnconsSize; ++i ){ u32 qn = ( (u32*)vmem( pvnqs ) )[ i ]; if( FD_ISSET( pvncons[ i ], &rds ) ){ static u8 buf[ vnbufsize ]; int ans = recv( pvncons[ i ], buf, vnbufsize - 1, 0 ); pvncheck( "recv failed!", ans, NULL, NULL ); if( ans == SOCKET_ERROR ) ans = 0; if( !ans ){ pvnremcon( i ); } else{ ans = pvnccbs[ i ]( buf, ans, pvncids[ i ], vcurTime() ); if( !ans ) pvnremcon( i ); else if( vsize( ans ) ){ vappend( qn, vmem( ans ), vsize( ans ) ); } } } if( FD_ISSET( pvncons[ i ], &wts ) && vsize( qn ) ){ int ans = send( pvncons[ i ], vmem( qn ), vsize( qn ), 0 ); pvncheck( "send failed!", ans, NULL, NULL ); if( ans == SOCKET_ERROR ) ans = 0; if( (u32)ans != vsize( qn ) ){ u32 ns = vsize( qn ) - (u32)ans; u8* tb = vsmalloc( ns ); vmemcpy( tb, ((u8*)vmem( qn )) + ans, ns ); verase( qn ); vappend( qn, tb, ns ); vsfree( tb ); }else verase( qn ); } } } } }
void vkill () { while (pw.size ()) verase (); }
void kbdinput::readcb () { struct _isigs { int ch; int sig; }; static const _isigs isig[] = { { VINTR, SIGINT }, { VQUIT, SIGQUIT }, { VSUSP, SIGTSTP }, #ifdef VDSUSP { VDSUSP, SIGTSTP }, #endif /* VDSUSP */ { -1, -1 } }; u_char c; size_t n = read (kbdfd, &c, 1); if (n <= 0) { setorig (); if (n == 0) fatal ("keyboard: EOF (with ICANON clear)\n"); else fatal ("keyboard: %m\n"); } dst->update (&c, 1); getclocknoise (dst); if (!lnext && c != _POSIX_VDISABLE) { #ifdef VLNEXT if (c == torig.c_cc[VLNEXT]) { lnext = true; return; } #endif /* VLNEXT */ for (int i = 0; isig[i].sig > 0; i++) if (c == torig.c_cc[isig[i].ch]) { setorig (); tcflush (kbdfd, TCIFLUSH); kill (0, isig[i].sig); gotsig = true; setraw (); getclocknoise (dst); vreprint (); gotsig = false; return; } if (iserase (c)) verase (); else if (iskill (c)) vkill (); else if (isreprint (c)) vreprint (); else goto normal; return; } normal: bool olnext = lnext; lnext = false; gotch (c, olnext); c = 0; }