diff options
| author | Karoly Lorentey | 2003-12-31 05:09:29 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2003-12-31 05:09:29 +0000 |
| commit | 819b8f00ed7b8a9a2190efaa02376ed332ecf763 (patch) | |
| tree | c30ab72204225385c428db008580a9f67f5c215c /lib-src | |
| parent | 16c290d8c16fb0fdb574c837c6b1badbc655efe2 (diff) | |
| download | emacs-819b8f00ed7b8a9a2190efaa02376ed332ecf763.tar.gz emacs-819b8f00ed7b8a9a2190efaa02376ed332ecf763.zip | |
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
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/emacsclient.c | 150 |
1 files changed, 90 insertions, 60 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 9f08e4dac37..544bebeaeda 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c | |||
| @@ -153,7 +153,7 @@ decode_options (argc, argv) | |||
| 153 | while (1) | 153 | while (1) |
| 154 | { | 154 | { |
| 155 | int opt = getopt_long (argc, argv, | 155 | int opt = getopt_long (argc, argv, |
| 156 | "VHnea:s:d:f", longopts, 0); | 156 | "VHnea:s:d:t", longopts, 0); |
| 157 | 157 | ||
| 158 | if (opt == EOF) | 158 | if (opt == EOF) |
| 159 | break; | 159 | break; |
| @@ -192,7 +192,7 @@ decode_options (argc, argv) | |||
| 192 | exit (0); | 192 | exit (0); |
| 193 | break; | 193 | break; |
| 194 | 194 | ||
| 195 | case 'f': | 195 | case 't': |
| 196 | frame = 1; | 196 | frame = 1; |
| 197 | break; | 197 | break; |
| 198 | 198 | ||
| @@ -225,7 +225,7 @@ Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\ | |||
| 225 | The following OPTIONS are accepted:\n\ | 225 | The following OPTIONS are accepted:\n\ |
| 226 | -V, --version Just print a version info and return\n\ | 226 | -V, --version Just print a version info and return\n\ |
| 227 | -H, --help Print this usage information message\n\ | 227 | -H, --help Print this usage information message\n\ |
| 228 | -f, --frame Open a new Emacs frame on the current terminal\n\ | 228 | -t, --tty Open a new Emacs frame on the current terminal\n\ |
| 229 | -n, --no-wait Don't wait for the server to return\n\ | 229 | -n, --no-wait Don't wait for the server to return\n\ |
| 230 | -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ | 230 | -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ |
| 231 | -d, --display=DISPLAY Visit the file in the given display\n\ | 231 | -d, --display=DISPLAY Visit the file in the given display\n\ |
| @@ -300,7 +300,7 @@ xmalloc (size) | |||
| 300 | defined-- exit with an errorcode. | 300 | defined-- exit with an errorcode. |
| 301 | */ | 301 | */ |
| 302 | void | 302 | void |
| 303 | fail () | 303 | fail (void) |
| 304 | { | 304 | { |
| 305 | if (alternate_editor) | 305 | if (alternate_editor) |
| 306 | { | 306 | { |
| @@ -720,14 +720,14 @@ init_pty () | |||
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | int | 722 | int |
| 723 | copy_from_to (int in, int out, int sigio) | 723 | copy_from_to (int in, int out) |
| 724 | { | 724 | { |
| 725 | static char buf[BUFSIZ]; | 725 | static char buf[BUFSIZ]; |
| 726 | int nread = read (in, &buf, BUFSIZ); | 726 | int nread = read (in, &buf, BUFSIZ); |
| 727 | if (nread == 0) | 727 | if (nread == 0) |
| 728 | return 1; /* EOF */ | 728 | return 1; /* EOF */ |
| 729 | else if (nread < 0 && errno != EAGAIN) | 729 | else if (nread < 0 && errno != EAGAIN) |
| 730 | return 0; /* Error */ | 730 | return 0; |
| 731 | else if (nread > 0) | 731 | else if (nread > 0) |
| 732 | { | 732 | { |
| 733 | int r = 0; | 733 | int r = 0; |
| @@ -735,16 +735,11 @@ copy_from_to (int in, int out, int sigio) | |||
| 735 | 735 | ||
| 736 | do { | 736 | do { |
| 737 | r = write (out, &buf, nread); | 737 | r = write (out, &buf, nread); |
| 738 | } while ((r < 0 && errno == EAGAIN) | 738 | } while ((r < 0 && errno == EINTR) |
| 739 | || (r > 0 && (written += r) && written != nread)); | 739 | || (r > 0 && (written += r) && written != nread)); |
| 740 | 740 | ||
| 741 | if (r < 0) | 741 | if (r < 0) |
| 742 | return 0; /* Error */ | 742 | return 0; |
| 743 | |||
| 744 | if (emacs_pid && sigio) | ||
| 745 | { | ||
| 746 | kill (emacs_pid, SIGIO); | ||
| 747 | } | ||
| 748 | } | 743 | } |
| 749 | return 1; | 744 | return 1; |
| 750 | } | 745 | } |
| @@ -754,53 +749,85 @@ pty_conversation (FILE *in) | |||
| 754 | { | 749 | { |
| 755 | char *str; | 750 | char *str; |
| 756 | char string[BUFSIZ]; | 751 | char string[BUFSIZ]; |
| 757 | fd_set set; | 752 | fd_set set, rset; |
| 753 | int res; | ||
| 754 | |||
| 755 | FD_ZERO (&set); | ||
| 756 | FD_SET (master, &set); | ||
| 757 | FD_SET (1, &set); | ||
| 758 | FD_SET (fileno (in), &set); | ||
| 758 | 759 | ||
| 759 | in_conversation = 1; | 760 | in_conversation = 1; |
| 760 | 761 | ||
| 761 | while (! quit_conversation) { | 762 | while (! quit_conversation) { |
| 762 | int res; | 763 | rset = set; |
| 763 | 764 | res = select (FD_SETSIZE, &rset, NULL, NULL, NULL); | |
| 764 | FD_ZERO (&set); | 765 | if (res < 0 && errno != EINTR) |
| 765 | FD_SET (master, &set); | ||
| 766 | FD_SET (1, &set); | ||
| 767 | FD_SET (fileno (in), &set); | ||
| 768 | res = select (FD_SETSIZE, &set, NULL, NULL, NULL); | ||
| 769 | if (res < 0) | ||
| 770 | { | 766 | { |
| 771 | if (errno != EINTR) | 767 | reset_tty (); |
| 772 | return 0; | 768 | fprintf (stderr, "%s: ", progname); |
| 769 | perror ("select"); | ||
| 770 | return 0; /* Error */ | ||
| 773 | } | 771 | } |
| 774 | else if (res > 0) | 772 | else if (res > 0) |
| 775 | { | 773 | { |
| 776 | if (FD_ISSET (master, &set)) | 774 | if (FD_ISSET (master, &rset)) |
| 777 | { | 775 | { |
| 778 | /* Copy Emacs output to stdout. */ | 776 | /* Copy Emacs output to stdout. */ |
| 779 | if (! copy_from_to (master, 0, 0)) | 777 | if (! copy_from_to (master, 0)) |
| 780 | return 1; | 778 | { |
| 779 | FD_CLR (master, &set); | ||
| 780 | } | ||
| 781 | } | 781 | } |
| 782 | if (FD_ISSET (1, &set)) | 782 | if (FD_ISSET (1, &rset)) |
| 783 | { | 783 | { |
| 784 | /* Forward user input to Emacs. */ | 784 | /* Forward user input to Emacs. */ |
| 785 | if (! copy_from_to (1, master, 1)) | 785 | if (! copy_from_to (1, master)) |
| 786 | return 1; | 786 | { |
| 787 | FD_CLR (master, &set); | ||
| 788 | } | ||
| 787 | } | 789 | } |
| 788 | if (FD_ISSET (fileno (in), &set)) | 790 | if (FD_ISSET (fileno (in), &rset)) |
| 789 | { | 791 | { |
| 792 | do { | ||
| 793 | res = read (fileno (in), string, BUFSIZ-1); | ||
| 794 | } while (res == EINTR); | ||
| 795 | if (res < 0) | ||
| 796 | { | ||
| 797 | reset_tty (); | ||
| 798 | fprintf (stderr, "%s: ", progname); | ||
| 799 | perror ("read"); | ||
| 800 | return 0; | ||
| 801 | } | ||
| 802 | if (!res) | ||
| 803 | { | ||
| 804 | return 1; | ||
| 805 | } | ||
| 806 | |||
| 807 | string[res] = 0; | ||
| 808 | if (string[res-1] == '\n') | ||
| 809 | string[res-1] = 0; | ||
| 810 | |||
| 790 | if (! emacs_pid) | 811 | if (! emacs_pid) |
| 791 | { | 812 | { |
| 792 | /* Get the pid of the Emacs process. | 813 | /* Get the pid of the Emacs process. |
| 793 | XXX Is there is some nifty libc/kernel feature for doing this? | 814 | XXX Is there some nifty libc/kernel feature for doing this? |
| 794 | */ | 815 | */ |
| 795 | str = fgets (string, BUFSIZ, in); | 816 | if (! string[0]) |
| 796 | if (! str) | ||
| 797 | { | 817 | { |
| 798 | reset_tty (); | 818 | reset_tty (); |
| 799 | fprintf (stderr, "%s: %s\n", progname, str); | 819 | fprintf (stderr, "%s: could not get Emacs process id\n" |
| 800 | fail (); | 820 | "Maybe this Emacs does not support multiple terminals.\n", progname); |
| 821 | return 0; | ||
| 801 | } | 822 | } |
| 802 | 823 | emacs_pid = strtol (string, NULL, 10); | |
| 803 | emacs_pid = atoi (str); | 824 | } |
| 825 | |||
| 826 | if (! emacs_pid) /* emacs_pid should be set above */ | ||
| 827 | { | ||
| 828 | reset_tty (); | ||
| 829 | fprintf (stderr, "%s: %s\n", progname, string); | ||
| 830 | return 0; | ||
| 804 | } | 831 | } |
| 805 | } | 832 | } |
| 806 | } | 833 | } |
| @@ -822,7 +849,7 @@ main (argc, argv) | |||
| 822 | argv[0]); | 849 | argv[0]); |
| 823 | fprintf (stderr, "on systems with Berkeley sockets.\n"); | 850 | fprintf (stderr, "on systems with Berkeley sockets.\n"); |
| 824 | 851 | ||
| 825 | fail (argc, argv); | 852 | fail (); |
| 826 | } | 853 | } |
| 827 | 854 | ||
| 828 | #else /* HAVE_SOCKETS */ | 855 | #else /* HAVE_SOCKETS */ |
| @@ -891,7 +918,7 @@ main (argc, argv) | |||
| 891 | { | 918 | { |
| 892 | fprintf (stderr, "%s: ", argv[0]); | 919 | fprintf (stderr, "%s: ", argv[0]); |
| 893 | perror ("socket"); | 920 | perror ("socket"); |
| 894 | fail (argc, argv); | 921 | fail (); |
| 895 | } | 922 | } |
| 896 | 923 | ||
| 897 | server.sun_family = AF_UNIX; | 924 | server.sun_family = AF_UNIX; |
| @@ -922,7 +949,8 @@ main (argc, argv) | |||
| 922 | 949 | ||
| 923 | { | 950 | { |
| 924 | int sock_status = 0; | 951 | int sock_status = 0; |
| 925 | 952 | int oerrno = 0; | |
| 953 | |||
| 926 | if (! socket_name) | 954 | if (! socket_name) |
| 927 | { | 955 | { |
| 928 | socket_name = alloca (system_name_length + 100); | 956 | socket_name = alloca (system_name_length + 100); |
| @@ -933,11 +961,15 @@ main (argc, argv) | |||
| 933 | if (strlen (socket_name) < sizeof (server.sun_path)) | 961 | if (strlen (socket_name) < sizeof (server.sun_path)) |
| 934 | strcpy (server.sun_path, socket_name); | 962 | strcpy (server.sun_path, socket_name); |
| 935 | else | 963 | else |
| 936 | fprintf (stderr, "%s: socket-name %s too long", | 964 | { |
| 937 | argv[0], socket_name); | 965 | fprintf (stderr, "%s: socket-name %s too long", |
| 966 | argv[0], socket_name); | ||
| 967 | fail (); | ||
| 968 | } | ||
| 938 | 969 | ||
| 939 | /* See if the socket exists, and if it's owned by us. */ | 970 | /* See if the socket exists, and if it's owned by us. */ |
| 940 | sock_status = socket_status (server.sun_path); | 971 | sock_status = socket_status (server.sun_path); |
| 972 | oerrno = errno; | ||
| 941 | if (sock_status) | 973 | if (sock_status) |
| 942 | { | 974 | { |
| 943 | /* Failing that, see if LOGNAME or USER exist and differ from | 975 | /* Failing that, see if LOGNAME or USER exist and differ from |
| @@ -958,6 +990,7 @@ main (argc, argv) | |||
| 958 | sprintf (server.sun_path, "/tmp/esrv%d-%s", | 990 | sprintf (server.sun_path, "/tmp/esrv%d-%s", |
| 959 | (int) pw->pw_uid, system_name); | 991 | (int) pw->pw_uid, system_name); |
| 960 | sock_status = socket_status (server.sun_path); | 992 | sock_status = socket_status (server.sun_path); |
| 993 | oerrno = errno; | ||
| 961 | } | 994 | } |
| 962 | } | 995 | } |
| 963 | } | 996 | } |
| @@ -970,7 +1003,7 @@ main (argc, argv) | |||
| 970 | if (0 != geteuid ()) | 1003 | if (0 != geteuid ()) |
| 971 | { | 1004 | { |
| 972 | fprintf (stderr, "%s: Invalid socket owner\n", argv[0]); | 1005 | fprintf (stderr, "%s: Invalid socket owner\n", argv[0]); |
| 973 | fail (argc, argv); | 1006 | fail (); |
| 974 | } | 1007 | } |
| 975 | break; | 1008 | break; |
| 976 | 1009 | ||
| @@ -978,13 +1011,13 @@ main (argc, argv) | |||
| 978 | /* `stat' failed */ | 1011 | /* `stat' failed */ |
| 979 | if (errno == ENOENT) | 1012 | if (errno == ENOENT) |
| 980 | fprintf (stderr, | 1013 | fprintf (stderr, |
| 981 | "%s: can't find socket; have you started the server?\n\ | 1014 | "%s: Can't find socket; have you started the server?\n\ |
| 982 | To start the server in Emacs, type \"M-x server-start\".\n", | 1015 | To start the server in Emacs, type \"M-x server-start\".\n", |
| 983 | argv[0]); | 1016 | argv[0]); |
| 984 | else | 1017 | else |
| 985 | fprintf (stderr, "%s: can't stat %s: %s\n", | 1018 | fprintf (stderr, "%s: Can't stat %s: %s\n", |
| 986 | argv[0], server.sun_path, strerror (errno)); | 1019 | argv[0], server.sun_path, strerror (oerrno)); |
| 987 | fail (argc, argv); | 1020 | fail (); |
| 988 | break; | 1021 | break; |
| 989 | } | 1022 | } |
| 990 | } | 1023 | } |
| @@ -994,7 +1027,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 994 | { | 1027 | { |
| 995 | fprintf (stderr, "%s: ", argv[0]); | 1028 | fprintf (stderr, "%s: ", argv[0]); |
| 996 | perror ("connect"); | 1029 | perror ("connect"); |
| 997 | fail (argc, argv); | 1030 | fail (); |
| 998 | } | 1031 | } |
| 999 | 1032 | ||
| 1000 | /* We use the stream OUT to send our command to the server. */ | 1033 | /* We use the stream OUT to send our command to the server. */ |
| @@ -1002,7 +1035,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 1002 | { | 1035 | { |
| 1003 | fprintf (stderr, "%s: ", argv[0]); | 1036 | fprintf (stderr, "%s: ", argv[0]); |
| 1004 | perror ("fdopen"); | 1037 | perror ("fdopen"); |
| 1005 | fail (argc, argv); | 1038 | fail (); |
| 1006 | } | 1039 | } |
| 1007 | 1040 | ||
| 1008 | /* We use the stream IN to read the response. | 1041 | /* We use the stream IN to read the response. |
| @@ -1014,7 +1047,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 1014 | { | 1047 | { |
| 1015 | fprintf (stderr, "%s: ", argv[0]); | 1048 | fprintf (stderr, "%s: ", argv[0]); |
| 1016 | perror ("fdopen"); | 1049 | perror ("fdopen"); |
| 1017 | fail (argc, argv); | 1050 | fail (); |
| 1018 | } | 1051 | } |
| 1019 | 1052 | ||
| 1020 | #ifdef HAVE_GETCWD | 1053 | #ifdef HAVE_GETCWD |
| @@ -1032,7 +1065,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 1032 | #else | 1065 | #else |
| 1033 | fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno)); | 1066 | fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno)); |
| 1034 | #endif | 1067 | #endif |
| 1035 | fail (argc, argv); | 1068 | fail (); |
| 1036 | } | 1069 | } |
| 1037 | 1070 | ||
| 1038 | if (nowait) | 1071 | if (nowait) |
| @@ -1054,7 +1087,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 1054 | { | 1087 | { |
| 1055 | fprintf (stderr, "%s: ", argv[0]); | 1088 | fprintf (stderr, "%s: ", argv[0]); |
| 1056 | perror ("fdopen"); | 1089 | perror ("fdopen"); |
| 1057 | fail (argc, argv); | 1090 | fail (); |
| 1058 | } | 1091 | } |
| 1059 | 1092 | ||
| 1060 | if (! init_tty ()) | 1093 | if (! init_tty ()) |
| @@ -1062,7 +1095,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 1062 | reset_tty (); | 1095 | reset_tty (); |
| 1063 | fprintf (stderr, "%s: ", argv[0]); | 1096 | fprintf (stderr, "%s: ", argv[0]); |
| 1064 | perror ("fdopen"); | 1097 | perror ("fdopen"); |
| 1065 | fail (argc, argv); | 1098 | fail (); |
| 1066 | } | 1099 | } |
| 1067 | 1100 | ||
| 1068 | if (! init_pty ()) | 1101 | if (! init_pty ()) |
| @@ -1070,10 +1103,10 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 1070 | reset_tty (); | 1103 | reset_tty (); |
| 1071 | fprintf (stderr, "%s: ", argv[0]); | 1104 | fprintf (stderr, "%s: ", argv[0]); |
| 1072 | perror ("fdopen"); | 1105 | perror ("fdopen"); |
| 1073 | fail (argc, argv); | 1106 | fail (); |
| 1074 | } | 1107 | } |
| 1075 | 1108 | ||
| 1076 | fprintf (out, "-pty "); | 1109 | fprintf (out, "-tty "); |
| 1077 | quote_file_name (pty_name, out); | 1110 | quote_file_name (pty_name, out); |
| 1078 | fprintf (out, " "); | 1111 | fprintf (out, " "); |
| 1079 | quote_file_name (getenv("TERM"), out); | 1112 | quote_file_name (getenv("TERM"), out); |
| @@ -1133,11 +1166,8 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 1133 | if (! pty_conversation (out)) | 1166 | if (! pty_conversation (out)) |
| 1134 | { | 1167 | { |
| 1135 | reset_tty (); | 1168 | reset_tty (); |
| 1136 | fprintf (stderr, "%s: ", argv[0]); | 1169 | fail (); |
| 1137 | perror ("fdopen"); | ||
| 1138 | fail (argc, argv); | ||
| 1139 | } | 1170 | } |
| 1140 | close (master); | ||
| 1141 | reset_tty (); | 1171 | reset_tty (); |
| 1142 | return 0; | 1172 | return 0; |
| 1143 | } | 1173 | } |