void EventCheck2() { VCOS_THREAD_T thread1, thread2; // Create two event group. TEST_OK("os_eventgroup_create", os_eventgroup_create ( &eventgroup, "group") ); TEST_OK("os_eventgroup_create", os_eventgroup_create ( &eventgroup2, "group2") ); TEST_OK("os_thread_start", os_thread_start( &thread1, &ThreadTwo, NULL, 1000, "ThreadOne")); TEST_OK("os_thread_start", os_thread_start( &thread2, &ThreadThree, NULL, 1000, "ThreadTwo")); // Wait for threads to start. Should really check a semaphore! TEST_OK("os_delay", os_delay(1000)); for (current_event=1;current_event<=TERM_EVENT;current_event++) { TEST_OK("os_eventgroup_signal", os_eventgroup_signal ( &eventgroup, current_event) ); // for moment same on other thread current_event2 = current_event; TEST_OK("os_eventgroup_signal", os_eventgroup_signal ( &eventgroup2, current_event2) ); TEST_OK("os_delay", os_delay(1000)); } TEST_OK("os_eventgroup_destroy", os_eventgroup_destroy ( &eventgroup ) ); }
void test_2_task(void) { while (1) { uint8_t x; os_semaphore_wait(&a); for (x = 20; x < 7; x++) { usart_putsf("G'day World %d\r\n", x); os_delay(os_get_current_pid(), 1000); } os_semaphore_signal(&a); os_delay(os_get_current_pid(), 1000); } }
/// Releases job control resources and terminates running jobs void job_teardown(void) { // 20 tries will give processes about 1 sec to exit cleanly uint32_t remaining_tries = 20; bool all_dead = true; int i; Job *job; // Politely ask each job to terminate for (i = 0; i < MAX_RUNNING_JOBS; i++) { if ((job = table[i]) != NULL) { all_dead = false; uv_process_kill(&job->proc, SIGTERM); } } if (all_dead) { return; } os_delay(10, 0); // Right now any exited process are zombies waiting for us to acknowledge // their status with `wait` or handling SIGCHLD. libuv does that // automatically (and then calls `exit_cb`) but we have to give it a chance // by running the loop one more time event_poll(0); // Prepare to start shooting for (i = 0; i < MAX_RUNNING_JOBS; i++) { job = table[i]; // Still alive while (job && is_alive(job) && remaining_tries--) { os_delay(50, 0); // Acknowledge child exits event_poll(0); // It's possible that the event_poll call removed the job from the table, // reset 'job' so the next iteration won't run in that case. job = table[i]; } if (job && is_alive(job)) { uv_process_kill(&job->proc, SIGKILL); } } // Last run to ensure all children were removed event_poll(0); }
void ui_puts(uint8_t *str) { uint8_t *p = str; uint8_t c; while ((c = *p)) { if (c < 0x20) { abort(); } size_t clen = (size_t)mb_ptr2len(p); ui_call_put((String){ .data = (char *)p, .size = clen }); col++; if (mb_ptr2cells(p) > 1) { // double cell character, blank the next cell ui_call_put((String)STRING_INIT); col++; } if (utf_ambiguous_width(utf_ptr2char(p))) { pending_cursor_update = true; } if (col >= width) { ui_linefeed(); } p += clen; if (p_wd) { // 'writedelay': flush & delay each time. ui_flush(); uint64_t wd = (uint64_t)labs(p_wd); os_delay(wd, false); } }
// TODO: Error codes int usart_getc(FILE *unused) { if (usart_is_initialized) { while (!(UCSRA & (1 << RXC))) os_delay(os_get_current_process(), 1000); return UDR; } return 0; }
// TODO: Error codes int usart_putc(char data, FILE *unused) { if (usart_is_initialized) { while (!(UCSRA & (1 << UDRE))) os_delay(os_get_current_process(), 1000); UDR = data; } return 0; }
void task2(void *arg) { os_printf("task2 start....\n"); for (;;) { #if msg_queue_test memset(buffer, 0, 10); msg_get(&my_queue, buffer); os_printf("queue 0 read = %s\n", buffer); memset(buffer, 0, 10); msg_get(&my_queue1, buffer); os_printf("queue 1 read = %s\n", buffer); memset(buffer, 0, 10); msg_get(&my_queue2, buffer); os_printf("queue 2 read = %s\n", buffer); #endif #if sem_test sem_get(&sem); os_printf("task2 sem.count = %d\n", sem.count ); #endif #if mutex_test os_printf("task2 running\n" ); mutex_get(&mutex); os_printf("task2 priority: %d\n", new_task->prio ); mutex_put(&mutex); #endif os_delay(100); }; }
void task1(void *arg) { os_printf("task1 start....\n"); for (;;) { #if msg_queue_test msg_put(&my_queue, &msg1, FIFO); msg_put(&my_queue, &msg2, FIFO); msg_put(&my_queue, &msg3, FIFO); msg_put(&my_queue1, &msg4, FIFO); msg_put(&my_queue1, &msg5, FIFO); msg_put(&my_queue1, &msg6, FIFO); msg_put(&my_queue2, &msg7, FIFO); msg_put(&my_queue2, &msg8, FIFO); msg_put(&my_queue2, &msg9, FIFO); #endif #if sem_test sem_put(&sem); os_printf("task1 sem.count = %d\n", sem.count ); #endif #if mutex_test mutex_get(&mutex); os_printf("task1 priority: %d\n", new_task->prio ); schedule(); os_printf("task1 running\n"); mutex_put(&mutex); #endif os_delay(300); } }
void task4(void *arg) { os_printf("task1 start....\n"); for (;;) { os_printf("task4 running\n"); os_delay(10); } }
void job_teardown() { // 20 tries will give processes about 1 sec to exit cleanly uint32_t remaining_tries = 20; bool all_dead = true; int i; Job *job; // Politely ask each job to terminate for (i = 0; i < MAX_RUNNING_JOBS; i++) { if ((job = table[i]) != NULL) { all_dead = false; uv_process_kill(&job->proc, SIGTERM); } } if (all_dead) { return; } os_delay(10, 0); // Right now any exited process are zombies waiting for us to acknowledge // their status with `wait` or handling SIGCHLD. libuv does that // automatically (and then calls `exit_cb`) but we have to give it a chance // by running the loop one more time uv_run(uv_default_loop(), UV_RUN_NOWAIT); // Prepare to start shooting for (i = 0; i < MAX_RUNNING_JOBS; i++) { if ((job = table[i]) == NULL) { continue; } // Still alive while (is_alive(job) && remaining_tries--) { os_delay(50, 0); // Acknowledge child exits uv_run(uv_default_loop(), UV_RUN_NOWAIT); } if (is_alive(job)) { uv_process_kill(&job->proc, SIGKILL); } } }
int main(void) { os_add_task(test_task, &test_stack[127], 1); os_add_task(test_2_task, &test_2_stack[127], 2); os_semaphore_init(&a, 1); usart_init(0, USART_TRANSMIT); os_start(); while (1) { uint8_t x; os_semaphore_wait(&a); for (x = 10; x < 15; x++) { usart_putsf("Hello World %d\r\n", x); os_delay(os_get_current_pid(), 1000); } os_semaphore_signal(&a); os_delay(os_get_current_pid(), 1000); } }
void ThreadCheck() { VCOS_THREAD_T thread; // First create a sync semaphore TEST_OK("os_semaphore_create", os_semaphore_create(&sem1, OS_SEMAPHORE_TYPE_SUSPEND)); // and grab it TEST_OK("os_semaphore_obtain", os_semaphore_obtain(&sem1)); // Start the thread which shuold stall on the semaphore TEST_OK("os_thread_start", os_thread_start( &thread, &ThreadOne, NULL, 1000, "ThreadOne")); // Wait for thread to start for 1000 - should stall on semaphore and not change flag TEST_OK("os_delay", os_delay(1000)); // Check global data is unchanged TEST_OK("Flag = 0", flag); // release semaphore TEST_OK("os_semaphore_release", os_semaphore_release(&sem1)); // Wait for thread to continue for 100 - should be enough for it to set the flag TEST_OK("os_delay", os_delay(100)); // Check global data is changed to non-zero TEST_OK("Flag = 1", (flag == 0)); // Semaphore is currently released, so check the obtained function is correct. TEST_OK("os_semaphore_obtained - 0", os_semaphore_obtained(&sem1)) // now get the sema and test again TEST_OK("os_semaphore_obtain", os_semaphore_obtain(&sem1)); TEST_OK("os_semaphore_obtained - 1", (os_semaphore_obtained(&sem1) == 0)) TEST_OK("os_semaphore_release", os_semaphore_release(&sem1)); }
void adc_task(void) { uint8_t update_time = 0; adc_init(); while (1) { char light_str[6], temp_str[6], time_str[6]; uint8_t light = adc_acquire(0); uint8_t temperature = adc_acquire(1); uint8_t_to_ascii(light, &(light_str[0])); uint8_t_to_ascii(temperature, &(temp_str[0])); uint8_t_to_ascii(ticks, &(time_str[0])); os_semaphore_wait(&lcd_sem); lcd_set_cursor(0, 0); lcd_putstr("Time: "); lcd_putstr(time_str); lcd_set_cursor(1, 0); lcd_putstr("Light: "); lcd_putstr(light_str); lcd_set_cursor(2, 0); lcd_putstr("Temp: "); lcd_putstr(temp_str); os_semaphore_signal(&lcd_sem); os_semaphore_wait(&stt_sem); if (state) { update_time = 1; } else { update_time = 0; } os_semaphore_signal(&stt_sem); os_semaphore_wait(&tck_sem); if (update_time) { ticks++; } os_semaphore_signal(&tck_sem); if (state == 1) { usart_puts("Time: "); usart_puts(time_str); usart_puts("\r\n"); usart_puts("Light: "); usart_puts(light_str); usart_puts("\r\n"); usart_puts("Temperature: "); usart_puts(temp_str); usart_puts("\r\n"); } os_delay(os_get_current_pid(), 1000); } }
void EventCheck() { VCOS_THREAD_T thread; // Create one event group. TEST_OK("os_eventgroup_create", os_eventgroup_create ( &eventgroup, "group") ); TEST_OK("os_thread_start", os_thread_start( &thread, &ThreadTwo, NULL, 1000, "ThreadOne")); // Wait for thread to start. Should really check a semaphore! TEST_OK("os_delay", os_delay(1000)); for (current_event=1;current_event<=TERM_EVENT;current_event++) { TEST_OK("os_eventgroup_signal", os_eventgroup_signal ( &eventgroup, current_event) ); TEST_OK("os_delay", os_delay(1000)); } TEST_OK("os_eventgroup_destroy", os_eventgroup_destroy ( &eventgroup ) ); }
int main(void) { os_init(); os_semaphore_init(&lcd_sem, 1); os_semaphore_init(&btn_sem, 1); os_semaphore_init(&stt_sem, 1); os_semaphore_init(&tck_sem, 1); os_add_task(uart_task, &uart_task_stack[STACK_SIZE + 64], 1, "uart"); os_add_task(adc_task, &adc_task_stack[STACK_SIZE + 64], 0, "adc"); os_add_task(button_task, &button_task_stack[STACK_SIZE + 64], 2, "btn"); os_start_ticker(); os_semaphore_wait(&lcd_sem); lcd_init(); os_semaphore_signal(&lcd_sem); i2c_init(); usart_init(USART_TRANSMIT | USART_RECEIVE); usart_putc('\f'); while(1) { char buff[6]; os_delay(os_get_current_pid(), 2000); /*usart_puts("Start I2C\r\n"); int8_t start_ = i2c_start(); int8_t send_ = i2c_send_address(0xa0); i2c_stop(); if (start_ != 0) { usart_puts("Start error\r\n"); uint8_t_to_ascii((uint8_t) start_, &(buff[0])); usart_puts(buff); usart_puts("\r\n"); } if (send_ != 0) { usart_puts("Send error\r\n"); uint8_t_to_ascii((uint8_t) send_, &(buff[0])); usart_puts(buff); usart_puts("\r\n"); } usart_puts("Stop I2C\r\n\r\n");*/ } return 0; }
/* * If the machine has job control, use it to suspend the program, * otherwise fake it by starting a new shell. */ void mch_suspend() { /* BeOS does have SIGTSTP, but it doesn't work. */ #if defined(SIGTSTP) && !defined(__BEOS__) out_flush(); /* needed to make cursor visible on some systems */ settmode(TMODE_COOK); out_flush(); /* needed to disable mouse on some systems */ # if defined(_REENTRANT) && defined(SIGCONT) sigcont_received = FALSE; # endif kill(0, SIGTSTP); /* send ourselves a STOP signal */ # if defined(_REENTRANT) && defined(SIGCONT) /* * Wait for the SIGCONT signal to be handled. It generally happens * immediately, but somehow not all the time. Do not call pause() * because there would be race condition which would hang Vim if * signal happened in between the test of sigcont_received and the * call to pause(). If signal is not yet received, call sleep(0) * to just yield CPU. Signal should then be received. If somehow * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting * further if signal is not received after 1+2+3+4 ms (not expected * to happen). */ { long wait_time; for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++) /* Loop is not entered most of the time */ os_delay(wait_time, FALSE); } # endif /* * Set oldtitle to NULL, so the current title is obtained again. */ vim_free(oldtitle); oldtitle = NULL; settmode(TMODE_RAW); need_check_timestamps = TRUE; did_check_timestamps = FALSE; #else suspend_shell(); #endif }
void TimerCheck() { int32_t stime, etime, diff; TEST_OK("Timer Init", os_time_init()); stime = os_get_time_in_usecs(); // One second delay os_delay(1000); etime = os_get_time_in_usecs(); // Should be at least 1s greater than stime; diff = etime - stime; printf("Start %ld, end %ld, diff %d\n", stime, etime, diff); TEST_OK("Delay approx correct", (diff < 1000000l || diff > 1010000l)); TEST_OK("Timer term", os_time_term()); }
void button_task(void) { uint8_t start = 0, stop = 0, pause = 0; os_semaphore_wait(&btn_sem); // Port A with no pull ups for buttons, input DDRA &= ~(0b01110000); os_semaphore_signal(&btn_sem); os_semaphore_wait(&lcd_sem); lcd_set_cursor(4, 0); lcd_putstr("Stopped"); os_semaphore_signal(&lcd_sem); while (1) { os_semaphore_wait(&btn_sem); if (!(PINA & 0b00010000)) { start = 1; } else { start = 0; } if (!(PINA & 0b00100000)) { pause = 1; } else { pause = 0; } if (!(PINA & 0b01000000)) { stop = 1; } else { stop = 0; } os_semaphore_signal(&btn_sem); if (state == 1 && pause == 1) { os_semaphore_wait(&btn_sem); pause = 0; os_semaphore_signal(&btn_sem); os_semaphore_wait(&stt_sem); state = 2; os_semaphore_signal(&stt_sem); os_semaphore_wait(&lcd_sem); lcd_set_cursor(4, 0); lcd_putstr("Paused "); os_semaphore_signal(&lcd_sem); } if (start) { os_semaphore_wait(&btn_sem); start = 0; os_semaphore_signal(&btn_sem); os_semaphore_wait(&stt_sem); state = 1; os_semaphore_signal(&stt_sem); os_semaphore_wait(&lcd_sem); lcd_set_cursor(4, 0); lcd_putstr("Running"); os_semaphore_signal(&lcd_sem); } if (stop) { os_semaphore_wait(&btn_sem); stop = 0; os_semaphore_signal(&btn_sem); os_semaphore_wait(&stt_sem); state = 0; os_semaphore_signal(&stt_sem); os_semaphore_wait(&lcd_sem); lcd_set_cursor(4, 0); lcd_putstr("Stopped"); os_semaphore_signal(&lcd_sem); os_semaphore_wait(&tck_sem); ticks = 0; os_semaphore_signal(&tck_sem); } os_delay(os_get_current_pid(), 50); } }
int os_inner_init(const char* title) { const char* display; struct utsname uts; struct sigaction term_action; struct sigaction quit_action; struct sigaction hup_action; struct sigaction pipe_action; #ifdef USE_SDL SDL_version compiled; #endif unsigned char endian[4] = { 0x1, 0x2, 0x3, 0x4 }; uint32 endian_little = 0x04030201; uint32 endian_big = 0x01020304; log_std(("os: os_inner_init\n")); if (uname(&uts) != 0) { log_std(("ERROR:os: uname failed\n")); } else { log_std(("os: sys %s\n", uts.sysname)); log_std(("os: release %s\n", uts.release)); log_std(("os: version %s\n", uts.version)); log_std(("os: machine %s\n", uts.machine)); } #if HAVE_SYSCONF #ifdef _SC_CLK_TCK log_std(("os: sysconf(_SC_CLK_TCK) %ld\n", sysconf(_SC_CLK_TCK))); #endif #ifdef _SC_NPROCESSORS_CONF log_std(("os: sysconf(_SC_NPROCESSORS_CONF) %ld\n", sysconf(_SC_NPROCESSORS_CONF))); #endif #ifdef _SC_NPROCESSORS_ONLN log_std(("os: sysconf(_SC_NPROCESSORS_ONLN) %ld\n", sysconf(_SC_NPROCESSORS_ONLN))); #endif #ifdef _SC_PHYS_PAGES log_std(("os: sysconf(_SC_PHYS_PAGES) %ld\n", sysconf(_SC_PHYS_PAGES))); #endif #ifdef _SC_AVPHYS_PAGES log_std(("os: sysconf(_SC_AVPHYS_PAGES) %ld\n", sysconf(_SC_AVPHYS_PAGES))); #endif #ifdef _SC_CHAR_BIT log_std(("os: sysconf(_SC_CHAR_BIT) %ld\n", sysconf(_SC_CHAR_BIT))); #endif #ifdef _SC_LONG_BIT log_std(("os: sysconf(_SC_LONG_BIT) %ld\n", sysconf(_SC_LONG_BIT))); #endif #ifdef _SC_WORD_BIT log_std(("os: sysconf(_SC_WORD_BIT) %ld\n", sysconf(_SC_WORD_BIT))); #endif #endif #ifdef _POSIX_PRIORITY_SCHEDULING /* OSDEF Check for POSIX scheduling */ log_std(("os: scheduling available\n")); #else log_std(("os: scheduling NOT available\n")); #endif /* print the compiler version */ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) /* OSDEF Detect compiler version */ #define COMPILER_RESOLVE(a) #a #define COMPILER(a, b, c) COMPILER_RESOLVE(a) "." COMPILER_RESOLVE(b) "." COMPILER_RESOLVE(c) log_std(("os: compiler GNU %s\n", COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__))); #else log_std(("os: compiler unknown\n")); #endif /* check for int size */ if (sizeof(uint8) != 1) { target_err("The program is compiled with invalid uint8 type.\n"); return -1; } if (sizeof(uint16) != 2) { target_err("The program is compiled with invalid uint16 type.\n"); return -1; } if (sizeof(uint32) != 4) { target_err("The program is compiled with invalid uint32 type.\n"); return -1; } if (sizeof(uint64) != 8) { target_err("The program is compiled with invalid uint64 type.\n"); return -1; } /* check for the endianess */ #ifdef USE_MSB log_std(("os: compiled big endian system\n")); if (memcmp(endian, &endian_big, 4) != 0) { target_err("The program is compiled as bigendian but system doesn't appear to be bigendian.\n"); return -1; } #endif #ifdef USE_LSB log_std(("os: compiled little endian system\n")); if (memcmp(endian, &endian_little, 4) != 0) { target_err("The program is compiled as littleendian but system doesn't appear to be littleendian.\n"); return -1; } #endif #ifdef USE_SMP /* check the thread support */ if (os_thread() != 0) { target_err("Error on the threading support.\n"); return -1; } #endif /* get DISPLAY environment variable */ display = getenv("DISPLAY"); if (display) log_std(("os: DISPLAY=%s\n", display)); else log_std(("os: DISPLAY undef\n")); /* probe the delay system */ os_delay(); if (!os_internal_wm_active()) { log_std(("os: save term\n")); if (tcgetattr(fileno(stdin), &OS.term) != 0) { log_std(("ERROR:os: error getting the tty state.\n")); OS.term_active = 0; } else { OS.term_active = 1; } } #if defined(USE_X) OS.x_active = 0; { int event_base, error_base; int major_version, minor_version; log_std(("os: XOpenDisplay()\n")); OS.dga_display = XOpenDisplay(0); if (OS.dga_display) { OS.x_active = 1; } else { log_std(("WARNING:os: XOpenDisplay() failed. All the X drivers will be disabled.\n")); } } #endif #if defined(USE_SVGALIB) OS.svgalib_active = 0; if (!os_internal_wm_active()) { int h; log_std(("os: open /dev/svga\n")); /* try opening the device, otherwise vga_init() will abort the program. */ h = open("/dev/svga", O_RDWR); if (h >= 0) { int res; close(h); vga_disabledriverreport(); /* check the version of the SVGALIB */ res = vga_setmode(-1); if (res < 0 || res < 0x1911) { /* 1.9.11 */ log_std(("WARNING:os: invalid SVGALIB version %x. All the SVGALIB drivers will be disabled.\n", (int)res)); /* don't print the message. It may be a normal condition. */ /* target_nfo("Invalid SVGALIB version, you need SVGALIB version 1.9.x or 2.0.x.\nPlease upgrade or recompile without SVGALIB support.\n"); */ } else { log_std(("os: vga_init()\n")); if (vga_init() != 0) { log_std(("os: vga_init() failed\n")); target_err("Error initializing the SVGALIB video support.\n"); return -1; } OS.svgalib_active = 1; } } else { log_std(("WARNING:os: open /dev/svga failed. All the SVGALIB drivers will be disabled.\n")); /* don't print the message. It may be a normal condition. */ /* target_nfo("Error opening the SVGALIB device /dev/svga.\n"); */ } } else { log_std(("WARNING:os: vga_init() skipped because X is active. All the SVGALIB drivers will be disabled.\n")); /* don't print the message. It may be a normal condition. */ /* target_nfo("SVGALIB not initialized because it's unusable in X.\n"); */ } #endif #if defined(USE_SDL) log_std(("os: SDL_Init(SDL_INIT_NOPARACHUTE)\n")); if (SDL_Init(SDL_INIT_NOPARACHUTE) != 0) { log_std(("os: SDL_Init() failed, %s\n", SDL_GetError())); target_err("Error initializing the SDL video support.\n"); return -1; } OS.sdl_active = 1; SDL_VERSION(&compiled); log_std(("os: compiled with sdl %d.%d.%d\n", compiled.major, compiled.minor, compiled.patch)); log_std(("os: linked with sdl %d.%d.%d\n", SDL_Linked_Version()->major, SDL_Linked_Version()->minor, SDL_Linked_Version()->patch)); #ifdef USE_MSB if (SDL_BYTEORDER != SDL_BIG_ENDIAN) { target_err("Invalid SDL endianess.\n"); return -1; } #endif #ifdef USE_LSB if (SDL_BYTEORDER != SDL_LIL_ENDIAN) { target_err("Invalid SDL endianess.\n"); return -1; } #endif #endif #if defined(USE_SLANG) OS.slang_active = 0; if (!os_internal_wm_active()) { log_std(("os: SLtt_get_terminfo()\n")); SLtt_get_terminfo(); log_std(("os: SLsmg_init_smg()\n")); SLsmg_init_smg(); OS.slang_active = 1; } else { log_std(("WARNING:os: SLang_init_tty() skipped because X is active. All the SLang drivers will be disabled.\n")); } #endif #if defined(USE_CURSES) OS.curses_active = 0; if (!os_internal_wm_active()) { log_std(("os: initscr()\n")); initscr(); start_color(); cbreak(); noecho(); nonl(); OS.curses_active = 1; } else { log_std(("WARNING:os: curses initscr() skipped because X is active. All the curses drivers will be disabled.\n")); } #endif /* set the titlebar */ sncpy(OS.title_buffer, sizeof(OS.title_buffer), title); /* set some signal handlers */ /* STANDARD signals */ term_action.sa_handler = (void (*)(int))os_signal; /* block external generated signals in the signal handler */ sigemptyset(&term_action.sa_mask); sigaddset(&term_action.sa_mask, SIGALRM); sigaddset(&term_action.sa_mask, SIGINT); sigaddset(&term_action.sa_mask, SIGTERM); sigaddset(&term_action.sa_mask, SIGHUP); sigaddset(&term_action.sa_mask, SIGQUIT); term_action.sa_flags = SA_RESTART | SA_SIGINFO; /* external generated */ sigaction(SIGALRM, &term_action, 0); sigaction(SIGINT, &term_action, 0); sigaction(SIGTERM, &term_action, 0); /* internal generated */ sigaction(SIGABRT, &term_action, 0); sigaction(SIGFPE, &term_action, 0); sigaction(SIGILL, &term_action, 0); sigaction(SIGSEGV, &term_action, 0); sigaction(SIGBUS, &term_action, 0); /* HUP signal */ hup_action.sa_handler = os_hup_signal; sigemptyset(&hup_action.sa_mask); hup_action.sa_flags = SA_RESTART; sigaction(SIGHUP, &hup_action, 0); /* QUIT signal */ quit_action.sa_handler = os_quit_signal; sigemptyset(&quit_action.sa_mask); quit_action.sa_flags = SA_RESTART; sigaction(SIGQUIT, &quit_action, 0); /* PIPE signal, ignoring it force some functions to */ /* return with error. It happen for example on the LCD sockets. */ pipe_action.sa_handler = SIG_IGN; sigemptyset(&pipe_action.sa_mask); pipe_action.sa_flags = SA_RESTART; sigaction(SIGPIPE, &pipe_action, 0); return 0; }