aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/emacsclient.c281
1 files changed, 196 insertions, 85 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 3c6215a0144..d544fa63356 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -41,6 +41,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
41char *w32_getenv (const char *); 41char *w32_getenv (const char *);
42# define egetenv(VAR) w32_getenv (VAR) 42# define egetenv(VAR) w32_getenv (VAR)
43 43
44# undef signal
45
44#else /* !WINDOWSNT */ 46#else /* !WINDOWSNT */
45 47
46# ifdef HAVE_NTGUI 48# ifdef HAVE_NTGUI
@@ -68,8 +70,6 @@ char *w32_getenv (const char *);
68 70
69#endif /* !WINDOWSNT */ 71#endif /* !WINDOWSNT */
70 72
71#undef signal
72
73#include <ctype.h> 73#include <ctype.h>
74#include <errno.h> 74#include <errno.h>
75#include <getopt.h> 75#include <getopt.h>
@@ -144,7 +144,7 @@ static char const *server_file;
144/* If non-NULL, the tramp prefix emacs must use to find the files. */ 144/* If non-NULL, the tramp prefix emacs must use to find the files. */
145static char const *tramp_prefix; 145static char const *tramp_prefix;
146 146
147/* PID of the Emacs server process. */ 147/* If nonzero, PID of the Emacs server process. */
148static pid_t emacs_pid; 148static pid_t emacs_pid;
149 149
150/* If non-NULL, a string that should form a frame parameter alist to 150/* If non-NULL, a string that should form a frame parameter alist to
@@ -734,10 +734,13 @@ fail (void)
734 734
735#if defined HAVE_SOCKETS && defined HAVE_INET_SOCKETS 735#if defined HAVE_SOCKETS && defined HAVE_INET_SOCKETS
736 736
737enum { AUTH_KEY_LENGTH = 64 }; 737# ifndef NO_SOCKETS_IN_FILE_SYSTEM
738static void act_on_signals (HSOCKET);
739# else
740static void act_on_signals (HSOCKET s) {}
741# endif
738 742
739/* Socket used to communicate with the Emacs server process. */ 743enum { AUTH_KEY_LENGTH = 64 };
740static HSOCKET emacs_socket = 0;
741 744
742static void 745static void
743sock_err_message (const char *function_name) 746sock_err_message (const char *function_name)
@@ -790,16 +793,22 @@ send_to_emacs (HSOCKET s, const char *data)
790 if (sblen == SEND_BUFFER_SIZE 793 if (sblen == SEND_BUFFER_SIZE
791 || (0 < sblen && send_buffer[sblen - 1] == '\n')) 794 || (0 < sblen && send_buffer[sblen - 1] == '\n'))
792 { 795 {
793 int sent = send (s, send_buffer, sblen, 0); 796 int sent;
794 if (sent < 0) 797 while ((sent = send (s, send_buffer, sblen, 0)) < 0)
795 { 798 {
796 message (true, "%s: failed to send %d bytes to socket: %s\n", 799 if (errno != EINTR)
797 progname, sblen, strerror (errno)); 800 {
798 fail (); 801 message (true, "%s: failed to send %d bytes to socket: %s\n",
802 progname, sblen, strerror (errno));
803 fail ();
804 }
805 /* Act on signals not requiring communication to Emacs,
806 but defer action on the others to avoid confusing the
807 communication currently in progress. */
808 act_on_signals (INVALID_SOCKET);
799 } 809 }
800 if (sent != sblen)
801 memmove (send_buffer, &send_buffer[sent], sblen - sent);
802 sblen -= sent; 810 sblen -= sent;
811 memmove (send_buffer, &send_buffer[sent], sblen);
803 } 812 }
804 813
805 dlen -= part; 814 dlen -= part;
@@ -1091,86 +1100,181 @@ socket_status (const char *name)
1091} 1100}
1092 1101
1093 1102
1094/* A signal handler that passes the signal to the Emacs process. 1103/* Signal handlers merely set a flag, to avoid race conditions on
1095 Useful for SIGWINCH. */ 1104 POSIXish systems. Non-POSIX platforms lacking sigaction make do
1096 1105 with traditional calls to 'signal'; races are rare so this usually
1106 works. Although this approach may treat multiple deliveries of SIG
1107 as a single delivery and may act on signals in a different order
1108 than received, that is OK for emacsclient. Also, this approach may
1109 omit output if a printf call is interrupted by a signal, but printf
1110 output is not that important (emacsclient does not check for printf
1111 errors, after all) so this is also OK for emacsclient. */
1112
1113/* Reinstall for SIG the signal handler HANDLER if needed. It is
1114 needed on a non-POSIX or traditional platform where an interrupt
1115 resets the signal handler to SIG_DFL. */
1097static void 1116static void
1098pass_signal_to_emacs (int signalnum) 1117reinstall_handler_if_needed (int sig, void (*handler) (int))
1099{ 1118{
1100 int old_errno = errno; 1119# ifndef SA_RESETHAND
1120 /* This is a platform without POSIX's sigaction. */
1121 signal (sig, handler);
1122# endif
1123}
1101 1124
1102 if (emacs_pid) 1125/* Flags for each signal, and handlers that set the flags. */
1103 kill (emacs_pid, signalnum);
1104 1126
1105 signal (signalnum, pass_signal_to_emacs); 1127static sig_atomic_t volatile
1106 errno = old_errno; 1128 got_sigcont, got_sigtstp, got_sigttou, got_sigwinch;
1129
1130static void
1131handle_sigcont (int sig)
1132{
1133 got_sigcont = 1;
1134 reinstall_handler_if_needed (sig, handle_sigcont);
1135}
1136static void
1137handle_sigtstp (int sig)
1138{
1139 got_sigtstp = 1;
1140 reinstall_handler_if_needed (sig, handle_sigtstp);
1141}
1142static void
1143handle_sigttou (int sig)
1144{
1145 got_sigttou = 1;
1146 reinstall_handler_if_needed (sig, handle_sigttou);
1147}
1148static void
1149handle_sigwinch (int sig)
1150{
1151 got_sigwinch = 1;
1152 reinstall_handler_if_needed (sig, handle_sigwinch);
1107} 1153}
1108 1154
1109/* Signal handler for SIGCONT; notify the Emacs process that it can 1155/* Install for signal SIG the handler HANDLER. However, if FLAG is
1110 now resume our tty frame. */ 1156 non-null and if the signal is currently being ignored, do not
1157 install the handler and keep *FLAG zero. */
1111 1158
1112static void 1159static void
1113handle_sigcont (int signalnum) 1160install_handler (int sig, void (*handler) (int), sig_atomic_t volatile *flag)
1114{ 1161{
1115 int old_errno = errno; 1162# ifdef SA_RESETHAND
1116 pid_t pgrp = getpgrp (); 1163 if (flag)
1117 pid_t tcpgrp = tcgetpgrp (STDOUT_FILENO);
1118
1119 if (tcpgrp == pgrp)
1120 { 1164 {
1121 /* We are in the foreground. */ 1165 struct sigaction oact;
1122 send_to_emacs (emacs_socket, "-resume \n"); 1166 if (sigaction (sig, NULL, &oact) == 0 && oact.sa_handler == SIG_IGN)
1167 return;
1123 } 1168 }
1124 else if (0 <= tcpgrp && tty) 1169 struct sigaction act = { .sa_handler = handler };
1170 sigemptyset (&act.sa_mask);
1171 sigaction (sig, &act, NULL);
1172# else
1173 void (*ohandler) (int) = signal (sig, handler);
1174 if (flag)
1125 { 1175 {
1126 /* We are in the background; cancel the continue. */ 1176 if (ohandler == SIG_IGN)
1127 kill (-pgrp, SIGTTIN); 1177 {
1178 signal (sig, SIG_IGN);
1179 /* While HANDLER was mistakenly installed a signal may have
1180 arrived and set *FLAG, so clear *FLAG now. */
1181 *flag = 0;
1182 }
1128 } 1183 }
1129 1184# endif
1130 signal (signalnum, handle_sigcont);
1131 errno = old_errno;
1132} 1185}
1133 1186
1134/* Signal handler for SIGTSTP; notify the Emacs process that we are 1187/* Initial installation of signal handlers. */
1135 going to sleep. Normally the suspend is initiated by Emacs via
1136 server-handle-suspend-tty, but if the server gets out of sync with
1137 reality, we may get a SIGTSTP on C-z. Handling this signal and
1138 notifying Emacs about it should get things under control again. */
1139 1188
1140static void 1189static void
1141handle_sigtstp (int signalnum) 1190init_signals (void)
1142{ 1191{
1143 int old_errno = errno; 1192 install_handler (SIGCONT, handle_sigcont, &got_sigcont);
1144 sigset_t set; 1193 install_handler (SIGTSTP, handle_sigtstp, &got_sigtstp);
1145 1194 install_handler (SIGTTOU, handle_sigttou, &got_sigttou);
1146 if (emacs_socket) 1195 install_handler (SIGWINCH, handle_sigwinch, &got_sigwinch);
1147 send_to_emacs (emacs_socket, "-suspend \n"); 1196 /* Don't mess with SIGINT and SIGQUIT, as Emacs has no way to
1148 1197 determine which terminal the signal came from. C-g is a normal
1149 /* Unblock this signal and call the default handler by temporarily 1198 input event on secondary terminals. */
1150 changing the handler and resignaling. */
1151 sigprocmask (SIG_BLOCK, NULL, &set);
1152 sigdelset (&set, signalnum);
1153 signal (signalnum, SIG_DFL);
1154 raise (signalnum);
1155 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
1156 signal (signalnum, handle_sigtstp);
1157
1158 errno = old_errno;
1159} 1199}
1160 1200
1201/* Act on delivered tty-related signal SIG that normally has handler
1202 HANDLER. EMACS_SOCKET connects to Emacs. */
1161 1203
1162/* Set up signal handlers before opening a frame on the current tty. */ 1204static void
1205act_on_tty_signal (int sig, void (*handler) (int), HSOCKET emacs_socket)
1206{
1207 /* Notify Emacs that we are going to sleep. Normally the suspend is
1208 initiated by Emacs via server-handle-suspend-tty, but if the
1209 server gets out of sync with reality, we may get a SIGTSTP on
1210 C-z. Handling this signal and notifying Emacs about it should
1211 get things under control again. */
1212 send_to_emacs (emacs_socket, "-suspend \n");
1213
1214 /* Execute the default action by temporarily changing handling to
1215 the default and resignaling. */
1216 install_handler (sig, SIG_DFL, NULL);
1217 raise (sig);
1218 install_handler (sig, handler, NULL);
1219}
1220
1221/* Act on delivered signals if possible. If EMACS_SOCKET is valid,
1222 use it to communicate to Emacs. */
1163 1223
1164static void 1224static void
1165init_signals (void) 1225act_on_signals (HSOCKET emacs_socket)
1166{ 1226{
1167 /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of 1227 while (true)
1168 deciding which terminal the signal came from. C-g is now a 1228 {
1169 normal input event on secondary terminals. */ 1229 bool took_action = false;
1170 signal (SIGWINCH, pass_signal_to_emacs); 1230
1171 signal (SIGCONT, handle_sigcont); 1231 if (emacs_socket != INVALID_SOCKET)
1172 signal (SIGTSTP, handle_sigtstp); 1232 {
1173 signal (SIGTTOU, handle_sigtstp); 1233 if (got_sigcont)
1234 {
1235 got_sigcont = 0;
1236 took_action = true;
1237 pid_t tcpgrp = tcgetpgrp (STDOUT_FILENO);
1238 if (0 <= tcpgrp)
1239 {
1240 pid_t pgrp = getpgrp ();
1241 if (tcpgrp == pgrp)
1242 {
1243 /* We are in the foreground. */
1244 send_to_emacs (emacs_socket, "-resume \n");
1245 }
1246 else if (tty)
1247 {
1248 /* We are in the background; cancel the continue. */
1249 kill (-pgrp, SIGTTIN);
1250 }
1251 }
1252 }
1253
1254 if (got_sigtstp)
1255 {
1256 got_sigtstp = 0;
1257 took_action = true;
1258 act_on_tty_signal (SIGTSTP, handle_sigtstp, emacs_socket);
1259 }
1260 if (got_sigttou)
1261 {
1262 got_sigttou = 0;
1263 took_action = true;
1264 act_on_tty_signal (SIGTTOU, handle_sigttou, emacs_socket);
1265 }
1266 }
1267
1268 if (emacs_pid && got_sigwinch)
1269 {
1270 got_sigwinch = 0;
1271 took_action = true;
1272 kill (emacs_pid, SIGWINCH);
1273 }
1274
1275 if (!took_action)
1276 break;
1277 }
1174} 1278}
1175 1279
1176/* Create a local socket and connect it to Emacs. */ 1280/* Create a local socket and connect it to Emacs. */
@@ -1464,7 +1568,7 @@ w32_give_focus (void)
1464 1568
1465/* Start the emacs daemon and try to connect to it. */ 1569/* Start the emacs daemon and try to connect to it. */
1466 1570
1467static void 1571static HSOCKET
1468start_daemon_and_retry_set_socket (void) 1572start_daemon_and_retry_set_socket (void)
1469{ 1573{
1470# ifndef WINDOWSNT 1574# ifndef WINDOWSNT
@@ -1581,13 +1685,23 @@ start_daemon_and_retry_set_socket (void)
1581 "Emacs daemon should have started, trying to connect again\n"); 1685 "Emacs daemon should have started, trying to connect again\n");
1582# endif /* WINDOWSNT */ 1686# endif /* WINDOWSNT */
1583 1687
1584 emacs_socket = set_socket (true); 1688 HSOCKET emacs_socket = set_socket (true);
1585 if (emacs_socket == INVALID_SOCKET) 1689 if (emacs_socket == INVALID_SOCKET)
1586 { 1690 {
1587 message (true, 1691 message (true,
1588 "Error: Cannot connect even after starting the Emacs daemon\n"); 1692 "Error: Cannot connect even after starting the Emacs daemon\n");
1589 exit (EXIT_FAILURE); 1693 exit (EXIT_FAILURE);
1590 } 1694 }
1695 return emacs_socket;
1696}
1697
1698/* Flush standard output and its underlying file descriptor. */
1699static void
1700flush_stdout (HSOCKET emacs_socket)
1701{
1702 fflush (stdout);
1703 while (fdatasync (STDOUT_FILENO) != 0 && errno == EINTR)
1704 act_on_signals (emacs_socket);
1591} 1705}
1592#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */ 1706#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
1593 1707
@@ -1641,13 +1755,14 @@ main (int argc, char **argv)
1641 in case of failure to connect. */ 1755 in case of failure to connect. */
1642 bool start_daemon_if_needed = alternate_editor && !alternate_editor[0]; 1756 bool start_daemon_if_needed = alternate_editor && !alternate_editor[0];
1643 1757
1644 emacs_socket = set_socket (alternate_editor || start_daemon_if_needed); 1758 HSOCKET emacs_socket = set_socket (alternate_editor
1759 || start_daemon_if_needed);
1645 if (emacs_socket == INVALID_SOCKET) 1760 if (emacs_socket == INVALID_SOCKET)
1646 { 1761 {
1647 if (! start_daemon_if_needed) 1762 if (! start_daemon_if_needed)
1648 fail (); 1763 fail ();
1649 1764
1650 start_daemon_and_retry_set_socket (); 1765 emacs_socket = start_daemon_and_retry_set_socket ();
1651 } 1766 }
1652 1767
1653 char *cwd = get_current_dir_name (); 1768 char *cwd = get_current_dir_name ();
@@ -1719,6 +1834,8 @@ main (int argc, char **argv)
1719 if (find_tty (&tty_type, &tty_name, !tty)) 1834 if (find_tty (&tty_type, &tty_name, !tty))
1720 { 1835 {
1721# ifndef NO_SOCKETS_IN_FILE_SYSTEM 1836# ifndef NO_SOCKETS_IN_FILE_SYSTEM
1837 /* Install signal handlers before opening a frame on the
1838 current tty. */
1722 init_signals (); 1839 init_signals ();
1723# endif 1840# endif
1724 send_to_emacs (emacs_socket, "-tty "); 1841 send_to_emacs (emacs_socket, "-tty ");
@@ -1809,20 +1926,16 @@ main (int argc, char **argv)
1809 printf ("Waiting for Emacs..."); 1926 printf ("Waiting for Emacs...");
1810 skiplf = false; 1927 skiplf = false;
1811 } 1928 }
1812 fflush (stdout); 1929 flush_stdout (emacs_socket);
1813 while (fdatasync (STDOUT_FILENO) != 0 && errno == EINTR)
1814 continue;
1815 1930
1816 /* Now, wait for an answer and print any messages. */ 1931 /* Now, wait for an answer and print any messages. */
1817 while (exit_status == EXIT_SUCCESS) 1932 while (exit_status == EXIT_SUCCESS)
1818 { 1933 {
1819 do 1934 do
1820 { 1935 {
1821 errno = 0; 1936 act_on_signals (emacs_socket);
1822 rl = recv (emacs_socket, string, BUFSIZ, 0); 1937 rl = recv (emacs_socket, string, BUFSIZ, 0);
1823 } 1938 }
1824 /* If we receive a signal (e.g. SIGWINCH, which we pass
1825 through to Emacs), on some OSes we get EINTR and must retry. */
1826 while (rl < 0 && errno == EINTR); 1939 while (rl < 0 && errno == EINTR);
1827 1940
1828 if (rl <= 0) 1941 if (rl <= 0)
@@ -1916,9 +2029,7 @@ main (int argc, char **argv)
1916 2029
1917 if (!skiplf) 2030 if (!skiplf)
1918 printf ("\n"); 2031 printf ("\n");
1919 fflush (stdout); 2032 flush_stdout (emacs_socket);
1920 while (fdatasync (STDOUT_FILENO) != 0 && errno == EINTR)
1921 continue;
1922 2033
1923 if (rl < 0) 2034 if (rl < 0)
1924 exit_status = EXIT_FAILURE; 2035 exit_status = EXIT_FAILURE;