void TclSetSignalHandler(Tcl_Interp* interp,char* function) { asynchandler=Tcl_AsyncCreate(TclSignalHandler,(ClientData)NULL); #ifdef SIGINT signal(SIGINT,signal_handler); #else signal(SIGBREAK,signal_handler); #endif }
void EnableSyncpoints (void) { #ifdef TCL_THREADS CreateManagerThread(); #else Tcl_AsyncCreate(activator); #endif signalingEnabled = 1; }
int VMDinitialize(int *argc, char ***argv) { int i; #if defined VMDMPI // hack to fix up env vars if necessary for (i=0; i<(*argc); i++) { if(!strupcmp((*argv)[i], "-vmddir")) { if((*argc) > (i + 1)) { setenv("VMDDIR", (*argv)[++i], 1); } else { msgErr << "-vmddir must specify a fully qualified path." << sendmsg; } } } vmd_mpi_init(argc, argv); // initialize MPI, fix up env vars, etc. #endif #if defined(_MSC_VER) && !defined(VMDSEPARATESTARTUP) win32vmdstart(); // get registry info etc #endif #if !defined(VMDNOMACBUNDLE) && defined(__APPLE__) macosxvmdstart(*argc, *argv); // get env variables etc #endif // Tell Tcl where the executable is located const char *argv0 = vmd_initialize_tcl((*argv)[0]); #ifdef VMDTCL // register signal handler tclhandler = Tcl_AsyncCreate(VMDTclAsyncProc, (ClientData)NULL); signal(SIGINT, (sighandler_t) VMDTclSigHandler); #endif // Let people know who we are. VMDtitle(); // Tell the user what we think about the hardware we're running on. // If VMD is compiled for MPI, then we don't print any of the normal // standalone startup messages and instead we use the special MPI-specific // node scan startup messages only. #if !defined(VMDMPI) #if defined(VMDTHREADS) int vmdnumcpus = wkf_thread_numprocessors(); msgInfo << "Multithreading available, " << vmdnumcpus << ((vmdnumcpus > 1) ? " CPUs" : " CPU") << " detected." << sendmsg; #endif long vmdcorefree = vmd_get_avail_physmem_mb(); if (vmdcorefree >= 0) { long vmdcorepcnt = vmd_get_avail_physmem_percent(); msgInfo << "Free system memory: " << vmdcorefree << "MB (" << vmdcorepcnt << "%)" << sendmsg; } #endif // Read environment variables and command line options. // Initialize customArgv with just argv0 to avoid problems with // Tcl extension. customArgv.append((char *)argv0); VMDGetOptions(*argc, *argv); #if (!defined(__APPLE__) && !defined(_MSC_VER)) && (defined(VMDOPENGL) || defined(VMDFLTK)) // If we're using X-windows, we autodetect if the DISPLAY environment // variable is unset, and automatically switch back to text mode without // requiring the user to pass the "-dispdev text" command line parameters if ((which_display == DISPLAY_WIN) && (getenv("DISPLAY") == NULL)) { which_display = DISPLAY_TEXT; } #endif #if defined(VMDTKCON) vmdcon_init(); msgInfo << "Using VMD Console redirection interface." << sendmsg; // we default to a widget mode console, unless text mode is requested. // we don't have an tcl interpreter registered yet, so it is set to NULL. // flushing pending messages to the screen, is only in text mode possible. if ((which_display == DISPLAY_TEXT) || just_print_help) { vmdcon_use_text(NULL); vmdcon_purge(); } else { vmdcon_use_widget(NULL); } #endif #ifdef VMDFLTK // Do various special FLTK initialization stuff here if ((which_display != DISPLAY_TEXT)) { // Cause FLTK to to use 24-bit color for all windows if possible // This must be done before any FLTK windows are shown for the first time. if (!Fl::visual(FL_DOUBLE | FL_RGB8)) { if (!Fl::visual(FL_RGB8)) { Fl::visual(FL_RGB); } } // Disable the use of the arrow keys for navigating buttons and other // non-text widgets, we'll try it out and see how it pans out Fl::visible_focus(0); // Disable Drag 'n Drop since the only text field in VMD is the // atomselection input and DND severely gets in the way there. Fl::dnd_text_ops(0); } #endif // Quit now if the user just wanted a list of command line options. if (just_print_help) { vmd_sleep(10); // This is here so that the user can see the message // before the terminal/shell exits... return 0; } // Set up default allocators; these may be overridden by cave or freevr. vmd_alloc = malloc; // system malloc() in the default case vmd_dealloc = free; // system free() in the default case vmd_realloc = realloc; // system realloc(), set to NULL when not available // check for a CAVE display if (DISPLAY_USES_CAVE(which_display)) { #ifdef VMDCAVE // allocate shared memory pool used to communicate with child renderers int megs = 2048; if (getenv("VMDCAVEMEM") != NULL) { megs = atoi(getenv("VMDCAVEMEM")); } msgInfo << "Attempting to get " << megs << "MB of CAVE Shared Memory" << sendmsg; grab_CAVE_memory(megs); CAVEConfigure(argc, *argv, NULL); // configure cave walls and memory use // point VMD shared memory allocators to CAVE routines vmd_alloc = malloc_from_CAVE_memory; vmd_dealloc = free_to_CAVE_memory; vmd_realloc = NULL; // no realloc() functionality is available presently #else msgErr << "Not compiled with the CAVE options set." << sendmsg; which_display = DISPLAY_WIN; #endif } // check for a FreeVR display if (DISPLAY_USES_FREEVR(which_display)) { #ifdef VMDFREEVR int megs = 2048; if (getenv("VMDFREEVRMEM") != NULL) { megs = atoi(getenv("VMDFREEVRMEM")); } msgInfo << "Attempting to get " << megs << "MB of FreeVR Shared Memory" << sendmsg; grab_FreeVR_memory(megs); // have to do this *before* vrConfigure() if // we want more than the default shared mem. vrConfigure(NULL, NULL, NULL); // configure FreeVR walls // point shared memory allocators to FreeVR routines vmd_alloc = malloc_from_FreeVR_memory; vmd_dealloc = free_to_FreeVR_memory; vmd_realloc = NULL; // no realloc() functionality is available presently #else msgErr << "Not compiled with the FREEVR options set." << sendmsg; which_display = DISPLAY_WIN; #endif } // return custom argc/argv *argc = customArgv.num(); for (i=0; i<customArgv.num(); i++) { (*argv)[i] = customArgv[i]; } return 1; // successful startup }
static int elTclSignal(ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { ElTclInterpInfo *iinfo = data; ElTclSignalContext *ctx; sigset_t set, oset; int i, signum; char *action; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "signal ?script|-ignore|-default|-block|-unblock?"); return TCL_ERROR; } if (objc == 2 && !strcmp(Tcl_GetStringFromObj(objv[1], NULL), "names")) { /* [signal names] */ Tcl_DString dstring; Tcl_DStringInit(&dstring); for(i=0; i<ELTCL_MAXSIG; i++) if (signalNames[i] != NULL) { Tcl_DStringAppendElement(&dstring, signalNames[i]); } Tcl_DStringResult(interp, &dstring); return TCL_OK; } /* objv[1] must be a signal name */ signum = -1; for(i=0; i<ELTCL_MAXSIG; i++) if (signalNames[i] != NULL) if (!strcmp(Tcl_GetStringFromObj(objv[1], NULL), signalNames[i])) { signum = i; break; } if (signum < 0) { /* or an integer */ if (Tcl_GetIntFromObj(interp, objv[1], &signum) == TCL_ERROR) return TCL_ERROR; } /* prepare the interpreter result so that this command returns the * previous action for that signal */ ctx = getSignalContext(signum, iinfo); if (ctx == NULL || ctx->script == ELTCL_SIGDFL) { Tcl_SetResult(interp, "-default", TCL_STATIC); } else if (ctx->script == ELTCL_SIGIGN) { Tcl_SetResult(interp, "-ignore", TCL_STATIC); } else { Tcl_SetObjResult(interp, ctx->script); } /* if no action given, return current script associated with * signal */ if (objc == 2) { return TCL_OK; } /* get the given action */ action = Tcl_GetStringFromObj(objv[2], NULL); /* check if signal should be reset to default */ if (!strcmp(action, "-default")) { /* special case of SIGWINCH, which we must keep processing */ #ifdef SIGWINCH if (signum != SIGWINCH) #endif if (signal(signum, SIG_DFL) == (void *)-1) goto error; if (ctx == NULL) return TCL_OK; if (ctx->script != ELTCL_SIGDFL && ctx->script != ELTCL_SIGIGN) { Tcl_DecrRefCount(ctx->script); Tcl_AsyncDelete(ctx->asyncH); } ctx->script = ELTCL_SIGDFL; return TCL_OK; } /* check if signal should be ignored */ if (!strcmp(action, "-ignore")) { if (ctx == NULL) { ctx = createSignalContext(signum, iinfo); if (ctx == NULL) goto error; } /* special case of SIGWINCH, which we must keep processing */ #ifdef SIGWINCH if (signum != SIGWINCH) #endif if (signal(signum, SIG_IGN) == (void *)-1) goto error; if (ctx->script != ELTCL_SIGDFL && ctx->script != ELTCL_SIGIGN) { Tcl_DecrRefCount(ctx->script); Tcl_AsyncDelete(ctx->asyncH); } ctx->script = ELTCL_SIGIGN; return TCL_OK; } /* check if signal should be (un)blocked */ if (!strcmp(action, "-block") || !strcmp(action, "-unblock")) { Tcl_DString dstring; int code; sigemptyset(&set); sigemptyset(&oset); sigaddset(&set, signum); if (!strcmp(action, "-block")) code = sigprocmask(SIG_BLOCK, &set, &oset); else code = sigprocmask(SIG_UNBLOCK, &set, &oset); if (code) goto error; /* return the previous mask */ Tcl_DStringInit(&dstring); for(i=0; i<ELTCL_MAXSIG; i++) if (signalNames[i] != NULL) { if (sigismember(&oset, i)) Tcl_DStringAppendElement(&dstring, signalNames[i]); } Tcl_DStringResult(interp, &dstring); return TCL_OK; } /* a script was given: create async handler and register signal */ if (ctx == NULL) { ctx = createSignalContext(signum, iinfo); if (ctx == NULL) goto error; } /* block signal while installing handler */ sigemptyset(&set); sigaddset(&set, signum); if (sigprocmask(SIG_BLOCK, &set, &oset)) goto error; #ifdef SIGWINCH if (signum != SIGWINCH) #endif if (signal(signum, signalHandler) == (void *)-1) { sigprocmask(SIG_SETMASK, &oset, NULL); goto error; } if (ctx->script != ELTCL_SIGDFL && ctx->script != ELTCL_SIGIGN) { Tcl_DecrRefCount(ctx->script); Tcl_AsyncDelete(ctx->asyncH); } ctx->script = objv[2]; Tcl_IncrRefCount(ctx->script); ctx->asyncH = Tcl_AsyncCreate(asyncSignalHandler, ctx); sigprocmask(SIG_SETMASK, &oset, NULL); return TCL_OK; error: Tcl_SetResult(interp, (char *)Tcl_ErrnoMsg(errno), TCL_VOLATILE); Tcl_SetErrno(errno); Tcl_PosixError(interp); return TCL_ERROR; }