]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/tty/lib_tstp.c
ncurses 5.0
[ncurses.git] / ncurses / tty / lib_tstp.c
similarity index 85%
rename from ncurses/lib_tstp.c
rename to ncurses/tty/lib_tstp.c
index 0fb8b848986c3f6b2748d62195fea2e59746e28a..6fb912cf5096d2bd7ef3b988d146d05df886ceb9 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998 Free Software Foundation, Inc.                        *
+ * Copyright (c) 1998,1999 Free Software Foundation, Inc.                   *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
 #define _POSIX_SOURCE
 #endif
 
-MODULE_ID("$Id: lib_tstp.c,v 1.15 1998/02/11 12:13:57 tom Exp $")
+MODULE_ID("$Id: lib_tstp.c,v 1.20 1999/10/22 23:11:09 tom Exp $")
+
+#if defined(SIGTSTP) && (HAVE_SIGACTION || HAVE_SIGVEC)
+#define USE_SIGTSTP 1
+#else
+#define USE_SIGTSTP 0
+#endif
 
 /*
  * Note: This code is fragile!  Its problem is that different OSs
@@ -93,18 +99,32 @@ MODULE_ID("$Id: lib_tstp.c,v 1.15 1998/02/11 12:13:57 tom Exp $")
  * the future.  If nothing else, it's simpler...
  */
 
-#ifdef SIGTSTP
+#if USE_SIGTSTP
 static void tstp(int dummy GCC_UNUSED)
 {
        sigset_t mask, omask;
        sigaction_t act, oact;
 
+#ifdef SIGTTOU
+       int sigttou_blocked;
+#endif
+
        T(("tstp() called"));
 
        /*
         * The user may have changed the prog_mode tty bits, so save them.
+        *
+        * But first try to detect whether we still are in the foreground
+        * process group - if not, an interactive shell may already have
+        * taken ownership of the tty and modified the settings when our
+        * parent was stopped before us, and we would likely pick up the
+        * settings already modified by the shell.
         */
-       def_prog_mode();
+       if (SP != 0 && !SP->_endwin) /* don't do this if we're not in curses */
+#if HAVE_TCGETPGRP
+       if (tcgetpgrp(STDIN_FILENO) == getpgrp())
+#endif
+           def_prog_mode();
 
        /*
         * Block window change and timer signals.  The latter
@@ -118,6 +138,15 @@ static void tstp(int dummy GCC_UNUSED)
 #endif
        (void)sigprocmask(SIG_BLOCK, &mask, &omask);
 
+#ifdef SIGTTOU
+       sigttou_blocked = sigismember(&omask, SIGTTOU);
+       if (!sigttou_blocked) {
+           (void)sigemptyset(&mask);
+           (void)sigaddset(&mask, SIGTTOU);
+           (void)sigprocmask(SIG_BLOCK, &mask, NULL);
+       }
+#endif
+
        /*
         * End window mode, which also resets the terminal state to the
         * original (pre-curses) modes.
@@ -127,6 +156,12 @@ static void tstp(int dummy GCC_UNUSED)
        /* Unblock SIGTSTP. */
        (void)sigemptyset(&mask);
        (void)sigaddset(&mask, SIGTSTP);
+#ifdef SIGTTOU
+       if (!sigttou_blocked) {
+            /* Unblock this too if it wasn't blocked on entry */
+           (void)sigaddset(&mask, SIGTTOU);
+       }
+#endif
        (void)sigprocmask(SIG_UNBLOCK, &mask, NULL);
 
        /* Now we want to resend SIGSTP to this process and suspend it */
@@ -160,17 +195,20 @@ static void tstp(int dummy GCC_UNUSED)
        /* Reset the signals. */
        (void)sigprocmask(SIG_SETMASK, &omask, NULL);
 }
-#endif /* defined(SIGTSTP) */
+#endif /* USE_SIGTSTP */
 
 static void cleanup(int sig)
 {
+       static int nested;
+
        /*
         * Actually, doing any sort of I/O from within an signal handler is
         * "unsafe".  But we'll _try_ to clean up the screen and terminal
         * settings on the way out.
         */
-       if (sig == SIGINT
-        || sig == SIGQUIT) {
+       if (!nested++
+        && (sig == SIGINT
+         || sig == SIGQUIT)) {
 #if HAVE_SIGACTION || HAVE_SIGVEC
                sigaction_t act;
                sigemptyset(&act.sa_mask);
@@ -184,9 +222,15 @@ static void cleanup(int sig)
                    SCREEN *scan = _nc_screen_chain;
                    while(scan)
                    {
+                       if (SP != 0
+                       && SP->_ofp != 0
+                       && isatty(fileno(SP->_ofp))) {
+                           SP->_cleanup = TRUE;
+                       }
                        set_term(scan);
                        endwin();
-                       SP->_endwin = FALSE; /* in case we have an atexit! */
+                       if (SP)
+                           SP->_endwin = FALSE; /* in case we have an atexit! */
                        scan = scan->_next_screen;
                    }
                }
@@ -227,9 +271,9 @@ static int CatchIfDefault(int sig, sigaction_t *act)
        return FALSE;
 }
 #else
-static int CatchIfDefault(int sig, RETSIGTYPE (*handler)())
+static int CatchIfDefault(int sig, RETSIGTYPE (*handler)(int))
 {
-       void    (*ohandler)();
+       void    (*ohandler)(int);
 
        ohandler = signal(sig, SIG_IGN);
        if (ohandler == SIG_DFL
@@ -259,7 +303,7 @@ static int CatchIfDefault(int sig, RETSIGTYPE (*handler)())
  */
 void _nc_signal_handler(bool enable)
 {
-#ifdef SIGTSTP         /* Xenix 2.x doesn't have this */
+#if USE_SIGTSTP                /* Xenix 2.x doesn't have SIGTSTP, for example */
 static sigaction_t act, oact;
 static int ignore;
 
@@ -295,7 +339,7 @@ static int ignore;
                                ignore = TRUE;
                }
        }
-#else /* !SIGTSTP */
+#else /* !USE_SIGTSTP */
        if (enable)
        {
 #if HAVE_SIGACTION || HAVE_SIGVEC
@@ -321,5 +365,5 @@ static int ignore;
 #endif
 #endif /* !(HAVE_SIGACTION || HAVE_SIGVEC) */
        }
-#endif /* !SIGTSTP */
+#endif /* !USE_SIGTSTP */
 }