/* * ======================================================================== * Copyright 2006-2007 University of Washington * Copyright 2013-2022 Eduardo Chappa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * ======================================================================== */ #include #include #include "../headers.h" #include "../../pith/charconv/filesys.h" #include "tty.h" #include "signals.h" /* internal prototypes */ #ifndef _WINDOWS RETSIGTYPE do_hup_signal(int); #endif /* * picosigs - Install any handlers for the signals we're interested * in catching. */ void picosigs(void) { #ifndef _WINDOWS signal(SIGHUP, do_hup_signal); /* deal with SIGHUP */ signal(SIGTERM, do_hup_signal); /* deal with SIGTERM */ #ifdef SIGTSTP signal(SIGTSTP, SIG_DFL); #endif #if defined(SIGWINCH) && defined(TIOCGWINSZ) signal(SIGWINCH, winch_handler); /* window size changes */ #endif #endif /* !_WINDOWS */ } #ifndef _WINDOWS /* * do_hup_signal - jump back in the stack to where we can handle this */ RETSIGTYPE do_hup_signal(int sig) { signal(SIGHUP, SIG_IGN); /* ignore further SIGHUP's */ signal(SIGTERM, SIG_IGN); /* ignore further SIGTERM's */ if(Pmaster){ extern jmp_buf finstate; longjmp(finstate, COMP_GOTHUP); } else{ /* * if we've been interrupted and the buffer is changed, * save it... */ if(anycb() == TRUE){ /* time to save */ if(curbp->b_fname[0] == '\0'){ /* name it */ strncpy(curbp->b_fname, "pico.save", sizeof(curbp->b_fname)); curbp->b_fname[sizeof(curbp->b_fname)-1] = '\0'; } else{ strncat(curbp->b_fname, ".save", sizeof(curbp->b_fname)-strlen(curbp->b_fname)-1); curbp->b_fname[sizeof(curbp->b_fname)-1] = '\0'; } our_unlink(curbp->b_fname); writeout(curbp->b_fname, TRUE); } vttidy(); exit(1); } } #endif /* !_WINDOWS */ #if defined(SIGWINCH) && defined(TIOCGWINSZ) /* * winch_handler - handle window change signal */ RETSIGTYPE winch_handler(int sig) { int i = 0; signal(SIGWINCH, winch_handler); if(wheadp != NULL) ttresize(); else if (Pmaster){ i = Pmaster->arm_winch_cleanup; Pmaster->arm_winch_cleanup = 1; } if(Pmaster && Pmaster->winch_cleanup && Pmaster->arm_winch_cleanup) (*Pmaster->winch_cleanup)(); if(wheadp == NULL && Pmaster != NULL) Pmaster->arm_winch_cleanup = i; } #endif /* SIGWINCH and friends */ #ifdef POSIX_SIGNALS /*---------------------------------------------------------------------- Reset signals after critical imap code ----*/ void (*posix_signal(int sig_num, RETSIGTYPE (*action)(int)))(int) { struct sigaction new_action, old_action; memset((void *)&new_action, 0, sizeof(struct sigaction)); sigemptyset (&new_action.sa_mask); new_action.sa_handler = action; #ifdef SA_RESTART new_action.sa_flags = SA_RESTART; #else new_action.sa_flags = 0; #endif sigaction(sig_num, &new_action, &old_action); return(old_action.sa_handler); } int posix_sigunblock(int mask) { sigset_t sig_mask; sigemptyset(&sig_mask); sigaddset(&sig_mask, mask); #if HAVE_PTHREAD # define sigprocmask pthread_sigmask #endif return(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL)); } #endif /* POSIX_SIGNALS */ #if defined(sv3) || defined(ct) /* Placed by rll to handle the rename function not found in AT&T */ int rename(char *oldname, char *newname) { int rtn; char b[NLINE]; strncpy(b, fname_to_locale(oldname), sizeof(b)); b[sizeof(b)-1] = '\0'; if ((rtn = link(b, fname_to_locale(newname))) != 0) { perror("Was not able to rename file."); return(rtn); } if ((rtn = our_unlink(b)) != 0) perror("Was not able to unlink file."); return(rtn); } #endif