📄 eibdrv_sim.c
字号:
Stop or Exit button is pressed. */ shmdt(sim->shm_results); if (rw_sim.eib_fd>0) close(rw_sim.eib_fd); exit(97);}void sim_read(Eib_bcu2_sim_shm *shm_segment){ int i; unsigned long flags; struct sigaction read_sigalrm; struct sigaction read_sigterm; struct sigaction read_sigio; // must be before P() sim->f_stop_readwrite=0; rw_sim.eib_fd=0; P(sim->sem_start_rw); rw_sim.shm_segment=shm_segment; rw_sim.local_results.result=0; rw_sim.local_results.tp=0; for (i=0;i<EIB_BUF_ELEMENT_SIZE;i++) { rw_sim.local_results.rw[i]=0; rw_sim.local_results.w_failed[i]=0; } read_sigalrm.sa_handler=read_sigalrm_handler; sigfillset(&read_sigalrm.sa_mask); read_sigalrm.sa_flags=0; if (sigaction(SIGALRM,&read_sigalrm,NULL)==-1) { shmdt(sim->shm_results); exit(20); } read_sigterm.sa_handler=read_sigterm_handler; sigfillset(&read_sigterm.sa_mask); read_sigterm.sa_flags=0; if (sigaction(SIGTERM,&read_sigterm,NULL)==-1) { shmdt(sim->shm_results); exit(21); } read_sigio.sa_handler=read_sigio_handler; sigfillset(&read_sigio.sa_mask); read_sigio.sa_flags=0; if (sigaction(SIGIO,&read_sigio,NULL)==-1) { shmdt(sim->shm_results); exit(22); } if ((rw_sim.eib_fd=open(sim->device,O_RDWR|O_NONBLOCK))<0) { shmdt(sim->shm_results); exit(23); } if ((fcntl(rw_sim.eib_fd,F_SETOWN,getpid())==-1)|| ((flags=fcntl(rw_sim.eib_fd,F_GETFL))==-1) || ((fcntl(rw_sim.eib_fd,F_SETFL,flags|FASYNC)==-1))) { shmdt(sim->shm_results); exit(24); } alarm(sim->sim_parameter->run_time*60); while(!sim->f_stop_readwrite) pause(); alarm(0); /* Copy local results into shared memory segment */ P(sim->sem_shm_results); *rw_sim.shm_segment=rw_sim.local_results; V(sim->sem_shm_results); shmdt(sim->shm_results); close(rw_sim.eib_fd); exit(0);}void split_sigterm_handler(){ /* SIGTERM is raised after one of the write or read processes exits with a status != 0 or the Stop or Exit button is pressed. This signal handler is inherited to write and read processes until they register their own SIGTERM-Handlers. The split process never terminates upper the SIGTERM-Signal; this handler is necessary because of sending the SIGTERM signal to the whole process group of which split is process group leader. */ if (getpgrp()!=getpid()) { shmdt(sim->shm_results); exit(97); }}void sim_split(){ int i,j,result; struct sigaction split_sigchld; struct sigaction split_sigterm; pid_t exit_pid; int exit_status; int exit_code=0; split_sigterm.sa_handler=split_sigterm_handler; sigfillset(&split_sigterm.sa_mask); split_sigterm.sa_flags=0; if (sigaction(SIGTERM,&split_sigterm,NULL)==-1) exit(3); split_sigchld.sa_handler=SIG_DFL; sigfillset(&split_sigchld.sa_mask); split_sigchld.sa_flags=0; if (sigaction(SIGCHLD,&split_sigchld,NULL)==-1) exit(4); /* Create a process group and make itself to its leader */ if (setpgid(getpid(),0)!=0) exit(5); /* Fork write and read processes */ for (j=0;j<2;j++) { for (i=0;i<sim->sim_parameter->proc_count;i++) { result=fork(); if (result==0) { if (j==0) sim_write(sim->shm_results+j*sim->sim_parameter->proc_count+i); else sim_read(sim->shm_results+j*sim->sim_parameter->proc_count+i); } else if (result==-1) break; } if (result==-1) break; } /* In case of error terminate all processes created */ if (result==-1) { kill(0,SIGTERM); exit_code=1; } /* Unlock all read and write processes by a global semaphore variable */ if (semctl(sim->sem_start_rw,0,SETVAL,(int)2*sim->sim_parameter->proc_count)==-1) exit_code=2; /* Wait for termination of all write/read processes */ for (i=0;i<sim->sim_parameter->proc_count*2;i++) { exit_pid=wait(&exit_status); if ((WIFSIGNALED(exit_status))|| ((WIFEXITED(exit_status))&&(WEXITSTATUS(exit_status)>0))) { kill(0,SIGTERM); if (exit_code==0) exit_code=WEXITSTATUS(exit_status); } } exit(exit_code);}void cleanup(void *arg,int btn){ /* Return all semaphores, shared memory segments; close all open files; hide all forms and return the central simulator struct. This function is called in case of error during process creation in main function. */ Eib_bcu2_sim *sim=(Eib_bcu2_sim *)arg; switch(sim->cleanup_code) { case 8: shmdt(sim->shm_results); case 7: shmctl(sim->shm_results_id,IPC_RMID,(int)0); case 6: fl_ext_activate_object(sim->MainForm->StartBtn); return; case 5: semctl(sim->sem_start_rw,0,IPC_RMID,(int)0); case 4: semctl(sim->sem_shm_results,0,IPC_RMID,(int)0); case 3: fl_free_form(sim->MainForm->VisForm); fl_ext_free_indicator(sim->RunForm->Indicator); fl_free_form(sim->RunForm->VisForm); case 2: close(sim->eib_fd); case 1: returnEib_bcu2_sim(sim); fl_finish(); exit(3); }}void main_sigchld_handler(){ /* SIGCHLD is raised, when the split process terminates after the termination of all write/read processes upon the expiry of runtime or termination by Stop or Exit Btn. */ FD_ResultsForm *ResultsForm; int exit_status; pid_t exit_pid; int result; if (sim->state==EIBDRV_SIM_STATE_RUNNING) { sim->state=EIBDRV_SIM_STATE_READY; exit_pid=wait(&exit_status); if (WIFSIGNALED(exit_status)) { make_InternalErrorPanel(sim->Panels+6,98); fl_ext_panel1(sim->Panels+6,sim,panel_cb); } else if ((WIFEXITED(exit_status))&&(WEXITSTATUS(exit_status)>0)) { switch(WEXITSTATUS(exit_status)) { case 97: fl_ext_panel1(sim->Panels+5,sim,panel_cb); break; default: make_InternalErrorPanel(sim->Panels+6,WEXITSTATUS(exit_status)); fl_ext_panel1(sim->Panels+6,sim,panel_cb); break; } } else { time(&sim->stat_get_time); if (ioctl(sim->eib_fd,FT_GET_STAT,sim->stat)<0) { switch(result=errno) { case EFAULT: make_InternalErrorPanel(sim->Panels+6,59); fl_ext_panel1(sim->Panels+6,sim,panel_cb); break; case EBUSY: fl_ext_panel1(sim->Panels+4,sim,panel_cb); break; case EACCES: fl_ext_panel1(sim->Panels+10,sim,panel_cb); break; } } else { ResultsForm=create_form_ResultsForm(sim); fl_show_form(ResultsForm->VisForm,FL_PLACE_CENTER,FL_TRANSIENT,"eibdrv_sim"); if (create_Log(sim)<0) fl_ext_panel1(sim->Panels+11,sim,panel_cb); } } shmdt(sim->shm_results); shmctl(sim->shm_results_id,IPC_RMID,(int)0); fl_ext_activate_object(sim->MainForm->StartBtn); fl_hide_form(sim->RunForm->VisForm);#if FL_INCLUDE_VERSION < 89 fl_set_idle_callback(0,0);#endif } else // sim->state==EIB_BCU_SIM_STATE_SHUTDOWN { shmdt(sim->shm_results); shmctl(sim->shm_results_id,IPC_RMID,(int)0); semctl(sim->sem_start_rw,0,IPC_RMID,(int)0); semctl(sim->sem_shm_results,0,IPC_RMID,(int)0); fl_free_form(sim->MainForm->VisForm); fl_ext_free_indicator(sim->RunForm->Indicator); fl_free_form(sim->RunForm->VisForm); close(sim->eib_fd); returnEib_bcu2_sim(sim); fl_finish(); exit(0); } }int main(int argc,char *argv[]){ int result; int len; struct sigaction main_sigchld; sim=getEib_bcu2_sim(); if (read_PanelContentA(EIBDRV_SIM_PANELFILE,&sim->Panels)!=EIBDRV_SIM_PANELFILESIZE) { printf("eibdrv_sim: Panelfile %s not found!\n",EIBDRV_SIM_PANELFILE); exit(2); } if (argc!=2) { printf("usage: eibdrv_sim device\n"); exit(1); } sim->device=(char *)malloc((strlen(argv[1])+1)*sizeof(char)); strcpy(sim->device,argv[1]); fl_set_icm_color(FL_INACTIVE_COL,200,200,200); fl_initialize(&argc,argv,"eibdrv_sim",0,0); fl_set_border_width(2); sim->cleanup_code=1; if ((sim->eib_fd=open(argv[1],O_RDWR|O_NONBLOCK))<0) { switch(result=errno) { case ENOENT: fl_ext_panel1(sim->Panels,sim,cleanup); break; case EBUSY: fl_ext_panel1(sim->Panels+1,sim,cleanup); break; case ENOBUFS: fl_ext_panel1(sim->Panels+2,sim,cleanup); break; default: fl_ext_panel1(sim->Panels+3,sim,cleanup); break; } fl_do_forms(); } sim->cleanup_code=2; if (((sim->ftstation_settings->mode=ioctl(sim->eib_fd,FT_GET_MODE))<0) || ((sim->ftstation_settings->symb_baudrate=ioctl(sim->eib_fd,FT_GET_BAUDRATE))<0) || ((len=ioctl(sim->eib_fd,FT_GET_PORT_LENGTH))<0) || (ioctl(sim->eib_fd,FT_GET_OUTBUF_SIZE,&(sim->ftstation_settings->outbuf_size))<0) || (ioctl(sim->eib_fd,FT_GET_WPBUF_SIZE,&(sim->ftstation_settings->wpbuf_size))<0) || (ioctl(sim->eib_fd,FT_GET_RPBUF_SIZE,&(sim->ftstation_settings->rpbuf_size))<0) || (ioctl(sim->eib_fd,FT_GET_RPBUF_MSGSIZE,&(sim->ftstation_settings->rpbuf_msgbuf_size))<0)) { switch(result=errno) { case EBUSY: fl_ext_panel1(sim->Panels+4,sim,cleanup); fl_do_forms(); case EFAULT: fl_ext_panel1(sim->Panels+6,sim,cleanup); fl_do_forms(); case EACCES: fl_ext_panel1(sim->Panels+10,sim,cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -