From b895642720aaf1d89e22c7cdda11990919622a72 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 10 Jan 2013 18:40:58 -0800 Subject: 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 --- src/ChangeLog | 14 ++++++++++++++ src/lisp.h | 2 ++ src/sysdep.c | 26 +++++++++++++++++++++++--- src/term.c | 31 ++++++++++++++++++------------- 4 files changed, 57 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index dd22c5388b0..f0d875b2027 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2013-01-11 Paul Eggert + + emacsclient -t should not suspend Emacs server (Bug#13387) + * 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. + 2013-01-10 Rainer Orth (tiny change) * 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); extern void sys_subshell (void); extern void sys_suspend (void); extern void discard_tty_input (void); +extern void block_tty_out_signal (void); +extern void unblock_tty_out_signal (void); extern void init_sys_modes (struct tty_display_info *); extern void reset_sys_modes (struct tty_display_info *); extern 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) inherited_pgroup = getpid () == pgrp ? 0 : pgrp; } +/* Block and unblock SIGTTOU. */ + +void +block_tty_out_signal (void) +{ +#ifdef SIGTTOU + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGTTOU); + pthread_sigmask (SIG_BLOCK, &blocked, 0); +#endif +} + +void +unblock_tty_out_signal (void) +{ +#ifdef SIGTTOU + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); +#endif +} + /* Safely set a controlling terminal FD's process group to PGID. If we are not in the foreground already, POSIX requires tcsetpgrp to deliver a SIGTTOU signal, which would stop us. This is an @@ -725,11 +746,10 @@ static void tcsetpgrp_without_stopping (int fd, pid_t pgid) { #ifdef SIGTTOU - signal_handler_t handler; block_input (); - handler = signal (SIGTTOU, SIG_IGN); + block_tty_out_signal (); tcsetpgrp (fd, pgid); - signal (SIGTTOU, handler); + unblock_tty_out_signal (); unblock_input (); #endif } 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). */) if (fd == -1) error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno)); - if (strcmp (t->display_info.tty->name, DEV_TTY)) + if (!O_IGNORE_CTTY && strcmp (t->display_info.tty->name, DEV_TTY) != 0) dissociate_if_controlling_tty (fd); t->display_info.tty->output = fdopen (fd, "w+"); @@ -2903,13 +2903,23 @@ set_tty_hooks (struct terminal *terminal) terminal->delete_terminal_hook = &delete_tty; } -/* Drop the controlling terminal if fd is the same device. */ +/* If FD is the controlling terminal, drop it. */ static void dissociate_if_controlling_tty (int fd) { - pid_t pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ - if (0 <= pgid) - setsid (); + /* If tcgetpgrp succeeds, fd is the controlling terminal, + so dissociate it by invoking setsid. */ + if (0 <= tcgetpgrp (fd) && setsid () < 0) + { +#ifdef TIOCNOTTY + /* setsid failed, presumably because Emacs is already a process + group leader. Fall back on the obsolescent way to dissociate + a controlling tty. */ + block_tty_out_signal (); + ioctl (fd, TIOCNOTTY, 0); + unblock_tty_out_signal (); +#endif + } } /* 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) /* On some systems, tgetent tries to access the controlling terminal. */ - { - sigset_t blocked; - sigemptyset (&blocked); - sigaddset (&blocked, SIGTTOU); - pthread_sigmask (SIG_BLOCK, &blocked, 0); - status = tgetent (tty->termcap_term_buffer, terminal_type); - pthread_sigmask (SIG_UNBLOCK, &blocked, 0); - } + block_tty_out_signal (); + status = tgetent (tty->termcap_term_buffer, terminal_type); + unblock_tty_out_signal (); if (status < 0) { -- cgit v1.2.1 From 6020559a093bf243be6cd6a866933b4368ea67cc Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 11 Jan 2013 17:25:10 +0400 Subject: Avoid unnecessary byte position calculation for the gap movement. Since all users of move_gap do CHAR_TO_BYTE for other purposes anyway, all of them should use move_gap_both instead. * lisp.h (move_gap): Remove prototype. * insdel.c (move_gap): Remove. (move_gap_both): Add eassert. * editfns.c (Ftranspose_regions): Tweak to use move_gap_both. * xml.c (parse_region): Likewise. --- src/ChangeLog | 11 +++++++++++ src/editfns.c | 12 +++++++----- src/insdel.c | 11 ++--------- src/lisp.h | 1 - src/xml.c | 17 ++++++++--------- 5 files changed, 28 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index f0d875b2027..13a1f1a3858 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2013-01-11 Dmitry Antipov + + Avoid unnecessary byte position calculation for the gap movement. + Since all users of move_gap do CHAR_TO_BYTE for other purposes + anyway, all of them should use move_gap_both instead. + * lisp.h (move_gap): Remove prototype. + * insdel.c (move_gap): Remove. + (move_gap_both): Add eassert. + * editfns.c (Ftranspose_regions): Tweak to use move_gap_both. + * xml.c (parse_region): Likewise. + 2013-01-11 Paul Eggert emacsclient -t should not suspend Emacs server (Bug#13387) diff --git a/src/editfns.c b/src/editfns.c index 26dfdac3ba8..64269bab8df 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -4522,7 +4522,7 @@ Transposing beyond buffer boundaries is an error. */) (Lisp_Object startr1, Lisp_Object endr1, Lisp_Object startr2, Lisp_Object endr2, Lisp_Object leave_markers) { register ptrdiff_t start1, end1, start2, end2; - ptrdiff_t start1_byte, start2_byte, len1_byte, len2_byte; + ptrdiff_t start1_byte, start2_byte, len1_byte, len2_byte, end2_byte; ptrdiff_t gap, len1, len_mid, len2; unsigned char *start1_addr, *start2_addr, *temp; @@ -4583,20 +4583,22 @@ Transposing beyond buffer boundaries is an error. */) the gap the minimum distance to get it out of the way, and then deal with an unbroken array. */ + start1_byte = CHAR_TO_BYTE (start1); + end2_byte = CHAR_TO_BYTE (end2); + /* Make sure the gap won't interfere, by moving it out of the text we will operate on. */ if (start1 < gap && gap < end2) { if (gap - start1 < end2 - gap) - move_gap (start1); + move_gap_both (start1, start1_byte); else - move_gap (end2); + move_gap_both (end2, end2_byte); } - start1_byte = CHAR_TO_BYTE (start1); start2_byte = CHAR_TO_BYTE (start2); len1_byte = CHAR_TO_BYTE (end1) - start1_byte; - len2_byte = CHAR_TO_BYTE (end2) - start2_byte; + len2_byte = end2_byte - start2_byte; #ifdef BYTE_COMBINING_DEBUG if (end1 == start2) diff --git a/src/insdel.c b/src/insdel.c index 905249d6714..c2a3cd42821 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -84,21 +84,14 @@ check_markers (void) #endif /* MARKER_DEBUG */ -/* Move gap to position CHARPOS. - Note that this can quit! */ - -void -move_gap (ptrdiff_t charpos) -{ - move_gap_both (charpos, CHAR_TO_BYTE (charpos)); -} - /* Move gap to byte position BYTEPOS, which is also char position CHARPOS. Note that this can quit! */ void move_gap_both (ptrdiff_t charpos, ptrdiff_t bytepos) { + eassert (charpos == BYTE_TO_CHAR (bytepos) + && bytepos == CHAR_TO_BYTE (charpos)); if (bytepos < GPT_BYTE) gap_left (charpos, bytepos, 0); else if (bytepos > GPT_BYTE) diff --git a/src/lisp.h b/src/lisp.h index 3200127881b..22e0a188e4b 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2775,7 +2775,6 @@ extern void syms_of_image (void); /* Defined in insdel.c. */ extern Lisp_Object Qinhibit_modification_hooks; -extern void move_gap (ptrdiff_t); extern void move_gap_both (ptrdiff_t, ptrdiff_t); extern _Noreturn void buffer_overflow (void); extern void make_gap (ptrdiff_t); diff --git a/src/xml.c b/src/xml.c index 5939c58a564..5a52b0c2a1e 100644 --- a/src/xml.c +++ b/src/xml.c @@ -180,8 +180,7 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html xmlDoc *doc; Lisp_Object result = Qnil; const char *burl = ""; - ptrdiff_t bytes; - ptrdiff_t istart, iend; + ptrdiff_t istart, iend, istart_byte, iend_byte; fn_xmlCheckVersion (LIBXML_VERSION); @@ -189,9 +188,11 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html istart = XINT (start); iend = XINT (end); + istart_byte = CHAR_TO_BYTE (istart); + iend_byte = CHAR_TO_BYTE (iend); if (istart < GPT && GPT < iend) - move_gap (iend); + move_gap_both (iend, iend_byte); if (! NILP (base_url)) { @@ -199,17 +200,15 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html burl = SSDATA (base_url); } - bytes = CHAR_TO_BYTE (iend) - CHAR_TO_BYTE (istart); - if (htmlp) - doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), - bytes, burl, "utf-8", + doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (istart_byte), + iend_byte - istart_byte, burl, "utf-8", HTML_PARSE_RECOVER|HTML_PARSE_NONET| HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR| HTML_PARSE_NOBLANKS); else - doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), - bytes, burl, "utf-8", + doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (istart_byte), + iend_byte - istart_byte, burl, "utf-8", XML_PARSE_NONET|XML_PARSE_NOWARNING| XML_PARSE_NOBLANKS |XML_PARSE_NOERROR); -- cgit v1.2.1