Commit 16c290d8 authored by Karoly Lorentey's avatar Karoly Lorentey

Major bugfixes and slight enhancements.

src/dispextern.h (get_tty_size, tabs_safe_p, init_baud_rate): Update
prototypes.

src/dispnew.c (window_change_signal): Update call to get_tty_size.
src/frame.c (Fmake_terminal_frame): Ditto.
src/keyboard.c (Fsuspend_emacs): Ditto.

src/sysdep.c: Eliminate tty_outputs, wherever possible.  (The
exceptions are init_sys_modes and reset_sys_modes, which need access
to tty-local parameters).
(init_baud_rate): Change tty_output parameter to a simple file descriptor.
(narrow_foreground_group, widen_foreground_group): Ditto.
(tabs_safe_p, get_tty_size): Ditto.
(init_sys_modes): Update narrow_foreground_group invocation.
(reset_sys_modes): Update widen_foreground_group invocation.
(request_sigio)[!FASYNC && STRIDE]: Fix function signature.

src/term.c (delete_tty): Only close output file handle if it is
different from input.  Re-enable freeing of Wcm.
(term_init): Update get_tty_size, tabs_safe_p and init_baud_rate
invocations.

lib-src/emacsclient.c (here): Renamed to frame.
(longopts): Change --here to --frame.  The -h short option may be
confused with --help.
(decode_options, print_help_and_exit): Update to reflect above changes.
(main): Ditto.

lisp/server.el (server-start): Fix frame-live-p call syntax.
(server-process-filter): Handle 'emacsclient -f' without file
arguments.  Don't return any values to emacsclient when 'emacsclient
-f -e'.
(server-switch-buffer): Prevent infinite recursion when there are no
files to edit.


