aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-01-10 18:40:58 -0800
committerPaul Eggert2013-01-10 18:40:58 -0800
commitb895642720aaf1d89e22c7cdda11990919622a72 (patch)
tree319a9a095ad702cbb7c93eb0a127444fd7874805 /src
parenta778dd57d0da9004a72320f8082d4f6220f178e2 (diff)
downloademacs-b895642720aaf1d89e22c7cdda11990919622a72.tar.gz
emacs-b895642720aaf1d89e22c7cdda11990919622a72.zip
emacsclient -t should not suspend Emacs server
* lisp.h, sysdep.c (block_tty_out_signal, unblock_tty_out_signal): New functions. * term.c (init_tty): Use them instead of rolling our own code. * sysdep.c (tcsetpgrp_without_stopping): Likewise. Here, this switches from 'signal' to 'pthread_sigmask', which is safer in multithreaded applications. * term.c (Fresume_tty): Don't bother dissociating if O_IGNORE_CTTY, which has already arranged for that. (dissociate_if_controlling_tty): If setsid fails, fall back on TIOCNOTTY. This is the main part of the bug fix. Fixes: debbugs:13387
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/lisp.h2
-rw-r--r--src/sysdep.c26
-rw-r--r--src/term.c31
4 files changed, 57 insertions, 16 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index dd22c5388b0..f0d875b2027 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12013-01-11 Paul Eggert <eggert@cs.ucla.edu>
2
3 emacsclient -t should not suspend Emacs server (Bug#13387)
4 * lisp.h, sysdep.c (block_tty_out_signal, unblock_tty_out_signal):
5 New functions.
6 * term.c (init_tty): Use them instead of rolling our own code.
7 * sysdep.c (tcsetpgrp_without_stopping): Likewise. Here, this
8 switches from 'signal' to 'pthread_sigmask', which is safer in
9 multithreaded applications.
10 * term.c (Fresume_tty): Don't bother dissociating if O_IGNORE_CTTY,
11 which has already arranged for that.
12 (dissociate_if_controlling_tty): If setsid fails, fall back on TIOCNOTTY.
13 This is the main part of the bug fix.
14
12013-01-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> (tiny change) 152013-01-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> (tiny change)
2 16
3 * gtkutil.c (xg_initialize): Add ifdef HAVE_FREETYPE around 17 * gtkutil.c (xg_initialize): Add ifdef HAVE_FREETYPE around
diff --git a/src/lisp.h b/src/lisp.h
index 8db61d3623a..3200127881b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3462,6 +3462,8 @@ extern void init_sigio (int);
3462extern void sys_subshell (void); 3462extern void sys_subshell (void);
3463extern void sys_suspend (void); 3463extern void sys_suspend (void);
3464extern void discard_tty_input (void); 3464extern void discard_tty_input (void);
3465extern void block_tty_out_signal (void);
3466extern void unblock_tty_out_signal (void);
3465extern void init_sys_modes (struct tty_display_info *); 3467extern void init_sys_modes (struct tty_display_info *);
3466extern void reset_sys_modes (struct tty_display_info *); 3468extern void reset_sys_modes (struct tty_display_info *);
3467extern void init_all_sys_modes (void); 3469extern void init_all_sys_modes (void);
diff --git a/src/sysdep.c b/src/sysdep.c
index 049eb85afe5..158d2f73eec 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -714,6 +714,27 @@ init_foreground_group (void)
714 inherited_pgroup = getpid () == pgrp ? 0 : pgrp; 714 inherited_pgroup = getpid () == pgrp ? 0 : pgrp;
715} 715}
716 716
717/* Block and unblock SIGTTOU. */
718
719void
720block_tty_out_signal (void)
721{
722#ifdef SIGTTOU
723 sigset_t blocked;
724 sigemptyset (&blocked);
725 sigaddset (&blocked, SIGTTOU);
726 pthread_sigmask (SIG_BLOCK, &blocked, 0);
727#endif
728}
729
730void
731unblock_tty_out_signal (void)
732{
733#ifdef SIGTTOU
734 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
735#endif
736}
737
717/* Safely set a controlling terminal FD's process group to PGID. 738/* Safely set a controlling terminal FD's process group to PGID.
718 If we are not in the foreground already, POSIX requires tcsetpgrp 739 If we are not in the foreground already, POSIX requires tcsetpgrp
719 to deliver a SIGTTOU signal, which would stop us. This is an 740 to deliver a SIGTTOU signal, which would stop us. This is an
@@ -725,11 +746,10 @@ static void
725tcsetpgrp_without_stopping (int fd, pid_t pgid) 746tcsetpgrp_without_stopping (int fd, pid_t pgid)
726{ 747{
727#ifdef SIGTTOU 748#ifdef SIGTTOU
728 signal_handler_t handler;
729 block_input (); 749 block_input ();
730 handler = signal (SIGTTOU, SIG_IGN); 750 block_tty_out_signal ();
731 tcsetpgrp (fd, pgid); 751 tcsetpgrp (fd, pgid);
732 signal (SIGTTOU, handler); 752 unblock_tty_out_signal ();
733 unblock_input (); 753 unblock_input ();
734#endif 754#endif
735} 755}
diff --git a/src/term.c b/src/term.c
index d76562bb4db..f66a0bddc33 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2423,7 +2423,7 @@ frame's terminal). */)
2423 if (fd == -1) 2423 if (fd == -1)
2424 error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno)); 2424 error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno));
2425 2425
2426 if (strcmp (t->display_info.tty->name, DEV_TTY)) 2426 if (!O_IGNORE_CTTY && strcmp (t->display_info.tty->name, DEV_TTY) != 0)
2427 dissociate_if_controlling_tty (fd); 2427 dissociate_if_controlling_tty (fd);
2428 2428
2429 t->display_info.tty->output = fdopen (fd, "w+"); 2429 t->display_info.tty->output = fdopen (fd, "w+");
@@ -2903,13 +2903,23 @@ set_tty_hooks (struct terminal *terminal)
2903 terminal->delete_terminal_hook = &delete_tty; 2903 terminal->delete_terminal_hook = &delete_tty;
2904} 2904}
2905 2905
2906/* Drop the controlling terminal if fd is the same device. */ 2906/* If FD is the controlling terminal, drop it. */
2907static void 2907static void
2908dissociate_if_controlling_tty (int fd) 2908dissociate_if_controlling_tty (int fd)
2909{ 2909{
2910 pid_t pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ 2910 /* If tcgetpgrp succeeds, fd is the controlling terminal,
2911 if (0 <= pgid) 2911 so dissociate it by invoking setsid. */
2912 setsid (); 2912 if (0 <= tcgetpgrp (fd) && setsid () < 0)
2913 {
2914#ifdef TIOCNOTTY
2915 /* setsid failed, presumably because Emacs is already a process
2916 group leader. Fall back on the obsolescent way to dissociate
2917 a controlling tty. */
2918 block_tty_out_signal ();
2919 ioctl (fd, TIOCNOTTY, 0);
2920 unblock_tty_out_signal ();
2921#endif
2922 }
2913} 2923}
2914 2924
2915/* Create a termcap display on the tty device with the given name and 2925/* Create a termcap display on the tty device with the given name and
@@ -3030,14 +3040,9 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3030 3040
3031 /* On some systems, tgetent tries to access the controlling 3041 /* On some systems, tgetent tries to access the controlling
3032 terminal. */ 3042 terminal. */
3033 { 3043 block_tty_out_signal ();
3034 sigset_t blocked; 3044 status = tgetent (tty->termcap_term_buffer, terminal_type);
3035 sigemptyset (&blocked); 3045 unblock_tty_out_signal ();
3036 sigaddset (&blocked, SIGTTOU);
3037 pthread_sigmask (SIG_BLOCK, &blocked, 0);
3038 status = tgetent (tty->termcap_term_buffer, terminal_type);
3039 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
3040 }
3041 3046
3042 if (status < 0) 3047 if (status < 0)
3043 { 3048 {