PUBLIC int mime_run_command(const char *cmd, FILE *fo) { sigset_t nset; FILE *nfo; pid_t pid; int p[2]; int flags; if (cmd == NULL) return 0; flags = get_cmd_flags(cmd, &cmd); if (fo == NULL) /* no output file, just return the flags! */ return flags; if ((flags & CMD_FLAG_SHELLCMD) != 0) { /* run command under the shell */ char *cp; char *shellcmd; if ((shellcmd = value(ENAME_SHELL)) == NULL) shellcmd = __UNCONST(_PATH_CSHELL); (void)sasprintf(&cp, "%s -c '%s'", shellcmd, cmd); cmd = cp; } if (prepare_pipe(&nset, p) != 0) { warn("mime_run_command: prepare_pipe"); return flags; /* XXX - this or -1? */ } flush_files(fo, 0); /* flush fo, all registered files, and stdout */ switch (pid = start_command(cmd, &nset, p[READ], fileno(fo), NULL)) { case -1: /* error */ /* start_command already did a warn(). */ warnx("mime_run_command: %s", cmd); /* tell a bit more */ (void)close(p[READ]); (void)close(p[WRITE]); return flags; /* XXX - this or -1? */ case 0: /* child */ assert(/*CONSTCOND*/ 0); /* a real coding error! */ /* NOTREACHED */ default: /* parent */ (void)close(p[READ]); nfo = fdopen(p[WRITE], "w"); if (nfo == NULL) { warn("mime_run_command: fdopen"); (void)close(p[WRITE]); warn("fdopen"); return flags; } register_file(nfo, 1, pid); return flags; } }
PUBLIC void mime_run_function(void (*fn)(FILE *, FILE *, void *), FILE *fo, void *cookie) { sigset_t nset; FILE *nfo; pid_t pid; int p[2]; if (prepare_pipe(&nset, p) != 0) { warn("mime_run_function: pipe"); return; } flush_files(fo, 0); /* flush fo, all registered files, and stdout */ switch (pid = fork()) { case -1: /* error */ warn("mime_run_function: fork"); (void)close(p[READ]); (void)close(p[WRITE]); return; case 0: /* child */ (void)close(p[WRITE]); prepare_child(&nset, p[READ], fileno(fo)); fn(stdin, stdout, cookie); (void)fflush(stdout); _exit(0); /* NOTREACHED */ default: /* parent */ (void)close(p[READ]); nfo = fdopen(p[WRITE], "w"); if (nfo == NULL) { warn("run_function: fdopen"); (void)close(p[WRITE]); return; } register_file(nfo, 1, pid); return; } }
/* void catch_signal(int sig, int code, struct sigcontext *scp) { */ void catch_signal(int sig) { char *sptr; cStr *sigstr; cData arg1; Bool do_shutdown = NO; signal(sig, catch_signal); sptr = sig_name(sig); sigstr = string_from_chars(sptr, strlen(sptr)); write_err("Caught signal %d: %S", sig, sigstr); string_discard(sigstr); /* figure out what to do */ switch (sig) { #ifdef __UNIX__ case SIGHUP: atomic = NO; handle_connection_output(); flush_files(); #endif #ifndef __MSVC__ case SIGUSR2: /* let the db do what it wants from here */ break; case SIGUSR1: { cData *d; cList *l; /* First cancel all preempted and suspended tasks */ l = vm_list(); for (d = list_first(l); d; d = list_next(l, d)) { /* boggle */ if (d->type != INTEGER) continue; vm_cancel(d->u.val); } list_discard(l); /* now cancel the current task if it is valid */ if (vm_lookup(task_id) != NULL) { vm_cancel(task_id); } /* jump back to the main loop */ longjmp(main_jmp, 1); break; } #endif case SIGILL: /* lets panic and hopefully shutdown without frobbing the db */ panic(sig_name(sig)); break; case SIGTERM: if (running) { write_err("*** Attempting normal shutdown ***"); running = NO; /* jump back to the main loop, ignore any current tasks; *drip*, *drip*, leaky */ longjmp(main_jmp, 1); } else { panic(sig_name(sig)); } break; default: do_shutdown = YES; break; } /* only pass onto the db if we are 'executing' */ if (!running) return; /* send a message to the system object */ arg1.type = SYMBOL; arg1.u.symbol = ident_get(sptr); vm_task(SYSTEM_OBJNUM, signal_id, 1, &arg1); if (do_shutdown) running = NO; }
short pass2( void ) { short int i; unsigned short reloc; register SCNHDR *sec_hdr_ptr; register SEC_DATA *sec_data_ptr; register unsigned long size; SYMBOL *sym; long where_we_were; char section_name[SYMNMLEN + 1]; pass = 2; size = 0; section_name[SYMNMLEN] = '\0'; for( i = 1, sec_hdr_ptr = §ion_header[1]; i <= (short) section_cnt; ++i, ++sec_hdr_ptr ) { strncpy( section_name, sec_hdr_ptr->s_name, SYMNMLEN); sym = symbol_lookup( section_name ); if( NULL == sym ) FATAL_ERROR("Couldn't find section header in symbol table - pass2.c:pass2()"); sym->value = 0L; if( i > 1 ) update_symbol_table( 0L, (long) size, (long) i ); size += (sec_hdr_ptr->s_size / ((sec_hdr_ptr->s_flags & SECTION_PM) == SECTION_PM ? PM_WORD_SIZE : DM_WORD_SIZE)); } if( (obj_fd = fopen( obj_name, UPDATE_BINARY )) == NULL ) { FATAL_ERROR("Error opening object file"); } header_ptr = ftell( obj_fd ); /* Seek past the object file and section headers so we can write the * the raw data for each section. */ fseek( obj_fd, (long)(header_ptr + FILHSZ + AOUTSZ + section_cnt * SCNHSZ), 0 ); glob_sym_fd = temp_file_create( WRITE_BINARY ); glob_sym_temp_index = num_open_files - 1; stat_sym_fd = temp_file_create( WRITE_BINARY ); stat_sym_temp_index = num_open_files - 1; sym_fd = temp_file_create( WRITE_BINARY ); sym_temp_index = num_open_files - 1; rel_fd = temp_file_create( WRITE_BINARY ); rel_temp_index = num_open_files - 1; line_fd = temp_file_create( WRITE_BINARY ); line_temp_index = num_open_files - 1; reloc = 0; size = 0; for( i = 1, sec_hdr_ptr = §ion_header[1], sec_data_ptr = §ion_data[1]; i <= (short) section_cnt; ++i, ++sec_hdr_ptr, ++sec_data_ptr ) { num_line = 0; num_reloc = 0; /* Code generation time */ code_process( temp_file[sec_data_ptr->temp_file_index], (long) size, i ); sec_hdr_ptr->s_nlnno = (unsigned short) num_line; sec_hdr_ptr->s_nreloc = (unsigned short) num_reloc; reloc += sec_hdr_ptr->s_nreloc; size += (sec_hdr_ptr->s_size / ((sec_hdr_ptr->s_flags & SECTION_PM) == SECTION_PM ? PM_WORD_SIZE : DM_WORD_SIZE)); } fixup_symbol_table( sym_fd ); flush_files(); /* Write the finished table to the symbol table file */ if( (glob_sym_fd = fopen(temp_file[glob_sym_temp_index], READ_BINARY )) == NULL ) FATAL_ERROR("Error opening global symbol temp file"); if( (stat_sym_fd = fopen(temp_file[stat_sym_temp_index], READ_BINARY )) == NULL ) FATAL_ERROR("Error opening static symbol temp file"); dump_symbols(); fclose( glob_sym_fd ); fclose( stat_sym_fd ); fflush( sym_fd ); fclose( sym_fd ); /* Write the object file header and the section headers */ where_we_were = ftell( obj_fd ); fseek( obj_fd, 0L, 0 ); object_headers(); fseek( obj_fd, where_we_were, 0 ); /* Write the relocation info to the object file */ if( (rel_fd = fopen(temp_file[rel_temp_index], READ_BINARY)) == NULL ) FATAL_ERROR("Error opening temp relocation file"); write_all_relocation_info( (long) reloc ); fclose( rel_fd ); if( !check_if_errors() ) { /* Append the line number entries, symbol table, and string table * to the end of the object file. */ copy_section( temp_file[line_temp_index] ); copy_section( temp_file[sym_temp_index] ); write_string_table(); fflush( obj_fd ); fclose( obj_fd ); delete_temp_files(); return( 0 ); } else { asm_exit( FATAL ); } }
struct cmd_result * treat_cmd(struct cmd *command,void *sdata) { struct acq_workspace *ws=(struct acq_workspace *)sdata; int id1,id2,id3,id4,id5; struct data_descriptor *current_ctrl; int i; char * encoded; char *sres; int streamid; struct generic_buffer *acq_buffer; unsigned char *binary_data; struct cmd_result *res=malloc(sizeof(struct cmd_result)); res->retcode=-1; res->str=NULL; printf("********************* NEW COMMAND **********************\n"); printf("executing local function %s with %d params : \n",command->name,command->nb_params); for (i=0;i<command->nb_params;i++) { printf("param%d=%s\n",i,command->params[i]); } if (!strcmp(command->name,"init_acq")) { //param 0 : datadir //param 1 : varmod IP (or undef) if (ws->initialized!=0) { res->str=strdup("acq has been already been initialized"); res->retcode=1; return res; } if (command->nb_params<2) { res->retcode=0; res->str=malloc(4096*sizeof(char)); sprintf(res->str,"init_acq, %d arguments given, 2 needed",command->nb_params-1); return res; } //initializing the stats init_stats(ws,command->params[1]); //initializing the acquisition init_acquisition(ws,command->params[0]); //initializing the scheduler init_burst_detector(ws); //initializing all the other modules launch_consumer_chain(ws); //initialization is done ws->initialized=1; res->str=strdup("acquisition initialized"); res->retcode=1; return res; } //******************************************** if (!strcmp(command->name,"deinit_acq")) { if (ws->initialized!=1) { res->str=strdup("ethacq is not initialized"); res->retcode=1; return res; } //deinit the acquisition deinit_acquisition(ws); //stopping all the treatment modules stop_consumer_chain(ws); //deinit the scheduler deinit_burst_detector(ws); //initializing the stats deinit_stats(ws); //close and free the streams structures ws->nb_streams=0; //deinit is done ws->initialized=0; //return ok res->str=strdup("acquisition deinitialized"); res->retcode=1; return res; } //******************************************** //stop any other command until initialize is completed if (ws->initialized==0) { res->str=strdup("cmd are forbidden while acq not initialized"); res->retcode=0; return res; } //******************************************** if (!strcmp(command->name,"newunit_acq")) { //param 0 : nb_streams //param 1 : name of the acq library //param 2 : name of the uncap library //param 3 : stream_suffix //param 4 : specific param 1 //param 5 : specific param 2 //param 6 : specific param 3 if (command->nb_params<7) { res->retcode=0; res->str=malloc(4096*sizeof(char)); sprintf(res->str,"newunit_acq, %d arguments given, 7 needed",command->nb_params-1); return res; } //get first stream id int nbs=iohtoi(command->params[0]); int fid=ws->nb_streams; printf("nbs=%d fid=%d\n",nbs,fid); //create the workspace for the new unit printf("creating newunit workspace\n"); struct acqunit_workspace * newunit=make_acq_unit(nbs,fid,command->params[1],command->params[2],command->params[3],ws); if (newunit==NULL) { res->retcode=0; res->str=malloc(4096*sizeof(char)); sprintf(res->str,"error loading plugins"); return res; } //initialize acquisition library printf("initializing acquisition library\n"); newunit->specws=(newunit->init_acq)(command->params[4],command->params[5],command->params[6]); //initialize uncap library printf("initializing uncap library\n"); newunit->uncapws=(newunit->init_uncap)(nbs,fid,command->params[1]); //we initialize the nb of streams ws->nb_streams+=nbs; //initializing the streams printf("initializing the streams\n"); newunit->streams=malloc(nbs*sizeof(struct stream_workspace)); for(i=0;i<nbs;i++) { printf("creating stream %d with id %d\n",i,fid+i); newunit->streams[i].id=fid+i; newunit->streams[i].output=-1; newunit->streams[i].socket=NULL; newunit->streams[i].shdata=NULL; newunit->streams[i].acqunit=newunit; ws->streams[i+fid]=newunit->streams[i]; } //store the newunit in the main ws printf("linking the new unit\n"); newunit->next=ws->acqunits; ws->acqunits=newunit; //open new files printf("open the new files\n"); opennew_files(ws); //open new sockets printf("open the new sockets\n"); opennew_socket(ws); //open new shared buffers printf("open the new shared buffers\n"); opennew_shmem(ws); //start the thread printf("Starting the acquisition thread\n"); if (pthread_create(&(newunit->t_acquisition),NULL,acquisition,newunit)<0) { perror("pthread_create"); exit(1); } pthread_detach(newunit->t_acquisition); //attach an id to the acqunit newunit->auid=ws->nb_acqunits; ws->nb_acqunits++; //return the acqunit id as a result res->str=malloc(2048); sprintf(res->str,"%d",newunit->auid); res->retcode=1; return res; } //******************************************** if (!strcmp(command->name,"get_cpkt_byid_acq")) { //the five params are the five generic ids used freely by the uncap library //check the number of parameters if (command->nb_params<5) { res->retcode=0; res->str=malloc(4096*sizeof(char)); sprintf(res->str,"get_cpkt_byid_acq, %d arguments given, 5 needed",command->nb_params-1); return res; } //extract the parameters id1=iohtoi(command->params[0]); //this is the auid id2=iohtoi(command->params[1]); //this is id1 of uncap plugin id3=iohtoi(command->params[2]); //this is id2 of uncap plugin id4=iohtoi(command->params[3]); //this is id3 of uncap plugin id5=iohtoi(command->params[4]); //this is id4 of uncap plugin printf("searching for %x %x %x %x %x :\n",id1,id2,id3,id4,id5); for(i=1;i<10;i++) { //we try 10 times //wait for packet to come - the more chess we have the longer we wait usleep(i*50000); //search the packet in the ctrl fifo current_ctrl=ws->begin_ctrl; while(current_ctrl!=ws->end_ctrl) { if (current_ctrl->id==-1) { current_ctrl=current_ctrl->next; continue; } if (id1==current_ctrl->auws->auid) //the auid is good if ((current_ctrl->auws->select_packet_uncap)(current_ctrl->auws->uncapws,current_ctrl->generic_buffer->data,id2,id3,id4,id5)) { //result found, encode and send back encoded=encode_packet(current_ctrl->generic_buffer->data,current_ctrl->generic_buffer->size); res->str=strdup(encoded); free(encoded); res->retcode=1; //remove the found packet current_ctrl->id=-1; return res; } //if found current_ctrl=current_ctrl->next; } } //Three chess, we give up res->str=strdup("no packet with this id"); res->retcode=0; return res; } //************************************* if (!strcmp(command->name,"zero_stats_acq")) { zero_stats(ws); res->str=strdup("ok"); res->retcode=1; return res; } //************************************* if (!strcmp(command->name,"start_acq")) { printf("starting acquisition\n"); res->str=malloc(2048); memset(res->str,0,2048); if(ws->transfer_file != -1) { start_acquisition(ws); res->retcode=1; sprintf(res->str,"acquisition started"); } else { sprintf(res->str,"unknown directory : %s",ws->datadir); res->retcode=0; } return res; } //************************************* if (!strcmp(command->name,"stop_acq")) { printf("stoping acquisition\n"); stop_acquisition(ws); res->str=strdup("acquisition stopped"); res->retcode=1; return res; } //************************************* if (!strcmp(command->name,"set_refclock_acq")) { if (command->nb_params<1) { res->retcode=0; res->str=malloc(4096*sizeof(char)); sprintf(res->str,"set_refclock_acq, %d arguments given, 1 needed",command->nb_params-1); return res; } strcpy(ws->refclock,command->params[0]); //return result res->str=strdup("clock set"); res->retcode=1; return res; } //************************************* if (!strcmp(command->name,"inject_data_acq")) { printf("injecting data\n"); if (command->nb_params<2) { res->retcode=0; res->str=malloc(4096*sizeof(char)); sprintf(res->str,"inject_data_acq, %d arguments given, 2 needed",command->nb_params-1); return res; } //finding the corresponding stream streamid=iohtoi(command->params[0]); if (streamid>=ws->nb_streams) { res->str=strdup("no stream with that id"); res->retcode=0; return res; } //create a new buffer acq_buffer=get_generic_buffer(ws->bpool); //copy the data binary_data=decode_binary_data(command->params[1],&acq_buffer->size); strncpy((char *)acq_buffer->data,(const char *)binary_data,acq_buffer->size); free(binary_data); //fill a data descriptor with this packet insert_new_data_descriptor(ws,acq_buffer,ws->streams[streamid].acqunit,0); //return result res->str=strdup("data injected"); res->retcode=1; return res; } //************************************* if (!strcmp(command->name,"get_stats_acq")) { sres=get_stats(ws); res->str=sres; res->retcode=1; return res; } //************************************* if (!strcmp(command->name,"flush_files_acq")) { printf("flushing files\n"); if (get_acqstate(ws)!=0) { res->str=strdup("acquisition is still active, cant flush"); res->retcode=0; return res; } if (!strcmp(command->params[0],"")) { printf("no prefix given : using noname as prefix\n"); flush_files("noname",ws); res->str=strdup("files flushed with prefix noname"); } else { flush_files(command->params[0],ws); res->str=strdup("files flushed"); } res->retcode=1; return res; } //************************************* if (!strcmp(command->name,"start_shmem_acq")) { ws->active_shmem=1; res->retcode=1; res->str=strdup("Shared memory active"); return res; } //************************************* if (!strcmp(command->name,"stop_shmem_acq")) { ws->active_shmem=0; res->retcode=1; res->str=strdup("Shared memory inactive"); return res; } //************************************* if (!strcmp(command->name,"start_bsched_acq")) { ws->bsched_active=1; res->retcode=1; res->str=strdup("Burst scheduler active"); return res; } //************************************* if (!strcmp(command->name,"stop_bsched_acq")) { ws->bsched_active=0; res->retcode=1; res->str=strdup("Burst scheduler inactive"); return res; } //************************************* if (!strcmp(command->name,"allow_autoflush_acq")) { if (command->nb_params<1) { res->retcode=0; res->str=malloc(4096*sizeof(char)); sprintf(res->str,"allow_autoflush_acq, %d arguments given, 1 needed",command->nb_params-1); return res; } ws->autoflush_limit=iohtoi(command->params[0]); ws->autoflush_active=1; res->retcode=1; res->str=strdup("variable set"); return res; } //************************************* if (!strcmp(command->name,"dis_autoflush_acq")) { ws->autoflush_active=0; res->retcode=1; res->str=strdup("variable set"); return res; } //************************************* if (!strcmp(command->name,"allow_rawoutp_acq")) { ws->rawoutp_active=1; res->retcode=1; res->str=strdup("raw output active"); return res; } //************************************* if (!strcmp(command->name,"dis_rawoutp_acq")) { ws->rawoutp_active=0; res->retcode=1; res->str=strdup("raw output inactive"); return res; } //************************************* res->retcode=0; res->str=strdup("Unknown command"); printf("unknown command\n"); return res; }