git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-27
parent 9d9f1812
......@@ -39,7 +39,7 @@ commands:
then start up the emacs server (src/emacs, M-x server-start), and then
(from a shell prompt on another terminal) start emacsclient with
lib-src/emacsclient -h /optional/file/names...
lib-src/emacsclient -f /optional/file/names...
You'll hopefully have two fully working, independent frames on
separate terminals. (This seems to be very useful, emacsclient starts
......@@ -213,13 +213,7 @@ DIARY OF CHANGES
(Seems to be working OK.)
THINGS TO DO
------------
** Understand Emacs's low-level input system. It seems
complicated. :-)
** Fix mysterious memory corruption error with tty deletion. To
-- Fix mysterious memory corruption error with tty deletion. To
trigger it, try the following shell command:
while true; do TERM=no-such-terminal-definition emacsclient -h; done
......@@ -230,17 +224,23 @@ THINGS TO DO
Why were these vars collected into a struct before multi-tty
support?)
The bug does not seem to happen if the error occurs before terminal
initialization or if I comment out all xfree()s in delete_frame.
Update: yes it does, although it is much rarer. Or maybe it's
another bug.
(Done. Whew. It turned out that the problem had nothing to do
with hypothetical external references to Wcm, or any other
tty_output component; it was simply that delete_tty closed the
filehandles of secondary ttys twice, resulting in fclose doubly
free()ing memory. Utterly trivial matter. I love the C's memory
management, it puts hair on your chest.)
THINGS TO DO
------------
Idea: Some of these errors may have been caused by having more
file handles than FD_SETSIZE.
** Understand Emacs's low-level input system (it seems complicated) :-)
and maybe rewrite multi-tty input in terms of MULTIKBOARD.
** Find out why does Emacs abort when it wants to close its
controlling tty. Hint: chan_process[] array. Hey, maybe
noninterrupt-IO would work, too?
noninterrupt-IO would work, too? Update: no, there is no process
for stdin/out.
** Support raw secondary terminals. (Note that SIGIO works only on
the controlling terminal.) Hint: extend read_input_waiting() for
......@@ -252,9 +252,21 @@ THINGS TO DO
** Issue with SIGIO: it needs to be disabled during redisplay. See if
fcntl() kernel behaviour could be emulated by emacsclient.
** Get rid of the accessor macros in termchar.h, or define macros for
all members.
** Make parts of struct tty_output accessible from Lisp. The device
name and the type is sufficient.
** server.el: There are issues with saving files in buffers of closed
clients. Try editing a file with emacsclient -f, and (without
saving it) do a delete-frame. The frame is closed without
question, and a surprising confirmation prompt appears in another
frame.
** emacsclient.el, server.el: Handle eval or file open errors when
doing -f.
** Export delete_tty to the Lisp environment, for emacsclient.
** Make sure C-g goes to the right frame. This is hard, as SIGINT
......@@ -283,6 +295,6 @@ THINGS TO DO
** Fix DOS support (I can't do this myself).
** Do a grep on XXX and ?? for more issues.
;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
......@@ -118,7 +118,7 @@ int eval = 0;
char *display = NULL;
/* Nonzero means open a new Emacs frame on the current terminal. */
int here = 0;
int frame = 0;
/* If non-NULL, the name of an editor to fallback to if the server
is not running. --alternate-editor. */
......@@ -135,7 +135,7 @@ struct option longopts[] =
{ "eval", no_argument, NULL, 'e' },
{ "help", no_argument, NULL, 'H' },
{ "version", no_argument, NULL, 'V' },
{ "here", no_argument, NULL, 'h' },
{ "frame", no_argument, NULL, 'f' },
{ "alternate-editor", required_argument, NULL, 'a' },
{ "socket-name", required_argument, NULL, 's' },
{ "display", required_argument, NULL, 'd' },
......@@ -153,7 +153,7 @@ decode_options (argc, argv)
while (1)
{
int opt = getopt_long (argc, argv,
"VHnea:s:d:h", longopts, 0);
"VHnea:s:d:f", longopts, 0);
if (opt == EOF)
break;
......@@ -192,8 +192,8 @@ decode_options (argc, argv)
exit (0);
break;
case 'h':
here = 1;
case 'f':
frame = 1;
break;
case 'H':
......@@ -207,7 +207,7 @@ decode_options (argc, argv)
}
}
if (here) {
if (frame) {
nowait = 0;
display = 0;
}
......@@ -225,7 +225,7 @@ Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
The following OPTIONS are accepted:\n\
-V, --version Just print a version info and return\n\
-H, --help Print this usage information message\n\
-h, --here Open a new Emacs frame on the current terminal\n\
-f, --frame Open a new Emacs frame on the current terminal\n\
-n, --no-wait Don't wait for the server to return\n\
-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
-d, --display=DISPLAY Visit the file in the given display\n\
......@@ -876,7 +876,7 @@ main (argc, argv)
/* Process options. */
decode_options (argc, argv);
if ((argc - optind < 1) && !eval && !here)
if ((argc - optind < 1) && !eval && !frame)
{
fprintf (stderr, "%s: file name or argument required\n", progname);
fprintf (stderr, "Try `%s --help' for more information\n", progname);
......@@ -1048,7 +1048,7 @@ To start the server in Emacs, type \"M-x server-start\".\n",
fprintf (out, " ");
}
if (here)
if (frame)
{
if (! init_signals ())
{
......@@ -1108,7 +1108,7 @@ To start the server in Emacs, type \"M-x server-start\".\n",
}
else
{
if (!here)
if (!frame)
{
while ((str = fgets (string, BUFSIZ, stdin)))
{
......@@ -1128,7 +1128,7 @@ To start the server in Emacs, type \"M-x server-start\".\n",
return 0;
}
if (here)
if (frame)
{
if (! pty_conversation (out))
{
......
......@@ -271,7 +271,7 @@ Prefix arg means just kill any existing server communications subprocess."
(while server-frames
(let ((frame (cadar server-frames)))
(setq server-frames (cdr server-frames))
(when frame-live-p frame (delete-frame frame 'force))))
(when (frame-live-p frame) (delete-frame frame 'force))))
(unless leave-dead
(if server-process
(server-log (message "Restarting server")))
......@@ -314,7 +314,7 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"."
(coding-system (and default-enable-multibyte-characters
(or file-name-coding-system
default-file-name-coding-system)))
client nowait eval
client nowait eval newframe
(files nil)
(lineno 1)
(columnno 0))
......@@ -336,6 +336,7 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"."
(setq request "")))))
;; Open a new frame at the client. ARG is the name of the pseudo tty.
((and (equal "-pty" arg) (string-match "\\([^ ]*\\) \\([^ ]*\\) " request))
(setq newframe t)
(let ((pty (server-unquote-arg (match-string 1 request)))
(type (server-unquote-arg (match-string 2 request))))
(setq request (substring request (match-end 0)))
......@@ -364,7 +365,7 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"."
(if eval
(condition-case err
(let ((v (eval (car (read-from-string arg)))))
(when v
(when (and (not newframe v))
(with-temp-buffer
(let ((standard-output (current-buffer)))
(pp v)
......@@ -382,7 +383,7 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"."
(server-visit-files files client nowait)
(run-hooks 'post-command-hook))
;; CLIENT is now a list (CLIENTNUM BUFFERS...)
(if (null (cdr client))
(if (and (not newframe) (null (cdr client)))
;; This client is empty; get rid of it immediately.
(progn
(let ((frame (assq (car client) server-frames)))
......@@ -607,7 +608,8 @@ Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it."
;; since we've already effectively done that.
(if (null next-buffer)
(if server-clients
(server-switch-buffer (nth 1 (car server-clients)) killed-one)
(let ((buffer (nth 1 (car server-clients))))
(and buffer (server-switch-buffer buffer killed-one)))
(unless (or killed-one (window-dedicated-p (selected-window)))
(switch-to-buffer (other-buffer))
(message "No server buffers remain to edit")))
......
......@@ -2562,11 +2562,11 @@ extern int x_intersect_rectangles P_ ((XRectangle *, XRectangle *,
/* Defined in sysdep.c */
void get_tty_size P_ ((struct tty_output *, int *, int *));
void get_tty_size P_ ((int, int *, int *));
void request_sigio P_ ((void));
void unrequest_sigio P_ ((void));
int tabs_safe_p P_ ((struct tty_output *));
void init_baud_rate P_ ((struct tty_output *));
int tabs_safe_p P_ ((int));
void init_baud_rate P_ ((int));
void init_sigio P_ ((int));
/* Defined in xfaces.c */
......
......@@ -5927,7 +5927,7 @@ window_change_signal (signalnum) /* If we don't have an argument, */
if (! tty->term_initted)
continue;
get_tty_size (tty, &width, &height);
get_tty_size (fileno (TTY_INPUT (tty)), &width, &height);
{
Lisp_Object tail, frame;
......
......@@ -656,7 +656,7 @@ Note that changing the size of one terminal frame automatically affects all. */
{
int width, height;
get_tty_size (FRAME_TTY (f), &width, &height);
get_tty_size (fileno (TTY_INPUT (FRAME_TTY (f))), &width, &height);
change_frame_size (f, height, width, 0, 0, 0);
}
......
......@@ -10127,7 +10127,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
call1 (Vrun_hooks, intern ("suspend-hook"));
GCPRO1 (stuffstring);
get_tty_size (CURTTY (), &old_width, &old_height);
get_tty_size (fileno (TTY_INPUT (CURTTY ())), &old_width, &old_height);
reset_all_sys_modes ();
/* sys_suspend can get an error if it tries to fork a subshell
and the system resources aren't available for that. */
......@@ -10143,7 +10143,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
/* Check if terminal/window size has changed.
Note that this is not useful when we are running directly
with a window system; but suspend should be disabled in that case. */
get_tty_size (CURTTY (), &width, &height);
get_tty_size (fileno (TTY_INPUT (CURTTY ())), &width, &height);
if (width != old_width || height != old_height)
change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
......
......@@ -309,10 +309,13 @@ discard_tty_input ()
#endif /* not WINDOWSNT */
}
#ifdef SIGTSTP
/* Arrange for character C to be read as the next input from
the terminal. */
the terminal.
XXX What if we have multiple ttys?
*/
void
stuff_char (char c)
......@@ -331,7 +334,7 @@ stuff_char (char c)
#endif /* SIGTSTP */
void
init_baud_rate (struct tty_output *tty)
init_baud_rate (int fd)
{
if (noninteractive)
emacs_ospeed = 0;
......@@ -346,7 +349,7 @@ init_baud_rate (struct tty_output *tty)
#ifdef VMS
struct sensemode sg;
SYS$QIOW (0, fileno (TTY_INPUT (tty)), IO$_SENSEMODE, &sg, 0, 0,
SYS$QIOW (0, fd, IO$_SENSEMODE, &sg, 0, 0,
&sg.class, 12, 0, 0, 0, 0 );
emacs_ospeed = sg.xmit_baud;
#else /* not VMS */
......@@ -354,7 +357,7 @@ init_baud_rate (struct tty_output *tty)
struct termios sg;
sg.c_cflag = B9600;
tcgetattr (fileno (TTY_INPUT (tty)), &sg);
tcgetattr (fd, &sg);
emacs_ospeed = cfgetospeed (&sg);
#if defined (USE_GETOBAUD) && defined (getobaud)
/* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
......@@ -367,16 +370,16 @@ init_baud_rate (struct tty_output *tty)
sg.c_cflag = B9600;
#ifdef HAVE_TCATTR
tcgetattr (fileno (TTY_INPUT (tty)), &sg);
tcgetattr (fd, &sg);
#else
ioctl (fileno (TTY_INPUT (tty)), TCGETA, &sg);
ioctl (fd, TCGETA, &sg);
#endif
emacs_ospeed = sg.c_cflag & CBAUD;
#else /* neither VMS nor TERMIOS nor TERMIO */
struct sgttyb sg;
sg.sg_ospeed = B9600;
if (ioctl (fileno (TTY_INPUT (tty)), TIOCGETP, &sg) < 0)
if (ioctl (fd, TIOCGETP, &sg) < 0)
abort ();
emacs_ospeed = sg.sg_ospeed;
#endif /* not HAVE_TERMIO */
......@@ -392,6 +395,7 @@ init_baud_rate (struct tty_output *tty)
baud_rate = 1200;
}
/*ARGSUSED*/
void
set_exclusive_use (fd)
......@@ -976,7 +980,7 @@ request_sigio ()
}
void
unrequest_sigio (struct tty_output *tty)
unrequest_sigio ()
{
int off = 0;
......@@ -1078,23 +1082,23 @@ int inherited_pgroup;
group, redirect the TTY to point to our own process group. We need
to be in our own process group to receive SIGIO properly. */
void
narrow_foreground_group (struct tty_output *tty)
narrow_foreground_group (int fd)
{
int me = getpid ();
setpgrp (0, inherited_pgroup);
/* XXX This only works on the controlling tty. */
if (inherited_pgroup != me)
EMACS_SET_TTY_PGRP (fileno (TTY_INPUT (tty)), &me);
EMACS_SET_TTY_PGRP (fd, &me);
setpgrp (0, me);
}
/* Set the tty to our original foreground group. */
void
widen_foreground_group (struct tty_output *tty)
widen_foreground_group (int fd)
{
if (inherited_pgroup != getpid ())
EMACS_SET_TTY_PGRP (fileno (TTY_INPUT (tty)), &inherited_pgroup);
EMACS_SET_TTY_PGRP (fd, &inherited_pgroup);
setpgrp (0, inherited_pgroup);
}
......@@ -1289,11 +1293,9 @@ static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
void
init_all_sys_modes (void)
{
struct tty_output *tty = tty_list;
while (tty) {
struct tty_output *tty;
for (tty = tty_list; tty; tty = tty->next)
init_sys_modes (tty);
tty = tty->next;
}
}
void
......@@ -1358,7 +1360,7 @@ nil means don't delete them until `list-processes' is run. */);
#ifdef BSD_PGRPS
if (! read_socket_hook && EQ (Vwindow_system, Qnil))
narrow_foreground_group (tty_out);
narrow_foreground_group (fileno (TTY_INPUT (tty_out)));
#endif
#ifdef HAVE_WINDOW_SYSTEM
......@@ -1683,11 +1685,11 @@ nil means don't delete them until `list-processes' is run. */);
At the time this is called, init_sys_modes has not been done yet. */
int
tabs_safe_p (struct tty_output *tty)
tabs_safe_p (int fd)
{
struct emacs_tty etty;
EMACS_GET_TTY (fileno (TTY_INPUT (tty)), &etty);
EMACS_GET_TTY (fd, &etty);
return EMACS_TTY_TABS_OK (&etty);
}
......@@ -1696,9 +1698,7 @@ tabs_safe_p (struct tty_output *tty)
We store 0 if there's no valid information. */
void
get_tty_size (tty_out, widthp, heightp)
struct tty_output *tty_out;
int *widthp, *heightp;
get_tty_size (int fd, int *widthp, int *heightp)
{
#ifdef TIOCGWINSZ
......@@ -1706,7 +1706,7 @@ get_tty_size (tty_out, widthp, heightp)
/* BSD-style. */
struct winsize size;
if (ioctl (fileno (TTY_INPUT (tty_out)), TIOCGWINSZ, &size) == -1)
if (ioctl (fd, TIOCGWINSZ, &size) == -1)
*widthp = *heightp = 0;
else
{
......@@ -1720,7 +1720,7 @@ get_tty_size (tty_out, widthp, heightp)
/* SunOS - style. */
struct ttysize size;
if (ioctl (fileno (TTY_INPUT (tty_out)), TIOCGSIZE, &size) == -1)
if (ioctl (fd, TIOCGSIZE, &size) == -1)
*widthp = *heightp = 0;
else
{
......@@ -1733,7 +1733,7 @@ get_tty_size (tty_out, widthp, heightp)
struct sensemode tty;
SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SENSEMODE, &tty, 0, 0,
SYS$QIOW (0, fd, IO$_SENSEMODE, &tty, 0, 0,
&tty.class, 12, 0, 0, 0, 0);
*widthp = tty.scr_wid;
*heightp = tty.scr_len;
......@@ -1793,11 +1793,9 @@ set_window_size (fd, height, width)
void
reset_all_sys_modes (void)
{
struct tty_output *tty = tty_list;
while (tty) {
struct tty_output *tty;
for (tty = tty_list; tty; tty = tty->next)
reset_sys_modes (tty);
tty = tty->next;
}
}
/* Prepare the terminal for closing it; move the cursor to the
......@@ -1889,7 +1887,7 @@ reset_sys_modes (tty_out)
#endif
#ifdef BSD_PGRPS
widen_foreground_group (tty_out);
widen_foreground_group (fileno (TTY_INPUT (tty_out)));
#endif
}
......
......@@ -2403,7 +2403,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
/* Get frame size from system, or else from termcap. */
{
int height, width;
get_tty_size (tty, &width, &height);
get_tty_size (fileno (TTY_INPUT (tty)), &width, &height);
FrameCols (tty) = width;
FrameRows (tty) = height;
}
......@@ -2609,7 +2609,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
&& tty->TS_end_standout_mode
&& !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode));
UseTabs (tty) = tabs_safe_p (tty) && TabWidth (tty) == 8;
UseTabs (tty) = tabs_safe_p (fileno (TTY_INPUT (tty))) && TabWidth (tty) == 8;
TTY_SCROLL_REGION_OK (tty)
= (tty->Wcm->cm_abs
......@@ -2628,7 +2628,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
TTY_FAST_CLEAR_END_OF_LINE (tty) = tty->TS_clr_line != 0;
init_baud_rate (tty);
init_baud_rate (fileno (TTY_INPUT (tty)));
if (read_socket_hook) /* Baudrate is somewhat
meaningless in this case */
baud_rate = 9600;
......@@ -2737,7 +2737,7 @@ delete_tty (struct tty_output *tty)
if (tty->input)
fclose (tty->input);
if (tty->output)
if (tty->output && tty->output != tty->input)
fclose (tty->output);
if (tty->termscript)
fclose (tty->termscript);
......@@ -2745,10 +2745,8 @@ delete_tty (struct tty_output *tty)
if (tty->old_tty)
xfree (tty->old_tty);
#if 0 /* XXX There is a dangling reference somewhere into this. */
if (tty->Wcm)
xfree (tty->Wcm);
#endif
bzero (tty, sizeof (struct tty_output));
xfree (tty);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment