/*---------------------------------------------------------------------- This checks whether or not a character (UNIX) is ready to be read, or it times out. Args: time_out -- number of seconds before it will timeout Result: Returns a NO_OP_IDLE or a NO_OP_COMMAND if the timeout expires before input is available, or a KEY_RESIZE if a resize event occurs, or READY_TO_READ if input is available before the timeout. ----*/ UCS check_for_timeout(int time_out) { UCS res = NO_OP_COMMAND; fflush(stdout); #if defined(SIGWINCH) && defined(TIOCGWINSZ) if(!winch_occured){ if(setjmp(winch_state) != 0){ winch_occured = 1; ready_for_winch = 0; /* * Need to unblock signal after longjmp from handler, because * signal is normally unblocked upon routine exit from the handler. */ our_sigunblock(SIGWINCH); } else ready_for_winch = 1; } if(winch_occured){ winch_occured = ready_for_winch = 0; fix_windsize(ps_global); return(KEY_RESIZE); } #endif /* SIGWINCH */ switch(res = input_ready(time_out)){ case BAIL_OUT: read_bail(); /* non-tragic exit */ /* NO RETURN */ case PANIC_NOW: panic1("Select error: %s\n", error_description(errno)); /* NO RETURN */ case READ_INTR: res = NO_OP_COMMAND; /* fall through */ case NO_OP_IDLE: case NO_OP_COMMAND: case READY_TO_READ: #if defined(SIGWINCH) && defined(TIOCGWINSZ) ready_for_winch = 0; #endif return(res); } /* not reachable */ return(res); }
int pine_simple_ttgetc(int (*fi)(int), void (*fv)(void)) { int ch; #if defined(SIGWINCH) && defined(TIOCGWINSZ) if(!winch_occured){ if(setjmp(winch_state) != 0){ winch_occured = 1; ready_for_winch = 0; /* * Need to unblock signal after longjmp from handler, because * signal is normally unblocked upon routine exit from the handler. */ our_sigunblock(SIGWINCH); } else ready_for_winch = 1; } if(winch_occured){ winch_occured = ready_for_winch = 0; fix_windsize(ps_global); return(KEY_RESIZE); } #endif /* SIGWINCH */ ch = simple_ttgetc(fi, fv); #if defined(SIGWINCH) && defined(TIOCGWINSZ) ready_for_winch = 0; #endif return(ch); }
/* * pipe_callback - handle pine-specific pipe setup like child * signal handler and possibly any display stuff * BUG: this function should probably be in a "alpine/pipe.c" */ void pipe_callback(PIPE_S *syspipe, int flags, void *data) { #ifdef _WINDOWS bitmap_t bitmap; #endif if(flags & OSB_PRE_OPEN) { dprint((5, "Opening pipe: (%s%s%s%s%s%s)\n", (syspipe->mode & PIPE_WRITE) ? "W":"", (syspipe->mode & PIPE_READ) ? "R":"", (syspipe->mode & PIPE_NOSHELL) ? "N":"", (syspipe->mode & PIPE_PROT) ? "P":"", (syspipe->mode & PIPE_USER) ? "U":"", (syspipe->mode & PIPE_RESET) ? "T":"")); #ifdef _WINDOWS q_status_message(SM_ORDER, 0, 0, "Waiting for called program to finish..."); flush_status_messages(1); setbitmap(bitmap); draw_keymenu(&pipe_cancel_keymenu, bitmap, ps_global->ttyo->screen_cols, 1-FOOTER_ROWS(ps_global), 0, FirstMenu); #else /* UNIX */ if(!(syspipe->mode & (PIPE_WRITE | PIPE_READ)) && !(syspipe->mode & PIPE_SILENT)) { flush_status_messages(0); /* just clean up display */ ClearScreen(); fflush(stdout); } if(syspipe->mode & PIPE_RESET) ttyfix(0); #ifdef SIGCHLD /* * Prepare for demise of child. Use SIGCHLD if it's available so * we can do useful things, like keep the IMAP stream alive, while * we're waiting on the child. The handler may have been changed by * something in the composer, in particular, by an alt_editor call. * So we need to re-set it to child_signal and then set it back * when we're done. */ child_signalled = child_jump = 0; syspipe->chld = signal(SIGCHLD, child_signal); #endif #endif /* UNIX */ } else if(flags & OSB_POST_OPEN) { #ifdef _WINDOWS clearfooter(ps_global); ps_global->mangled_footer = 1; if((int) data == -2) q_status_message1(SM_ORDER, 2, 3, "Ignoring completion of %s", syspipe->command); #else /* UNIX */ if(!(syspipe->mode & (PIPE_WRITE | PIPE_READ)) && !(syspipe->mode & PIPE_SILENT)) { ClearScreen(); ps_global->mangled_screen = 1; } if(syspipe->mode & PIPE_RESET) ttyfix(1); #ifdef SIGCHLD (void) signal(SIGCHLD, SIG_DFL); #endif #endif /* UNIX */ } else if(flags & OSB_PRE_CLOSE) { #ifdef SIGCHLD /* * this is here so close_system_pipe so it has something * to do while we're waiting on the other end of the * pipe to complete. When we're in the background for * a shell, the the side effect is pinging */ RETSIGTYPE (*alarm_sig)(); int old_cue = F_ON(F_SHOW_DELAY_CUE, ps_global); /* * remember the current SIGALRM handler, and make sure it's * installed when we're finished just in case the longjmp * out of the SIGCHLD handler caused sleep() to lose it. * Don't pay any attention to that man behind the curtain. */ alarm_sig = signal(SIGALRM, SIG_IGN); (void) F_SET(F_SHOW_DELAY_CUE, ps_global, 0); ps_global->noshow_timeout = 1; while(!child_signalled) { /* wake up and prod server */ if(!(syspipe->mode & PIPE_NONEWMAIL)) new_mail(0, 2, (syspipe->mode & PIPE_RESET) ? NM_NONE : NM_DEFER_SORT); if(!child_signalled) { if(setjmp(child_state) == 0) { child_jump = 1; /* prepare to wake up */ sleep(600); /* give it 5mins to happend */ } else our_sigunblock(SIGCHLD); } child_jump = 0; } ps_global->noshow_timeout = 0; F_SET(F_SHOW_DELAY_CUE, ps_global, old_cue); (void) signal(SIGALRM, alarm_sig); (void) signal(SIGCHLD, syspipe->chld); #endif } else if(flags & OSB_POST_CLOSE) { if(syspipe->mode & PIPE_RESET) /* restore our tty modes */ ttyfix(1); if(!(syspipe->mode & (PIPE_WRITE | PIPE_READ | PIPE_SILENT))) { ClearScreen(); /* No I/O to forked child */ ps_global->mangled_screen = 1; } } }