mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-12 01:42:37 -07: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.
|
||||
|
||||
** 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
|
||||
----------------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
@ref{Batch Mode}.)
|
||||
|
||||
If @var{exit-data} is a string, its contents are stuffed into the
|
||||
terminal input buffer so that the shell (or whatever program next reads
|
||||
input) can read them. This is only possible on some systems. Note that
|
||||
recent versions of GNU/Linux disable the system API required for
|
||||
stuffing the string into the terminal input, so this might not work on
|
||||
your system without special privileges.
|
||||
If @var{exit-data} is a string, its contents (followed by a newline) are
|
||||
stuffed into the terminal input buffer so that the shell (or whatever
|
||||
program next reads input) can read them. However, stuffing is silently
|
||||
skipped if Emacs is not running interactively on a terminal, or if
|
||||
stuffing requires special privileges or is not supported on this platform.
|
||||
|
||||
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
|
||||
|
|
@ -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
|
||||
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
|
||||
@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 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
|
||||
@group
|
||||
|
|
@ -851,8 +853,6 @@ Really suspend? @kbd{y}
|
|||
|
||||
@group
|
||||
---------- Parent Shell ----------
|
||||
bash$ pwd
|
||||
/home/username
|
||||
bash$ fg
|
||||
@end group
|
||||
|
||||
|
|
|
|||
|
|
@ -2947,9 +2947,9 @@ sort_args (int argc, char **argv)
|
|||
DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 2, "P",
|
||||
doc: /* Exit the Emacs job and kill it.
|
||||
If ARG is an integer, return ARG as the exit program code.
|
||||
If ARG is a string, stuff it as keyboard input. (This might
|
||||
not work on modern systems due to security considerations, or
|
||||
not at all.)
|
||||
If ARG is a string, stuff it and then a newline as keyboard input,
|
||||
if Emacs is running interactively on a terminal and the platform
|
||||
supports and allows stuffing; this may need special privileges.
|
||||
Any other value of ARG, or ARG omitted, means return an
|
||||
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
|
||||
control, run a subshell instead.
|
||||
|
||||
If optional arg STUFFSTRING is non-nil, its characters are stuffed
|
||||
to be read as terminal input by Emacs's parent, after suspension.
|
||||
If optional arg STUFFSTRING is non-nil, stuff it and then a newline as
|
||||
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'.
|
||||
After resumption run the normal hook `suspend-resume-hook'.
|
||||
|
||||
Some operating systems cannot stop the Emacs process and resume it later.
|
||||
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. */)
|
||||
On such systems, Emacs starts a subshell instead of suspending. */)
|
||||
(Lisp_Object stuffstring)
|
||||
{
|
||||
specpdl_ref count = SPECPDL_INDEX ();
|
||||
|
|
@ -12472,38 +12468,34 @@ either signal an error or silently fail to stuff the characters. */)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
/* If STUFFSTRING is a string, stuff its contents as pending terminal input.
|
||||
Then in any case stuff anything Emacs has read ahead and not used. */
|
||||
/* If STUFFSTRING is a string, stuff its contents and then a newline as
|
||||
pending terminal input. Then stuff anything Emacs has read ahead and
|
||||
not used. However, do nothing if stuffing does not work. */
|
||||
|
||||
void
|
||||
stuff_buffered_input (Lisp_Object stuffstring)
|
||||
{
|
||||
#ifdef SIGTSTP /* stuff_char is defined if SIGTSTP. */
|
||||
register unsigned char *p;
|
||||
int bad_stuff = 0;
|
||||
|
||||
if (STRINGP (stuffstring))
|
||||
{
|
||||
register ptrdiff_t count;
|
||||
|
||||
p = SDATA (stuffstring);
|
||||
count = SBYTES (stuffstring);
|
||||
while (count-- > 0)
|
||||
stuff_char (*p++);
|
||||
stuff_char ('\n');
|
||||
char *p = SSDATA (stuffstring);
|
||||
for (ptrdiff_t i = SBYTES (stuffstring); !bad_stuff && 0 < i; i--)
|
||||
bad_stuff = stuff_char (*p++);
|
||||
if (!bad_stuff)
|
||||
bad_stuff = stuff_char ('\n');
|
||||
}
|
||||
|
||||
/* Anything we have read ahead, put back for the shell to read. */
|
||||
/* ?? What should this do when we have multiple keyboards??
|
||||
Should we ignore anything that was typed in at the "wrong" kboard?
|
||||
|
||||
rms: we should stuff everything back into the kboard
|
||||
it came from. */
|
||||
/* Anything we have read ahead, put back for the shell to read.
|
||||
When we have multiple keyboards, we should stuff everything back
|
||||
into the keyboard it came from, but fixing this is low priority as
|
||||
many systems prohibit stuffing for security reasons. */
|
||||
for (; kbd_fetch_ptr != kbd_store_ptr;
|
||||
kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr))
|
||||
{
|
||||
|
||||
if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT)
|
||||
stuff_char (kbd_fetch_ptr->ie.code);
|
||||
if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT && !bad_stuff)
|
||||
bad_stuff = stuff_char (kbd_fetch_ptr->ie.code);
|
||||
|
||||
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 void init_standard_fds (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 sys_subshell (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
|
||||
the terminal.
|
||||
Return 0 on success, -1 otherwise.
|
||||
XXX What if we have multiple ttys?
|
||||
*/
|
||||
|
||||
void
|
||||
int
|
||||
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 */
|
||||
#ifdef TIOCSTI
|
||||
ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
|
||||
#else /* no TIOCSTI */
|
||||
error ("Cannot stuff terminal input characters in this version of Unix");
|
||||
if (FRAMEP (selected_frame)
|
||||
&& FRAME_LIVE_P (XFRAME (selected_frame))
|
||||
&& FRAME_TERMCAP_P (XFRAME (selected_frame)))
|
||||
return ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
|
||||
#endif /* no TIOCSTI */
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* SIGTSTP */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue