/* The main DLL entry for DLL Initialization and Uninitialization: */ unsigned _System LibMain(unsigned hmod, unsigned termination) { if (termination) { #ifdef DEBUG_BUILD /* printf("[SDL DLL Unintialization] : Removing exception handler\n"); */ #endif DosUnsetExceptionHandler(&SDL_Main_xcpthand); return 1; } else { #ifdef DEBUG_BUILD /* Make stdout and stderr unbuffered! */ setbuf(stdout, NULL); setbuf(stderr, NULL); #endif /* Fire up exception handler */ #ifdef DEBUG_BUILD /* printf("[SDL DLL Initialization] : Setting exception handler\n"); */ #endif /* Set exception handler */ DosSetExceptionHandler(&SDL_Main_xcpthand); return 1; } }
PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg) { /* setup the exception handler for the thread */ APIRET rv; excpreg->ExceptionHandler = OS2_FloatExcpHandler; excpreg->prev_structure = NULL; rv = DosSetExceptionHandler(excpreg); PR_ASSERT(rv == NO_ERROR); }
int main(int argc,char*argv[]) { EXCEPTIONREGISTRATIONRECORD xcpt = { 0, &sighndlr }; /* make me immortile */ DosError(FERR_DISABLEEXCEPTION|FERR_DISABLEHARDERR); DosSetExceptionHandler(&xcpt); printf("My PID is %d, kill me!\n",getpid()); while(1) { sleep(0); } }
static void set_intr_run (void) { #if defined(_WIN32) SetConsoleCtrlHandler (stop_run, TRUE); #elif defined(__OS2__) APIRET rc; os2_excrr.ExceptionHandler = (ERR)stop_run; rc = DosSetExceptionHandler (&os2_excrr); /*if (rc != NO_ERROR)...*/ #elif defined(__DOS__) setsignal (SIGINT, stop_run); #else /*setsignal (SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/ setsignal (SIGINT, stop_run, 0); #endif }
void hb_vmSetExceptionHandler( void ) { #if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) && ! defined( __TINYC__ ) { LPTOP_LEVEL_EXCEPTION_FILTER ef = SetUnhandledExceptionFilter( hb_winExceptionHandler ); HB_SYMBOL_UNUSED( ef ); } #elif defined( HB_OS_OS2 ) /* Add OS2TermHandler to this thread's chain of exception handlers */ { APIRET rc; /* Return code */ memset( &s_regRec, 0, sizeof( s_regRec ) ); s_regRec.ExceptionHandler = ( ERR ) hb_os2ExceptionHandler; rc = DosSetExceptionHandler( &s_regRec ); if( rc != NO_ERROR ) hb_errInternal( HB_EI_ERRUNRECOV, "Could not setup exception handler (DosSetExceptionHandler())", NULL, NULL ); } #elif defined( HB_SIGNAL_EXCEPTION_HANDLER ) { stack_t ss; ss.ss_sp = ( void * ) s_signal_stack; ss.ss_size = SIGSTKSZ; ss.ss_flags = 0; /* set alternative stack for SIGSEGV executed on stack overflow */ if( sigaltstack( &ss, NULL ) == 0 ) { struct sigaction act; int i, sigs[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, 0 }; /* Ignore SIGPIPEs so they don't kill us. */ signal( SIGPIPE, SIG_IGN ); for( i = 0; sigs[ i ]; ++i ) { sigaction( sigs[ i ], 0, &act ); act.sa_sigaction = hb_signalExceptionHandler; act.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESETHAND; sigaction( sigs[ i ], &act, 0 ); } } } #endif }
static void worker_main(void *vpArg) { long conn_id; conn_rec *current_conn; apr_pool_t *pconn; apr_allocator_t *allocator; apr_bucket_alloc_t *bucket_alloc; worker_args_t *worker_args; HQUEUE workq; PID owner; int rc; REQUESTDATA rd; ULONG len; BYTE priority; int thread_slot = (int)vpArg; EXCEPTIONREGISTRATIONRECORD reg_rec = { NULL, thread_exception_handler }; ap_sb_handle_t *sbh; /* Trap exceptions in this thread so we don't take down the whole process */ DosSetExceptionHandler( ®_rec ); rc = DosOpenQueue(&owner, &workq, apr_psprintf(pchild, "/queues/httpd/work.%d", getpid())); if (rc) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, "unable to open work queue, exiting"); ap_scoreboard_image->servers[child_slot][thread_slot].tid = 0; } conn_id = ID_FROM_CHILD_THREAD(child_slot, thread_slot); ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_READY, NULL); apr_allocator_create(&allocator); apr_allocator_max_free_set(allocator, ap_max_mem_free); bucket_alloc = apr_bucket_alloc_create_ex(allocator); while (rc = DosReadQueue(workq, &rd, &len, (PPVOID)&worker_args, 0, DCWW_WAIT, &priority, NULLHANDLE), rc == 0 && rd.ulData != WORKTYPE_EXIT) { pconn = worker_args->pconn; ap_create_sb_handle(&sbh, pconn, child_slot, thread_slot); current_conn = ap_run_create_connection(pconn, ap_server_conf, worker_args->conn_sd, conn_id, sbh, bucket_alloc); if (current_conn) { ap_process_connection(current_conn, worker_args->conn_sd); ap_lingering_close(current_conn); } apr_pool_destroy(pconn); ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_READY, NULL); } ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_DEAD, NULL); apr_bucket_alloc_destroy(bucket_alloc); apr_allocator_destroy(allocator); }
ULONG FileGetJPEGInfo( CAMJpgInfo * pji, char * szFile, ULONG cbFile) { ULONG rc; ULONG ul; ULONG cbAlloc; BOOL fHandler = FALSE; CAMJXRR reg; do { memset( ®, 0, sizeof(CAMJXRR)); memset( pji, 0, sizeof(CAMJpgInfo)); rc = DosOpen( szFile, ®.hFile, &ul, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, 0); if (rc) { printf( "DosOpen - rc= 0x%x\n", (int)rc); break; } // allocate a lot of uncommited memory cbAlloc = ((cbFile + 0xfff) & ~0xfff); rc = DosAllocMem( (void**)(®.pBase), cbAlloc, PAG_READ | PAG_WRITE); if (rc) { printf( "DosAllocMem - rc= 0x%x\n", (int)rc); break; } // get up to the first 16k of the file - this is enough // for my Canon but not enough for a Sony I've tried ul = (cbFile >= 0x4000) ? 0x4000 : cbAlloc; rc = DosSetMem( reg.pBase, ul, PAG_COMMIT | PAG_DEFAULT); if (rc) { printf( "FileGetJPEGInfo - DosSetMem - rc= 0x%x\n", (int)rc); break; } ul = (cbFile >= 0x4000) ? 0x4000 : cbFile; ul = FileReadFile( reg.hFile, reg.pBase, ul, szFile); if (!ul) { rc = CAMERR_NEEDDATA; break; } // any access beyond 16k will generate an exception; // the handler will commit the page and read the corresponding // 4k from the file; if it encounters a file error, it will // longjmp() back to here so we can abort reg.lFilePtr += ul; reg.lEOF = cbFile; reg.pEnd = reg.pBase + cbAlloc; reg.szFile = szFile; reg.xrr.ExceptionHandler = FileExceptionHandler; // since the handler is lower on the stack than the jmpbuf, // longjmp() will unwind it before returning, so prevent // the cleanup code below from unsetting it if (setjmp( reg.jmpbuf)) { fHandler = FALSE; break; } rc = DosSetExceptionHandler( ®.xrr); if (rc) { printf( "DosSetExceptionHandler - rc= 0x%x\n", (int)rc); break; } fHandler = TRUE; // parse the file rc = FileIdentifyFile( pji, reg.pBase); if (rc) { printf( "FileIdentifyFile - rc= 0x%x\n", (int)rc); break; } // change the address of the thumb into an offset into the file if (pji->pThumb) pji->offsThumb = pji->pThumb - reg.pBase; } while (0); if (fHandler) { rc = DosUnsetExceptionHandler( ®.xrr); if (rc) printf( "DosUnsetExceptionHandler - rc= 0x%lx\n", rc); } if (reg.pBase) { rc = DosFreeMem( reg.pBase); if (rc) printf( "DosFreeMem - rc= 0x%x\n", (int)rc); } if (reg.hFile) { rc = DosClose( reg.hFile); if (rc) printf( "DosClose - rc= 0x%x\n", (int)rc); } return (0); }
/* Test each page. */ static bool TestPage(const char *pagelabel, uintptr_t pageaddr, int should_succeed) { const char *oplabel; uintptr_t opaddr; bool failed = false; for (unsigned int test = 0; test < 3; test++) { switch (test) { // The execute test must be done before the write test, because the // write test will clobber memory at the target address. case 0: oplabel = "reading"; opaddr = pageaddr + PAGESIZE/2 - 1; break; case 1: oplabel = "executing"; opaddr = pageaddr + PAGESIZE/2; break; case 2: oplabel = "writing"; opaddr = pageaddr + PAGESIZE/2 - 1; break; default: abort(); } #ifdef _WIN32 BOOL badptr; switch (test) { case 0: badptr = IsBadReadPtr((const void*)opaddr, 1); break; case 1: badptr = IsBadExecPtr(opaddr); break; case 2: badptr = IsBadWritePtr((void*)opaddr, 1); break; default: abort(); } if (badptr) { if (should_succeed) { printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel); failed = true; } else { printf("TEST-PASS | %s %s\n", oplabel, pagelabel); } } else { // if control reaches this point the probe succeeded if (should_succeed) { printf("TEST-PASS | %s %s\n", oplabel, pagelabel); } else { printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel); failed = true; } } #elif defined(__OS2__) XCPT xcpt; volatile int code = setjmp(xcpt.jmpbuf); if (!code) { xcpt.regrec.prev_structure = 0; xcpt.regrec.ExceptionHandler = ExceptionHandler; DosSetExceptionHandler(&xcpt.regrec); unsigned char scratch; switch (test) { case 0: scratch = *(volatile unsigned char *)opaddr; break; case 1: ((void (*)())opaddr)(); break; case 2: *(volatile unsigned char *)opaddr = 0; break; default: abort(); } } if (code) { if (should_succeed) { printf("TEST-UNEXPECTED-FAIL | %s %s | exception code %x\n", oplabel, pagelabel, code); failed = true; } else { printf("TEST-PASS | %s %s | exception code %x\n", oplabel, pagelabel, code); } } else { if (should_succeed) { printf("TEST-PASS | %s %s\n", oplabel, pagelabel); } else { printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel); failed = true; } DosUnsetExceptionHandler(&xcpt.regrec); } #else pid_t pid = fork(); if (pid == -1) { printf("ERROR | %s %s | fork=%s\n", oplabel, pagelabel, LastErrMsg()); exit(2); } else if (pid == 0) { volatile unsigned char scratch; switch (test) { case 0: scratch = *(volatile unsigned char *)opaddr; break; case 1: JumpTo(opaddr); break; case 2: *(volatile unsigned char *)opaddr = 0; break; default: abort(); } _exit(0); } else { int status; if (waitpid(pid, &status, 0) != pid) { printf("ERROR | %s %s | wait=%s\n", oplabel, pagelabel, LastErrMsg()); exit(2); } if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { if (should_succeed) { printf("TEST-PASS | %s %s\n", oplabel, pagelabel); } else { printf("TEST-UNEXPECTED-FAIL | %s %s | unexpected successful exit\n", oplabel, pagelabel); failed = true; } } else if (WIFEXITED(status)) { printf("ERROR | %s %s | unexpected exit code %d\n", oplabel, pagelabel, WEXITSTATUS(status)); exit(2); } else if (WIFSIGNALED(status)) { if (should_succeed) { printf("TEST-UNEXPECTED-FAIL | %s %s | unexpected signal %d\n", oplabel, pagelabel, WTERMSIG(status)); failed = true; } else { printf("TEST-PASS | %s %s | signal %d (as expected)\n", oplabel, pagelabel, WTERMSIG(status)); } } else { printf("ERROR | %s %s | unexpected exit status %d\n", oplabel, pagelabel, status); exit(2); } } #endif } return failed; }
/* draw_thread This is the drawing-thread. You have a valid presentation space handle (hps), a valid window handle (hwndSaver) and the configuration_data structure is loaded. The screen size is stored in "screenSizeX" and "screenSizeY". IMPORTANT NOTE 1: You must check the "stop_draw_thread" flag regularly. If it is set, free all resources you have allocated and call _endthread (or just return) to end the drawing-thread. IMPORTANT NOTE 2: If the "low_priority" flag is NOT set (that means you run with regular priority, sharing CPU usage with other programs), you should call DosSleep(x) with "x" set at least to 1 as often as possible, to allow other programs to do their work. A screen saver should not eat up other program's CPU time! IMPORTANT NOTE 3: For some of the PM calls to work properly, your thread needs an own HAB and maybe even a message queue. You have to get and release both of them here if you use such PM calls. The following sample code is from the "Pyramids" module that comes with the ScreenSaver distribution. It selects a random color and a random point on the screen, then draws lines in the selected color from each corner of the screen to the selected point (looks somewhat like a pyramid). It remembers a number of points (this number can be set in the configuration dialog). Having filled the point memory, it redraws the "oldest" visible pyramid in black. This has the effect that more and more pixels on the screen get black, only a few constantly changing colored lines remain. */ void draw_thread(void *args) { int i, j; const RECTL ScreenRect = { 0, 0, screenSizeX, screenSizeY }; int color_count = 0; ULONG color; int pushleftx = 11, pushlefty = 11, pushrightx = 11, pushrighty = 11; BOOL point_buffer_filled; BOOL first_paint = TRUE; POINTL *ptleft, *ptright; EXCEPTIONREGISTRATIONRECORD xcpthand = { (PEXCEPTIONREGISTRATIONRECORD)0, GPFHandler }; DosSetExceptionHandler(&xcpthand) ; i = 0; point_buffer_filled = FALSE; /* allocate memory for circular point buffer */ ptleft = malloc(configuration_data.count * sizeof(POINTL)); ptright = malloc(configuration_data.count * sizeof(POINTL)); if( (ptleft == NULL) || (ptright == NULL) ) goto end; GpiSetLineWidth( hps, LINEWIDTH_THICK ); srand(WinGetCurrentTime(hab)); do{ color = ((unsigned)rand()) % 17 - 2; }while ( color == -1 || color == 0 || color == 7 || color == 8 ); /* blank screen if requested */ if( configuration_data.blank_screen ) WinFillRect( hps, &ScreenRect, CLR_BLACK ); while(!stop_draw_thread){ if(point_buffer_filled){ /* redraw old line in black */ GpiSetColor(hps, CLR_BLACK); GpiMove(hps, &ptleft[i]); GpiLine(hps, &ptright[i]); } if( color_count == configuration_data.colors ){ /* select random color */ do{ color = ((unsigned)rand()) % 17 - 2; }while ( color == -1 || color == 0 || color == 7 || color == 8 ); color_count = 0; } GpiSetColor(hps, color); color_count++; if (first_paint ){ /* set the start coordinates */ ptleft[0].x = rand() % screenSizeX; ptleft[0].y = rand() % screenSizeY; ptright[0].x = rand() % screenSizeX; ptright[0].y = rand() % screenSizeY; first_paint = FALSE; } else { /* calculate new line points */ j = i==0 ? configuration_data.count - 1 : i - 1; ptleft[i].x = ptleft[j].x + pushleftx; ptleft[i].y = ptleft[j].y + pushlefty; ptright[i].x = ptright[j].x + pushrightx; ptright[i].y = ptright[j].y + pushrighty; } /* adjust lines if they hit a screen border */ if( ptleft[i].x >= screenSizeX ) { ptleft[i].x = 2 * screenSizeX - ptleft[i].x; pushleftx = - pushleftx + (rand() % 2); } if( ptleft[i].y >= screenSizeY ) { ptleft[i].y = 2 * screenSizeY - ptleft[i].y; pushlefty = - pushlefty + (rand() % 2); } if( ptright[i].x >= screenSizeX ) { ptright[i].x = 2 * screenSizeX - ptright[i].x; pushrightx = - pushrightx + ( rand() % 2); } if( ptright[i].y >= screenSizeY ) { ptright[i].y = 2 * screenSizeY - ptright[i].y; pushrighty = - pushrighty + ( rand() % 2); } if( ptleft[i].x < 0 ) { ptleft[i].x *= -1; pushleftx = - pushleftx + (rand() % 2); } if( ptleft[i].y < 0 ) { ptleft[i].y *= -1; pushlefty = - pushlefty + (rand() % 2); } if( ptright[i].x < 0 ) { ptright[i].x *= -1; pushrightx = - pushrightx + (rand() % 2); } if( ptright[i].y < 0 ) { ptright[i].y *= -1; pushrighty = - pushrighty + (rand() % 2); } /* draw line */ GpiMove(hps, &ptleft[i]); GpiLine(hps, &ptright[i]); /* sleep if necessary */ if(low_priority == FALSE) DosSleep(1); // sleep if user requests slower animation switch(configuration_data.animation_speed){ case 4: break; case 3: DosSleep(10); break; case 2: DosSleep(30); break; case 1: DosSleep(50); break; case 0: DosSleep(70); break; } i++; /* move circular buffer index */ if(i == configuration_data.count){ point_buffer_filled = TRUE; i = 0; } } /* free resources */ end: // goto from memory allocation free( ptleft ); free( ptright ); DosUnsetExceptionHandler(&xcpthand); _endthread(); }
int main(int argc, char *argv) { APIRET rc = NO_ERROR; PVOID pAlloc = NULL; PPQUEUE heap = NULL; int iRet = 0; EXCEPTIONREGISTRATIONRECORD xcpthand = { 0, &exception_handler }; int i = 0; srand(time(NULL)); /* * The whole idea with this sample is to demonstrate how to allocate memory * 'as needed'. The best way to do this is to use an exception handler */ rc = DosSetExceptionHandler(&xcpthand); /* * Allocate a very large buffer. This will fit approx 524280 nodes * which is way more than you'll need. */ rc = DosAllocMem(&pAlloc, 16*1024*1024, PAG_READ | PAG_WRITE); if(rc == NO_ERROR) { heap = pAlloc; } /* * Add some nodes with random priorities */ if(heap) { NODE tmpNode = { 0 }; PNODE node = NULL; puts("Add nodes"); for(i = 0; i < 100; i++) { tmpNode.priority = rand(); printf("Added node with priority: %u\n", tmpNode.priority); pqueue_push(heap, &tmpNode); } /* * Actually, it's neater to use the nodes-counter.. */ puts("\n\nEmpty heap"); while((node = pqueue_pop2(heap)) != NULL) { printf("Priority: %u\n", node->priority); } } /* * Free heap buffer */ if(heap) { DosFreeMem(heap); } /* * All registered exception handlers must be deregistered */ DosUnsetExceptionHandler(&xcpthand); return iRet; }
/* draw_thread This is the drawing-thread. You have a valid presentation space handle (hps), a valid window handle (hwndSaver) and the configuration_data structure is loaded. The screen size is stored in "screenSizeX" and "screenSizeY". IMPORTANT NOTE 1: You must check the "stop_draw_thread" flag regularly. If it is set, free all resources you have allocated and call _endthread (or just return) to end the drawing-thread. IMPORTANT NOTE 2: If the "low_priority" flag is NOT set (that means you run with regular priority, sharing CPU usage with other programs), you should call DosSleep(x) with "x" set at least to 1 as often as possible, to allow other programs to do their work. A screen saver should not eat up other program's CPU time! IMPORTANT NOTE 3: For some of the PM calls to work properly, your thread needs an own HAB and maybe even a message queue. You have to get and release both of them here if you use such PM calls. The following sample code is from the "Pyramids" module that comes with the ScreenSaver distribution. It selects a random color and a random point on the screen, then draws lines in the selected color from each corner of the screen to the selected point (looks somewhat like a pyramid). It remembers a number of points (this number can be set in the configuration dialog). Having filled the point memory, it redraws the "oldest" visible pyramid in black. This has the effect that more and more pixels on the screen get black, only a few constantly changing colored lines remain. */ void draw_thread(void *args) { INT i, j; typedef struct { INT x; INT y; float dx; float dy; INT step; } STAR; STAR *star; RECTL rect; BOOL point_buffer_filled; BOOL free_star_field = TRUE; float norm; EXCEPTIONREGISTRATIONRECORD xcpthand = { (PEXCEPTIONREGISTRATIONRECORD)0, GPFHandler }; DosSetExceptionHandler(&xcpthand) ; /* random seed (needed for each thread) */ srand(WinGetCurrentTime(hab)); i = 0; point_buffer_filled = FALSE; /* allocate stack memory for circular point buffer */ star = malloc(configuration_data.count * sizeof(STAR)); if( star == NULL ) stop_draw_thread = TRUE; /* blank Screen */ rect.xLeft = 0; rect.xRight = screenSizeX; rect.yBottom = 0; rect.yTop = screenSizeY; WinFillRect( hps, &rect, CLR_BLACK ); while(!stop_draw_thread){ if( free_star_field ){ /* create a new star */ star[i].x = rand() % screenSizeX/10 + screenSizeX * 9 / 20; star[i].y = rand() % screenSizeY / 10 + screenSizeY * 9 / 20; /* distance from screen center: */ star[i].dx = star[i].x - screenSizeX / 2; star[i].dy = star[i].y - screenSizeY / 2; /* it was created right in the middle: move it a little */ if( !star[i].dx && !star[i].dy) star[i].dx = 1; /* half the distance to the center: */ norm = sqrt( star[i].dx * star[i].dx + star[i].dy * star[i].dy ) / 2; if( norm < 1 ) norm = 1; /* Offsets normieren */ star[i].dx /= norm; star[i].dy /= norm; /* step counter for increasing star size: */ star[i].step = 1; rect.xLeft = star[i].x; rect.xRight = star[i].x + star[i].step / 22 + 1; rect.yBottom = star[i].y; rect.yTop = star[i].y + star[i].step / 22 + 1; WinFillRect( hps, &rect, CLR_WHITE ); } for( j = 0; j < (point_buffer_filled ? configuration_data.count : i + 1); j++){ /* move all stars */ rect.xLeft = star[j].x; rect.xRight = star[j].x + star[j].step / 22 + 1; rect.yBottom = star[j].y; rect.yTop = star[j].y + star[j].step / 22 + 1; WinFillRect( hps, &rect, CLR_BLACK ); star[j].step++; star[j].x += star[j].dx * star[j].step / 4; /* neu */ star[j].y += star[j].dy * star[j].step / 4; rect.xLeft = star[j].x; rect.xRight = star[j].x + star[j].step / 22 + 1; rect.yBottom = star[j].y; rect.yTop = star[j].y + star[j].step / 22 + 1; WinFillRect( hps, &rect, CLR_WHITE ); } i++; if( i==configuration_data.count ){ /* index wrap */ i = 0; point_buffer_filled = TRUE; free_star_field = FALSE; } if( point_buffer_filled ){ for( j = 0; j < configuration_data.count; j++){ /* check all stars whether they are still on screen */ if( star[j].x < - 10 || star[j].x > screenSizeX || star[j].y < -10 || star[j].y > screenSizeY ) { free_star_field = TRUE; i = j; break; } else { free_star_field = FALSE; } } } /* sleep if necessary */ if(low_priority == FALSE) DosSleep(1); /* sleep if user requests slower animation */ switch(configuration_data.animation_speed){ case 4: break; case 3: DosSleep(10); break; case 2: DosSleep(30); break; case 1: DosSleep(50); break; case 0: DosSleep(70); break; } } /* free resources */ free( star ); DosUnsetExceptionHandler(&xcpthand); _endthread(); }
int main( int argc, char **argv ) { APIRET rc; COMMAND cmd = {0,0}; int n; char *cp; char rc_string[12]; CONNECTION Connection; EXCEPTIONREGISTRATIONRECORD reg_rec; ESP_QUE_ELEMENT Qelement; if( argc == 1 ) SayMsg(HELP_INVOCATION_ESP); /****************************************************************************/ /* */ /* Parse the invocation options. */ /* */ /* - If this is a child debugger, then these additional parameters will */ /* precede the invocation parameters inherited from the parent. */ /* */ /* - /child=xxxxx where child = child debugger and */ /* xxxxx = child pid (for serial connections only.)*/ /* */ /* - /handle=xxxxx where handle = switch for com handle( serial only ) */ /* xxxxx = parent's com handle - inherited by */ /* the child. */ /* */ /****************************************************************************/ memset( &EspParms, 0, sizeof( ESP_PARMS ) ); memset( &Connection, 0, sizeof(Connection) ); if( strstr( argv[1], "/child" ) ) { ParseEspChildOptions( argc, argv, &EspParms, &Connection ); } else { ParseOptions( argc, argv, &EspParms, &Connection ); } printf("\nESP Version 5.00 \n");fflush(0); /****************************************************************************/ /* - Send connection info to the router. */ /****************************************************************************/ SendConnectionToRouter( &Connection ); /****************************************************************************/ /* - Make the connection. */ /****************************************************************************/ { int RcMoreInfo = 0; rc = ConnectInit( &RcMoreInfo ); if( rc != 0 ) { char BadConnectMsg[32] = ""; int MsgId; if( (Connection.ConnectType == _NETBIOS) && (RcMoreInfo != 0) ) { /*************************************************************************/ /* - handle netbios specific connect errors. */ /*************************************************************************/ n = 1; MsgId = ERR_NB_INADEQUATE_RESOURCES; switch( RcMoreInfo ) { case CANT_LOAD_NETB_DLL: n = 0; MsgId = ERR_NB_CANT_LOAD_DLL; break; case INADEQUATE_SESSIONS: strcpy( BadConnectMsg,"sessions"); break; case INADEQUATE_COMMANDS: strcpy( BadConnectMsg,"commands"); break; case INADEQUATE_NAMES: strcpy( BadConnectMsg,"names"); break; default: n = 1; MsgId = ERR_BAD_CONNECT; sprintf( BadConnectMsg, "NetBios error rc=%d", rc ); break; } } else if( (Connection.ConnectType == SOCKET) && (RcMoreInfo != 0) ) { /*************************************************************************/ /* - handle tcpip specific connect errors. */ /*************************************************************************/ switch( RcMoreInfo ) { case CANT_LOAD_TCPIP_DLL: n = 1; MsgId = ERR_TCPIP_CANT_LOAD_DLL; sprintf( BadConnectMsg, "%d", rc ); break; case TCPIP_NOT_RUNNING: n = 0; MsgId = ERR_TCPIP_NOT_RUNNING; break; case TCPIP_ERROR: n = 0; MsgId = ERR_TCPIP_ERROR; break; case TCPIP_NO_SERVICES_PORT: n = 0; MsgId = ERR_TCPIP_NO_SERVICES_PORT; break; default: n = 1; MsgId = ERR_BAD_CONNECT; sprintf( BadConnectMsg, "tcpip error rc=%d", rc ); break; } } else { /*************************************************************************/ /* - handle generic connect errors. */ /*************************************************************************/ n = 1; MsgId = ERR_BAD_CONNECT; sprintf( BadConnectMsg, "rc=%d", rc ); } ErrorPrintf( MsgId, n, BadConnectMsg ); } } /****************************************************************************/ /* - register an exception handler for the probe. */ /****************************************************************************/ reg_rec.ExceptionHandler = Handler; DosSetExceptionHandler(®_rec); /****************************************************************************/ /* - Add a connect sema4 for serial connections and wait to be posted. */ /****************************************************************************/ if( (SerialParallel() == SERIAL) && ( IsParent() == FALSE ) ) { USHORT EspPid; TIB *pTib; PIB *pPib; ALLPIDS *p; SetComHandle( EspParms.handle ); DosGetInfoBlocks(&pTib,&pPib); EspPid = (USHORT)pPib->pib_ulpid; CreateConnectSema4( EspPid, _ESP ); SerialConnect( JUST_WAIT, 0, _ESP, SendMsgToEspQue ); p = GetEspPid( EspPid ); p->Connect = CONNECTED; } /****************************************************************************/ /* - Each child debugger will have a termination que so we can kill the */ /* child debuggers on quit/restart. */ /****************************************************************************/ if( IsParent() == FALSE ) { rc = StartEspTermQue( ); if( rc != 0 ) { sprintf(rc_string, "%d",rc); ErrorPrintf( ERR_CANT_START_QUE, TRUE, 1, rc_string ); } } /****************************************************************************/ /* - Now, start the command processing loop. */ /****************************************************************************/ for(;;) { memset(&cmd,0,sizeof(cmd) ); RmtRecv(DEFAULT_HANDLE, (char*)&cmd, sizeof(cmd)); if( IsVerbose() ) PrintCmdMessage( cmd.api ) ; switch( cmd.api ) { case FINDEXE: RxFindExe(cmd); break; case STARTUSER: RxStartUser( cmd ); break; case GOINIT: RxGoInit(cmd); break; case GOENTRY: RxGoEntry(cmd); break; case DEFBRK: RxDefBrk(cmd); break; case UNDBRK: RxUndBrk(cmd); break; case PUTINBRK: RxPutInBrk(cmd); break; case PULLOUTBRK: RxPullOutBrk(cmd); break; case INSERTALLBRK: RxInsertAllBrk(); break; case REMOVEALLBRK: RxRemoveAllBrk(); break; case SELECT_SESSION: /*************************************************************************/ /* - Only the parent probe can select one of the debuggee sessions, so */ /* we send a message and tell him to do it. */ /*************************************************************************/ Qelement.ChildPid = GetEspProcessID(); SendMsgToEspQue( ESP_QMSG_SELECT_SESSION, &Qelement, sizeof(Qelement) ); memset(&cmd,0,sizeof(cmd) ); cmd.api = SELECT_SESSION; RmtSend( DEFAULT_HANDLE, &cmd, sizeof(cmd) ); break; case GOSTEP: RxGoStep(cmd); break; case GOFAST: RxGoFast(cmd); break; case DOSDEBUG: RxDosDebug( cmd ); break; case GETTHREADINFO: RxGetThreadInfo( cmd ); break; case FREEZETHREAD: RxFreezeThread( cmd ); break; case THAWTHREAD: RxThawThread( cmd ); break; case GETCALLSTACK: RxGetCallStack(cmd); break; case GETEXEORDLLENTRY: RxGetExeOrDllEntryOrExitPt(cmd); break; case NORMALQUIT: RxNormalQuit(cmd); /*************************************************************************/ /* - The que has to be up until after the normal quit because the */ /* system will need to post an end session message to the queue. */ /*************************************************************************/ if( IsParent() ) { if( SingleMultiple() == MULTIPLE ) { ALLPIDS *p; /***********************************************************************/ /* - Send a message to all of the child probes telling them that */ /* they are going to be killed. */ /***********************************************************************/ for( p = GetAllpids(); p ; p = p->next ) { if( (p->PidFlags.IsDebug) == TRUE && (p->pid != GetEspProcessID()) ) { ESP_QUE_ELEMENT Qelement; Qelement.ChildPid = p->EspPid; SendMsgToEspTermQue(ESP_PROBE_TERM, &Qelement, sizeof(Qelement) ); } } /***********************************************************************/ /* - send a message to the que to kill all the child probes and */ /* then wait until they are all dead. */ /***********************************************************************/ ResetAllProbesAreDeadFlag( ); SendMsgToEspQue(ESP_QMSG_PARENT_TERM,NULL,0); while( AllProbesAreDead() == FALSE ){ DosSleep(100) ;} } SendMsgToEspQue(ESP_QMSG_QUE_TERM,NULL,0); } CloseConnectSema4(); cmd.api = NORMALQUIT; cmd.len = sizeof(rc); /*************************************************************************/ /* - Now, tell dbg that we're finished normal quitting. */ /*************************************************************************/ RmtSend(DEFAULT_HANDLE, &cmd , sizeof(cmd) ); RmtSend(DEFAULT_HANDLE, &rc, cmd.len ); break; case SETEXECADDR: RxSetExecAddr(cmd); break; case DEFWPS: RxDefWps(cmd); break; case PUTINWPS: RxPutInWps(cmd); break; case PULLOUTWPS: RxPullOutWps(cmd); break; case GETDATABYTES: RxGetDataBytes(cmd); break; case GETMEMBLKS: RxGetMemBlocks(cmd); break; case SETXCPTNOTIFY: RxSetExceptions(cmd); break; case SETEXECTHREAD: RxSetExecThread(cmd); break; case WRITEREGS: RxWriteRegs(cmd); break; case GETCOREGS: RxGetCoRegs(cmd); break; case SETESPRUNOPTS: RxSetEspRunOpts(cmd); break; case TERMINATEESP: if( IsParent() == FALSE ) { memset( &Qelement, 0, sizeof(Qelement) ); Qelement.ChildPid = GetEspProcessID(); SendMsgToEspQue( ESP_QMSG_CHILD_TERM, &Qelement, sizeof(Qelement) ); } DosUnsetExceptionHandler(®_rec); RmtSend(DEFAULT_HANDLE, &cmd , sizeof(cmd) ); ConnectClose( DEFAULT_HANDLE ); exit(0); break; case START_QUE_LISTEN: SendMsgToEspQue(ESP_QMSG_OPEN_CONNECT,NULL,0); break; case START_ESP_QUE: RxStartEspQue(cmd); break; case CONNECT_ESP: /*************************************************************************/ /* - Serial connection only. */ /*************************************************************************/ { USHORT GoToPid; USHORT YieldPid; ALLPIDS *pYield; ALLPIDS *pGoTo; BOOL TorF; /************************************************************************/ /* - Receive the pid to be connected and mark it connected. */ /* - If this pid has not yet been assigned to a probe, then pGoTo */ /* will be NULL. */ /* - There MUST be a probe with a pid==0, so we release that probe. */ /* ( The pid will be stuffed into the structure at goinit() time.) */ /* - Post the connect sema4 for the goto pid. */ /************************************************************************/ RmtRecv( DEFAULT_HANDLE, &GoToPid, cmd.len ); pGoTo = GetPid( GoToPid ); if( pGoTo == NULL ) pGoTo = GetPid(0); pGoTo->Connect = CONNECTED; TorF = TRUE; if( GoToPid == GetEspProcessID() ) TorF = FALSE; /************************************************************************/ /* - Send back verification that the connection has been made. */ /************************************************************************/ memset(&cmd,0,sizeof(cmd) ); cmd.api = SERIAL_POLL; RmtSend( DEFAULT_HANDLE, &cmd, sizeof(cmd) ); PostConnectSema4( &pGoTo->ConnectSema4, TorF ); /************************************************************************/ /* - Disconnect/block this probe. */ /************************************************************************/ YieldPid = (USHORT)GetEspProcessID(); pYield = GetPid( YieldPid ); pYield->Connect = DISCONNECTED; SerialConnect( SET_WAIT, YieldPid, _ESP, SendMsgToEspQue ); } break; case CTRL_BREAK: { USHORT ThisPid; USHORT CtrlBreakPid; RmtRecv( DEFAULT_HANDLE, &CtrlBreakPid, cmd.len ); ThisPid = (USHORT)GetEspProcessID(); Qelement.ChildPid = CtrlBreakPid; Qelement.ChildSid = ThisPid; SendMsgToEspQue(ESP_QMSG_CTRL_BREAK, &Qelement, sizeof(Qelement)); SerialConnect( SET_WAIT, ThisPid, _ESP, SendMsgToEspQue ); } break; case SERIAL_POLL: ReportMessage(); break; default: cp = (char*)&cmd; for( n=1; n<=sizeof(cmd); n++,cp++) printf("%c",*cp); AsyncFlushModem(); break; } } }
void _cdecl main (SHORT argc, char *argv[]) { // bool ok = FALSE; // char test[5]; // test for trap 05 errors ULONG ulTimes; // need for Trap Ctrl-Break Signal #ifdef TESTING if(!dout) { DosBeep(500,300); } if(!memout) { DosBeep(1000,300); } #endif #ifdef ERR_HAND rc = set_int24(); if(rc != 0) { err_exit("Error initializing error handler", 3); } MYEXCEPTIONREGISTRATIONRECORD myExceptionRegRecord; myExceptionRegRecord.prev_structure = NULL; myExceptionRegRecord.ExceptionHandler = MyExceptionHandler; DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD) &myExceptionRegRecord); DosSetSignalExceptionFocus(SIG_SETFOCUS, &ulTimes); if(setjmp(myExceptionRegRecord.env)) goto OnException; #endif DBG_INI(dout<<"file "<<__FILE__<<" line "<<__LINE__<<" settings.numlock_on = "<<settings.numlock_on<<endl); filesys_init(); get_current_directory(cwd); // init cur dir Mem::vmem_setup(); strcpy(exe_dir, *argv); // assume loaded via X:\subdir\KED.EXE DBG_FILE(dout << "EXE_DIR = " << exe_dir <<endl); DBG_MEM(memout<< " main after except setup "<< checkmem2 << endl); assure_windows_ready(); if(!thread_init()) { err_exit("Error creating initial threads", 5); } process_env_string ("EDITOR"); /* do parameters from environment string */ strcpy (progname,*argv); argc--; /* don't count program name */ argv++; while (argc--) { /* process each parameter */ process_arg (*argv); argv++; } if (!*settings.help_path) { /* help is usually in same dir as program */ delta_filename (settings.help_path, progname, "*.HLP"); } //#ifdef TESTING //if(!debug_on) { // dout.close(); // memout.close(); //} //#endif assure_1_view(); DBG_INI(dout<<"edit.cpp line "<<__LINE__<<" shell_command.s = °"<<settings.shell_command.s<<"°"<<endl); DBG_INI(dout<<"file "<<__FILE__<<" line "<<__LINE__<<" settings.numlock_on = "<<settings.numlock_on<<endl); // ok = load_keys(); // Version 2.08 // if(!ok) // err_exit("Failed to load Keyboard driver", 10); edit_loop(); // test[5000] = 'A'; // test trap array bounds goto Ked_Exit; OnException: #ifdef ERR_HAND DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD) &myExceptionRegRecord); // Screen.term_mess = "application trapped"; err_exit(" application trapped", 20); #endif Ked_Exit: #ifdef ERR_HAND if(ORG_NUMLOCK) { DBG_NUML(dout<<" exit - setting NUMLOCK on"<<endl); numlock_set(TRUE); } else { DBG_NUML(dout<<" exit - setting NUMLOCK off"<<endl); numlock_set(FALSE); } DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD) &myExceptionRegRecord); #endif DBG_MEM(memout<< " main after except setup "<< checkmem2 << endl); DBG_BUGS(dout<<'\n'<<" Normal Closedown in LOGFILE "<<endl); }