/**************************************************************\ drsdaq Main program for data acquisition, starts threads for console input. Original program by S. Commichau. Oliver Grimm, May 2010 \**************************************************************/ #define LOCKFILE "/tmp/CT3_DAQ_LOCK" #include #include #include #include #include "DAQReadout.h" #include "HVFeedback.h" // Function prototypes void CrashHandler(int); void ExitFunction(); // ================ // Main program // ================ // // Several unlikely system call failures are handled via throwing an exception. int main() { char str[MAX_COM_SIZE], *Command; int LockDescriptor; // Assure only one instance of program runs (lock creator written to log file) // Lock file deleted by destructor if((LockDescriptor = open(LOCKFILE,O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1) { if(errno==EEXIST) { printf("Error: Lock file already existing\n"); snprintf(str, sizeof(str), "paste %s -s -d ' '",LOCKFILE); system(str); } else printf("Could not create lock file %s (%s)\n", LOCKFILE, strerror(errno)); exit(EXIT_FAILURE); } close(LockDescriptor); sprintf(str,"echo Created >%s; date >>%s; echo by $USER@$HOSTNAME >>%s",LOCKFILE,LOCKFILE,LOCKFILE); system(str); // Readline library uses getc() (allows interruption by signal) rl_getc_function = getc; // writev() in DAQ thread needs to be able to write at least 3 chunks if(IOV_MAX < 2) { printf("Fatal error: IOV_MAX is less than 2, cannot use writev() to write event data.\n"); exit(EXIT_FAILURE); } system("clear"); printf("\n*** DRS readout (built %s, %s, revision %s) *** \n\n",__DATE__, __TIME__, REVISION); // Set exit function atexit(&ExitFunction); // Construct main instance (static ensures destructor is called with exit()) static DAQReadout M; // Set signal handlers signal(SIGILL, &CrashHandler); signal(SIGABRT, &CrashHandler); signal(SIGFPE, &CrashHandler); signal(SIGSEGV, &CrashHandler); signal(SIGBUS, &CrashHandler); // Command loop while (!M.ExitRequest) { // Assemble prompt if (M.NumBoards == 0) snprintf(M.Prompt,sizeof(M.Prompt),"\rDAQ> "); else if (M.FirstBoard == M.LastBoard) snprintf(M.Prompt,sizeof(M.Prompt),"\rDAQ|B%d> ",M.FirstBoard); else snprintf(M.Prompt,sizeof(M.Prompt),"\rDAQ|B%d-%d> ",M.FirstBoard,M.LastBoard); // Read Command Command = readline(M.Prompt); if (Command == NULL) continue; if(strlen(Command)>0) add_history(Command); // Process command DimClient::sendCommand(SERVER_NAME"/Command", Command); free(Command); } } // Remove lock file before running default signal code void CrashHandler(int Signal) { remove(LOCKFILE); printf("Caught signal number %d. Removed lockfile and performing standard signal action. Good luck.\n",Signal); signal(Signal, SIG_DFL); raise(Signal); } // This function will be implicitly called by exit() void ExitFunction() { if (remove(LOCKFILE) == -1) { printf("Could not remove lock file %s (%s)\n", LOCKFILE, strerror(errno)); } }