mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-06-14 04:21:24 +00:00
Don’t stuff keyboard input uselessly
Also, document stuffing better. * src/keyboard.c (stuff_buffered_input): Give up on stuffing if it fails. * src/sysdep.c (stuff_char): Return failure indication.
This commit is contained in:
parent
936472345d
commit
aed1c8b536
6 changed files with 42 additions and 49 deletions
|
|
@ -504,6 +504,8 @@ THINGS TO DO
|
||||||
** flow-ctrl.el must be updated.
|
** flow-ctrl.el must be updated.
|
||||||
|
|
||||||
** Fix stuff_char for multi-tty. Doesn't seem to be of high priority.
|
** Fix stuff_char for multi-tty. Doesn't seem to be of high priority.
|
||||||
|
For security reasons stuff_char does not work by default on many
|
||||||
|
platforms, which makes such a fix even lower priority.
|
||||||
|
|
||||||
DIARY OF CHANGES
|
DIARY OF CHANGES
|
||||||
----------------
|
----------------
|
||||||
|
|
|
||||||
|
|
@ -711,12 +711,11 @@ If @var{exit-data} is an integer, that is used as the exit status of
|
||||||
the Emacs process. (This is useful primarily in batch operation; see
|
the Emacs process. (This is useful primarily in batch operation; see
|
||||||
@ref{Batch Mode}.)
|
@ref{Batch Mode}.)
|
||||||
|
|
||||||
If @var{exit-data} is a string, its contents are stuffed into the
|
If @var{exit-data} is a string, its contents (followed by a newline) are
|
||||||
terminal input buffer so that the shell (or whatever program next reads
|
stuffed into the terminal input buffer so that the shell (or whatever
|
||||||
input) can read them. This is only possible on some systems. Note that
|
program next reads input) can read them. However, stuffing is silently
|
||||||
recent versions of GNU/Linux disable the system API required for
|
skipped if Emacs is not running interactively on a terminal, or if
|
||||||
stuffing the string into the terminal input, so this might not work on
|
stuffing requires special privileges or is not supported on this platform.
|
||||||
your system without special privileges.
|
|
||||||
|
|
||||||
If @var{exit-data} is neither an integer nor a string, or is omitted,
|
If @var{exit-data} is neither an integer nor a string, or is omitted,
|
||||||
that means to use the (system-specific) exit status which indicates
|
that means to use the (system-specific) exit status which indicates
|
||||||
|
|
@ -816,6 +815,9 @@ before suspending Emacs, or this function signals an error.
|
||||||
|
|
||||||
If @var{string} is non-@code{nil}, its characters are sent to Emacs's
|
If @var{string} is non-@code{nil}, its characters are sent to Emacs's
|
||||||
superior shell, to be read as terminal input.
|
superior shell, to be read as terminal input.
|
||||||
|
However, this action is skipped if Emacs is not running interactively on
|
||||||
|
a terminal, or if stuffing characters into the terminal input requires
|
||||||
|
special privileges or is not supported on this platform.
|
||||||
|
|
||||||
Before suspending, @code{suspend-emacs} runs the normal hook
|
Before suspending, @code{suspend-emacs} runs the normal hook
|
||||||
@code{suspend-hook}. After the user resumes Emacs,
|
@code{suspend-hook}. After the user resumes Emacs,
|
||||||
|
|
@ -840,7 +842,7 @@ Here is an example of how you could use these hooks:
|
||||||
@c The sit-for prevents the @code{nil} that suspend-emacs returns
|
@c The sit-for prevents the @code{nil} that suspend-emacs returns
|
||||||
@c hiding the message.
|
@c hiding the message.
|
||||||
|
|
||||||
Here is what you would see upon evaluating @code{(suspend-emacs "pwd")}:
|
Here is what you would see upon evaluating @code{(suspend-emacs)}:
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
@group
|
@group
|
||||||
|
|
@ -851,8 +853,6 @@ Really suspend? @kbd{y}
|
||||||
|
|
||||||
@group
|
@group
|
||||||
---------- Parent Shell ----------
|
---------- Parent Shell ----------
|
||||||
bash$ pwd
|
|
||||||
/home/username
|
|
||||||
bash$ fg
|
bash$ fg
|
||||||
@end group
|
@end group
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2947,9 +2947,9 @@ sort_args (int argc, char **argv)
|
||||||
DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 2, "P",
|
DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 2, "P",
|
||||||
doc: /* Exit the Emacs job and kill it.
|
doc: /* Exit the Emacs job and kill it.
|
||||||
If ARG is an integer, return ARG as the exit program code.
|
If ARG is an integer, return ARG as the exit program code.
|
||||||
If ARG is a string, stuff it as keyboard input. (This might
|
If ARG is a string, stuff it and then a newline as keyboard input,
|
||||||
not work on modern systems due to security considerations, or
|
if Emacs is running interactively on a terminal and the platform
|
||||||
not at all.)
|
supports and allows stuffing; this may need special privileges.
|
||||||
Any other value of ARG, or ARG omitted, means return an
|
Any other value of ARG, or ARG omitted, means return an
|
||||||
exit code that indicates successful program termination.
|
exit code that indicates successful program termination.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12421,19 +12421,15 @@ DEFUN ("suspend-emacs", Fsuspend_emacs, Ssuspend_emacs, 0, 1, "",
|
||||||
If `cannot-suspend' is non-nil, or if the system doesn't support job
|
If `cannot-suspend' is non-nil, or if the system doesn't support job
|
||||||
control, run a subshell instead.
|
control, run a subshell instead.
|
||||||
|
|
||||||
If optional arg STUFFSTRING is non-nil, its characters are stuffed
|
If optional arg STUFFSTRING is non-nil, stuff it and then a newline as
|
||||||
to be read as terminal input by Emacs's parent, after suspension.
|
keyboard input, if Emacs is running interactively on a terminal and the
|
||||||
|
platform supports and allows stuffing; this may need special privileges.
|
||||||
|
|
||||||
Before suspending, run the normal hook `suspend-hook'.
|
Before suspending, run the normal hook `suspend-hook'.
|
||||||
After resumption run the normal hook `suspend-resume-hook'.
|
After resumption run the normal hook `suspend-resume-hook'.
|
||||||
|
|
||||||
Some operating systems cannot stop the Emacs process and resume it later.
|
Some operating systems cannot stop the Emacs process and resume it later.
|
||||||
On such systems, Emacs starts a subshell instead of suspending.
|
On such systems, Emacs starts a subshell instead of suspending. */)
|
||||||
|
|
||||||
On some operating systems, stuffing characters into terminal input
|
|
||||||
buffer requires special privileges or is not supported at all.
|
|
||||||
On such systems, calling this function with non-nil STUFFSTRING might
|
|
||||||
either signal an error or silently fail to stuff the characters. */)
|
|
||||||
(Lisp_Object stuffstring)
|
(Lisp_Object stuffstring)
|
||||||
{
|
{
|
||||||
specpdl_ref count = SPECPDL_INDEX ();
|
specpdl_ref count = SPECPDL_INDEX ();
|
||||||
|
|
@ -12472,38 +12468,34 @@ either signal an error or silently fail to stuff the characters. */)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If STUFFSTRING is a string, stuff its contents as pending terminal input.
|
/* If STUFFSTRING is a string, stuff its contents and then a newline as
|
||||||
Then in any case stuff anything Emacs has read ahead and not used. */
|
pending terminal input. Then stuff anything Emacs has read ahead and
|
||||||
|
not used. However, do nothing if stuffing does not work. */
|
||||||
|
|
||||||
void
|
void
|
||||||
stuff_buffered_input (Lisp_Object stuffstring)
|
stuff_buffered_input (Lisp_Object stuffstring)
|
||||||
{
|
{
|
||||||
#ifdef SIGTSTP /* stuff_char is defined if SIGTSTP. */
|
#ifdef SIGTSTP /* stuff_char is defined if SIGTSTP. */
|
||||||
register unsigned char *p;
|
int bad_stuff = 0;
|
||||||
|
|
||||||
if (STRINGP (stuffstring))
|
if (STRINGP (stuffstring))
|
||||||
{
|
{
|
||||||
register ptrdiff_t count;
|
char *p = SSDATA (stuffstring);
|
||||||
|
for (ptrdiff_t i = SBYTES (stuffstring); !bad_stuff && 0 < i; i--)
|
||||||
p = SDATA (stuffstring);
|
bad_stuff = stuff_char (*p++);
|
||||||
count = SBYTES (stuffstring);
|
if (!bad_stuff)
|
||||||
while (count-- > 0)
|
bad_stuff = stuff_char ('\n');
|
||||||
stuff_char (*p++);
|
|
||||||
stuff_char ('\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Anything we have read ahead, put back for the shell to read. */
|
/* Anything we have read ahead, put back for the shell to read.
|
||||||
/* ?? What should this do when we have multiple keyboards??
|
When we have multiple keyboards, we should stuff everything back
|
||||||
Should we ignore anything that was typed in at the "wrong" kboard?
|
into the keyboard it came from, but fixing this is low priority as
|
||||||
|
many systems prohibit stuffing for security reasons. */
|
||||||
rms: we should stuff everything back into the kboard
|
|
||||||
it came from. */
|
|
||||||
for (; kbd_fetch_ptr != kbd_store_ptr;
|
for (; kbd_fetch_ptr != kbd_store_ptr;
|
||||||
kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr))
|
kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr))
|
||||||
{
|
{
|
||||||
|
if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT && !bad_stuff)
|
||||||
if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT)
|
bad_stuff = stuff_char (kbd_fetch_ptr->ie.code);
|
||||||
stuff_char (kbd_fetch_ptr->ie.code);
|
|
||||||
|
|
||||||
clear_event (&kbd_fetch_ptr->ie);
|
clear_event (&kbd_fetch_ptr->ie);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5280,7 +5280,7 @@ maybe_disable_address_randomization (int argc, char **argv)
|
||||||
extern int emacs_exec_file (char const *, char *const *, char *const *);
|
extern int emacs_exec_file (char const *, char *const *, char *const *);
|
||||||
extern void init_standard_fds (void);
|
extern void init_standard_fds (void);
|
||||||
extern char *emacs_get_current_dir_name (void);
|
extern char *emacs_get_current_dir_name (void);
|
||||||
extern void stuff_char (char c);
|
extern int stuff_char (char c);
|
||||||
extern void init_foreground_group (void);
|
extern void init_foreground_group (void);
|
||||||
extern void sys_subshell (void);
|
extern void sys_subshell (void);
|
||||||
extern void sys_suspend (void);
|
extern void sys_suspend (void);
|
||||||
|
|
|
||||||
17
src/sysdep.c
17
src/sysdep.c
|
|
@ -390,23 +390,22 @@ discard_tty_input (void)
|
||||||
|
|
||||||
/* Arrange for character C to be read as the next input from
|
/* Arrange for character C to be read as the next input from
|
||||||
the terminal.
|
the terminal.
|
||||||
|
Return 0 on success, -1 otherwise.
|
||||||
XXX What if we have multiple ttys?
|
XXX What if we have multiple ttys?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
int
|
||||||
stuff_char (char c)
|
stuff_char (char c)
|
||||||
{
|
{
|
||||||
if (! (FRAMEP (selected_frame)
|
|
||||||
&& FRAME_LIVE_P (XFRAME (selected_frame))
|
|
||||||
&& FRAME_TERMCAP_P (XFRAME (selected_frame))))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Should perhaps error if in batch mode */
|
/* Should perhaps error if in batch mode */
|
||||||
#ifdef TIOCSTI
|
#ifdef TIOCSTI
|
||||||
ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
|
if (FRAMEP (selected_frame)
|
||||||
#else /* no TIOCSTI */
|
&& FRAME_LIVE_P (XFRAME (selected_frame))
|
||||||
error ("Cannot stuff terminal input characters in this version of Unix");
|
&& FRAME_TERMCAP_P (XFRAME (selected_frame)))
|
||||||
|
return ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
|
||||||
#endif /* no TIOCSTI */
|
#endif /* no TIOCSTI */
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SIGTSTP */
|
#endif /* SIGTSTP */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue