Mercurial > emacs
diff lib-src/emacsclient.c @ 82988:f82e3a6f5ccb
A few more bugfixes and new features.
(Sigh.) I obviously need to remember to separate individual changes
to multiple commits.
src/emacsclient.c: Improved error handling.
(decode_options): Changed frame option (again) from -f to -t.
(print_help_and_exit): Ditto.
(copy_from_to): Check EINTR after write, not EAGAIN. Removed SIGIO hack.
(pty_conversation): Handle errors transmitted through the socket.
Handle pty errors by not reading from it anymore.
(main): Restore correct errno after socket_status failed. Send -tty
on -t, not -pty.
lisp/server.el (server-process-filter): Watch -tty, not -pty.
Use make-frame-on-tty instead of make-terminal-frame.
Don't set newframe to t if make-frame-on-tty failed.
Don't delete frames here. Print correct message when there are no
files to edit, but a new frame was requested.
(server-sentinel): Delete the frame after the process.
(server-handle-delete-frame): New function for delete-frame-functions.
(server-start): Add server-handle-delete-frame to delete-frame-functions.
(server-buffer-done): Don't delete frames here.
src/alloc.c (mark_ttys): Add prototype.
(Fgarbage_collect): Call mark_ttys.
src/emacs.c: (shut_down_emacs): Don't flush stdout before
reset_sys_modes().
src/process.c (add_keyboard_wait_descriptor_called_flag): Removed.
(add_keyboard_wait_descriptor): Removed stdin hack.
src/sysdep.c: Unconditionally include sysselect.h.
(old_fcntl_flags): Changed to an array.
(init_sigio, reset_sigio): Use it.
(narrow_foreground_group, widen_foreground_group): Use setpgid, not
setpgrp.
(old_fcntl_owner): Changed to an array.
(init_sys_modes, reset_sys_modes): Use it. Fix fsync() and reset_sigio() calls.
src/term.c (Qframe_tty_name, Qframe_tty_type): New variables.
(syms_of_term): Initialize them.
(Fframe_tty_name, Fframe_tty_type): New functions.
(term_init): Call add_keyboard_wait_descriptor().
(Fdelete_tty): New function.
(delete_tty): Call delete_keyboard_wait_descriptor().
(get_current_tty): Removed.
(mark_ttys): New function.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-28
| author | Karoly Lorentey <lorentey@elte.hu> |
|---|---|
| date | Wed, 31 Dec 2003 05:09:29 +0000 |
| parents | 1682917e56b4 |
| children | 2ecd1f669db9 |
line wrap: on
line diff
--- a/lib-src/emacsclient.c Tue Dec 30 19:27:57 2003 +0000 +++ b/lib-src/emacsclient.c Wed Dec 31 05:09:29 2003 +0000 @@ -153,7 +153,7 @@ while (1) { int opt = getopt_long (argc, argv, - "VHnea:s:d:f", longopts, 0); + "VHnea:s:d:t", longopts, 0); if (opt == EOF) break; @@ -192,7 +192,7 @@ exit (0); break; - case 'f': + case 't': frame = 1; break; @@ -225,7 +225,7 @@ The following OPTIONS are accepted:\n\ -V, --version Just print a version info and return\n\ -H, --help Print this usage information message\n\ --f, --frame Open a new Emacs frame on the current terminal\n\ +-t, --tty 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\ @@ -300,7 +300,7 @@ defined-- exit with an errorcode. */ void -fail () +fail (void) { if (alternate_editor) { @@ -720,14 +720,14 @@ } int -copy_from_to (int in, int out, int sigio) +copy_from_to (int in, int out) { static char buf[BUFSIZ]; int nread = read (in, &buf, BUFSIZ); if (nread == 0) return 1; /* EOF */ else if (nread < 0 && errno != EAGAIN) - return 0; /* Error */ + return 0; else if (nread > 0) { int r = 0; @@ -735,16 +735,11 @@ do { r = write (out, &buf, nread); - } while ((r < 0 && errno == EAGAIN) + } while ((r < 0 && errno == EINTR) || (r > 0 && (written += r) && written != nread)); if (r < 0) - return 0; /* Error */ - - if (emacs_pid && sigio) - { - kill (emacs_pid, SIGIO); - } + return 0; } return 1; } @@ -754,53 +749,85 @@ { char *str; char string[BUFSIZ]; - fd_set set; + fd_set set, rset; + int res; + + FD_ZERO (&set); + FD_SET (master, &set); + FD_SET (1, &set); + FD_SET (fileno (in), &set); in_conversation = 1; while (! quit_conversation) { - int res; - - FD_ZERO (&set); - FD_SET (master, &set); - FD_SET (1, &set); - FD_SET (fileno (in), &set); - res = select (FD_SETSIZE, &set, NULL, NULL, NULL); - if (res < 0) + rset = set; + res = select (FD_SETSIZE, &rset, NULL, NULL, NULL); + if (res < 0 && errno != EINTR) { - if (errno != EINTR) - return 0; + reset_tty (); + fprintf (stderr, "%s: ", progname); + perror ("select"); + return 0; /* Error */ } else if (res > 0) { - if (FD_ISSET (master, &set)) + if (FD_ISSET (master, &rset)) { /* Copy Emacs output to stdout. */ - if (! copy_from_to (master, 0, 0)) - return 1; + if (! copy_from_to (master, 0)) + { + FD_CLR (master, &set); + } } - if (FD_ISSET (1, &set)) + if (FD_ISSET (1, &rset)) { /* Forward user input to Emacs. */ - if (! copy_from_to (1, master, 1)) - return 1; + if (! copy_from_to (1, master)) + { + FD_CLR (master, &set); + } } - if (FD_ISSET (fileno (in), &set)) + if (FD_ISSET (fileno (in), &rset)) { + do { + res = read (fileno (in), string, BUFSIZ-1); + } while (res == EINTR); + if (res < 0) + { + reset_tty (); + fprintf (stderr, "%s: ", progname); + perror ("read"); + return 0; + } + if (!res) + { + return 1; + } + + string[res] = 0; + if (string[res-1] == '\n') + string[res-1] = 0; + if (! emacs_pid) { /* Get the pid of the Emacs process. - XXX Is there is some nifty libc/kernel feature for doing this? + XXX Is there some nifty libc/kernel feature for doing this? */ - str = fgets (string, BUFSIZ, in); - if (! str) + if (! string[0]) { reset_tty (); - fprintf (stderr, "%s: %s\n", progname, str); - fail (); + fprintf (stderr, "%s: could not get Emacs process id\n" + "Maybe this Emacs does not support multiple terminals.\n", progname); + return 0; } - - emacs_pid = atoi (str); + emacs_pid = strtol (string, NULL, 10); + } + + if (! emacs_pid) /* emacs_pid should be set above */ + { + reset_tty (); + fprintf (stderr, "%s: %s\n", progname, string); + return 0; } } } @@ -822,7 +849,7 @@ argv[0]); fprintf (stderr, "on systems with Berkeley sockets.\n"); - fail (argc, argv); + fail (); } #else /* HAVE_SOCKETS */ @@ -891,7 +918,7 @@ { fprintf (stderr, "%s: ", argv[0]); perror ("socket"); - fail (argc, argv); + fail (); } server.sun_family = AF_UNIX; @@ -922,7 +949,8 @@ { int sock_status = 0; - + int oerrno = 0; + if (! socket_name) { socket_name = alloca (system_name_length + 100); @@ -933,11 +961,15 @@ if (strlen (socket_name) < sizeof (server.sun_path)) strcpy (server.sun_path, socket_name); else - fprintf (stderr, "%s: socket-name %s too long", - argv[0], socket_name); + { + fprintf (stderr, "%s: socket-name %s too long", + argv[0], socket_name); + fail (); + } /* See if the socket exists, and if it's owned by us. */ sock_status = socket_status (server.sun_path); + oerrno = errno; if (sock_status) { /* Failing that, see if LOGNAME or USER exist and differ from @@ -958,6 +990,7 @@ sprintf (server.sun_path, "/tmp/esrv%d-%s", (int) pw->pw_uid, system_name); sock_status = socket_status (server.sun_path); + oerrno = errno; } } } @@ -970,7 +1003,7 @@ if (0 != geteuid ()) { fprintf (stderr, "%s: Invalid socket owner\n", argv[0]); - fail (argc, argv); + fail (); } break; @@ -978,13 +1011,13 @@ /* `stat' failed */ if (errno == ENOENT) fprintf (stderr, - "%s: can't find socket; have you started the server?\n\ + "%s: Can't find socket; have you started the server?\n\ To start the server in Emacs, type \"M-x server-start\".\n", argv[0]); else - fprintf (stderr, "%s: can't stat %s: %s\n", - argv[0], server.sun_path, strerror (errno)); - fail (argc, argv); + fprintf (stderr, "%s: Can't stat %s: %s\n", + argv[0], server.sun_path, strerror (oerrno)); + fail (); break; } } @@ -994,7 +1027,7 @@ { fprintf (stderr, "%s: ", argv[0]); perror ("connect"); - fail (argc, argv); + fail (); } /* We use the stream OUT to send our command to the server. */ @@ -1002,7 +1035,7 @@ { fprintf (stderr, "%s: ", argv[0]); perror ("fdopen"); - fail (argc, argv); + fail (); } /* We use the stream IN to read the response. @@ -1014,7 +1047,7 @@ { fprintf (stderr, "%s: ", argv[0]); perror ("fdopen"); - fail (argc, argv); + fail (); } #ifdef HAVE_GETCWD @@ -1032,7 +1065,7 @@ #else fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno)); #endif - fail (argc, argv); + fail (); } if (nowait) @@ -1054,7 +1087,7 @@ { fprintf (stderr, "%s: ", argv[0]); perror ("fdopen"); - fail (argc, argv); + fail (); } if (! init_tty ()) @@ -1062,7 +1095,7 @@ reset_tty (); fprintf (stderr, "%s: ", argv[0]); perror ("fdopen"); - fail (argc, argv); + fail (); } if (! init_pty ()) @@ -1070,10 +1103,10 @@ reset_tty (); fprintf (stderr, "%s: ", argv[0]); perror ("fdopen"); - fail (argc, argv); + fail (); } - fprintf (out, "-pty "); + fprintf (out, "-tty "); quote_file_name (pty_name, out); fprintf (out, " "); quote_file_name (getenv("TERM"), out); @@ -1133,11 +1166,8 @@ if (! pty_conversation (out)) { reset_tty (); - fprintf (stderr, "%s: ", argv[0]); - perror ("fdopen"); - fail (argc, argv); + fail (); } - close (master); reset_tty (); return 0; }
