diff options
Diffstat (limited to 'lib-src/emacsclient.c')
| -rw-r--r-- | lib-src/emacsclient.c | 334 |
1 files changed, 178 insertions, 156 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 2af139aee6d..049886ed2ba 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Client process that communicates with GNU Emacs acting as server. | 1 | /* Client process that communicates with GNU Emacs acting as server. |
| 2 | Copyright (C) 1986-1987, 1994, 1999-2011 Free Software Foundation, Inc. | 2 | Copyright (C) 1986-1987, 1994, 1999-2012 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -152,7 +152,7 @@ int tty = 0; | |||
| 152 | const char *alternate_editor = NULL; | 152 | const char *alternate_editor = NULL; |
| 153 | 153 | ||
| 154 | /* If non-NULL, the filename of the UNIX socket. */ | 154 | /* If non-NULL, the filename of the UNIX socket. */ |
| 155 | char *socket_name = NULL; | 155 | const char *socket_name = NULL; |
| 156 | 156 | ||
| 157 | /* If non-NULL, the filename of the authentication file. */ | 157 | /* If non-NULL, the filename of the authentication file. */ |
| 158 | const char *server_file = NULL; | 158 | const char *server_file = NULL; |
| @@ -194,10 +194,10 @@ struct option longopts[] = | |||
| 194 | 194 | ||
| 195 | /* Like malloc but get fatal error if memory is exhausted. */ | 195 | /* Like malloc but get fatal error if memory is exhausted. */ |
| 196 | 196 | ||
| 197 | static long * | 197 | static void * |
| 198 | xmalloc (unsigned int size) | 198 | xmalloc (size_t size) |
| 199 | { | 199 | { |
| 200 | long *result = (long *) malloc (size); | 200 | void *result = malloc (size); |
| 201 | if (result == NULL) | 201 | if (result == NULL) |
| 202 | { | 202 | { |
| 203 | perror ("malloc"); | 203 | perror ("malloc"); |
| @@ -250,32 +250,33 @@ get_current_dir_name (void) | |||
| 250 | ) | 250 | ) |
| 251 | { | 251 | { |
| 252 | buf = (char *) xmalloc (strlen (pwd) + 1); | 252 | buf = (char *) xmalloc (strlen (pwd) + 1); |
| 253 | if (!buf) | ||
| 254 | return NULL; | ||
| 255 | strcpy (buf, pwd); | 253 | strcpy (buf, pwd); |
| 256 | } | 254 | } |
| 257 | #ifdef HAVE_GETCWD | 255 | #ifdef HAVE_GETCWD |
| 258 | else | 256 | else |
| 259 | { | 257 | { |
| 260 | size_t buf_size = 1024; | 258 | size_t buf_size = 1024; |
| 261 | buf = (char *) xmalloc (buf_size); | ||
| 262 | if (!buf) | ||
| 263 | return NULL; | ||
| 264 | for (;;) | 259 | for (;;) |
| 265 | { | 260 | { |
| 261 | int tmp_errno; | ||
| 262 | buf = malloc (buf_size); | ||
| 263 | if (! buf) | ||
| 264 | break; | ||
| 266 | if (getcwd (buf, buf_size) == buf) | 265 | if (getcwd (buf, buf_size) == buf) |
| 267 | break; | 266 | break; |
| 268 | if (errno != ERANGE) | 267 | tmp_errno = errno; |
| 268 | free (buf); | ||
| 269 | if (tmp_errno != ERANGE) | ||
| 269 | { | 270 | { |
| 270 | int tmp_errno = errno; | ||
| 271 | free (buf); | ||
| 272 | errno = tmp_errno; | 271 | errno = tmp_errno; |
| 273 | return NULL; | 272 | return NULL; |
| 274 | } | 273 | } |
| 275 | buf_size *= 2; | 274 | buf_size *= 2; |
| 276 | buf = (char *) realloc (buf, buf_size); | 275 | if (! buf_size) |
| 277 | if (!buf) | 276 | { |
| 278 | return NULL; | 277 | errno = ENOMEM; |
| 278 | return NULL; | ||
| 279 | } | ||
| 279 | } | 280 | } |
| 280 | } | 281 | } |
| 281 | #else | 282 | #else |
| @@ -283,8 +284,6 @@ get_current_dir_name (void) | |||
| 283 | { | 284 | { |
| 284 | /* We need MAXPATHLEN here. */ | 285 | /* We need MAXPATHLEN here. */ |
| 285 | buf = (char *) xmalloc (MAXPATHLEN + 1); | 286 | buf = (char *) xmalloc (MAXPATHLEN + 1); |
| 286 | if (!buf) | ||
| 287 | return NULL; | ||
| 288 | if (getwd (buf) == NULL) | 287 | if (getwd (buf) == NULL) |
| 289 | { | 288 | { |
| 290 | int tmp_errno = errno; | 289 | int tmp_errno = errno; |
| @@ -360,7 +359,7 @@ w32_getenv (char *envvar) | |||
| 360 | char *value; | 359 | char *value; |
| 361 | DWORD dwType; | 360 | DWORD dwType; |
| 362 | 361 | ||
| 363 | if (value = getenv (envvar)) | 362 | if ((value = getenv (envvar))) |
| 364 | /* Found in the environment. strdup it, because values returned | 363 | /* Found in the environment. strdup it, because values returned |
| 365 | by getenv cannot be free'd. */ | 364 | by getenv cannot be free'd. */ |
| 366 | return xstrdup (value); | 365 | return xstrdup (value); |
| @@ -383,7 +382,7 @@ w32_getenv (char *envvar) | |||
| 383 | { | 382 | { |
| 384 | DWORD size; | 383 | DWORD size; |
| 385 | 384 | ||
| 386 | if (size = ExpandEnvironmentStrings (value, NULL, 0)) | 385 | if ((size = ExpandEnvironmentStrings (value, NULL, 0))) |
| 387 | { | 386 | { |
| 388 | char *buffer = (char *) xmalloc (size); | 387 | char *buffer = (char *) xmalloc (size); |
| 389 | if (ExpandEnvironmentStrings (value, buffer, size)) | 388 | if (ExpandEnvironmentStrings (value, buffer, size)) |
| @@ -494,16 +493,17 @@ static void message (int, const char *, ...) ATTRIBUTE_FORMAT_PRINTF (2, 3); | |||
| 494 | static void | 493 | static void |
| 495 | message (int is_error, const char *format, ...) | 494 | message (int is_error, const char *format, ...) |
| 496 | { | 495 | { |
| 497 | char msg[2048]; | ||
| 498 | va_list args; | 496 | va_list args; |
| 499 | 497 | ||
| 500 | va_start (args, format); | 498 | va_start (args, format); |
| 501 | vsprintf (msg, format, args); | ||
| 502 | va_end (args); | ||
| 503 | 499 | ||
| 504 | #ifdef WINDOWSNT | 500 | #ifdef WINDOWSNT |
| 505 | if (w32_window_app ()) | 501 | if (w32_window_app ()) |
| 506 | { | 502 | { |
| 503 | char msg[2048]; | ||
| 504 | vsnprintf (msg, sizeof msg, format, args); | ||
| 505 | msg[sizeof msg - 1] = '\0'; | ||
| 506 | |||
| 507 | if (is_error) | 507 | if (is_error) |
| 508 | MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR); | 508 | MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR); |
| 509 | else | 509 | else |
| @@ -514,9 +514,11 @@ message (int is_error, const char *format, ...) | |||
| 514 | { | 514 | { |
| 515 | FILE *f = is_error ? stderr : stdout; | 515 | FILE *f = is_error ? stderr : stdout; |
| 516 | 516 | ||
| 517 | fputs (msg, f); | 517 | vfprintf (f, format, args); |
| 518 | fflush (f); | 518 | fflush (f); |
| 519 | } | 519 | } |
| 520 | |||
| 521 | va_end (args); | ||
| 520 | } | 522 | } |
| 521 | 523 | ||
| 522 | /* Decode the options from argv and argc. | 524 | /* Decode the options from argv and argc. |
| @@ -636,6 +638,22 @@ decode_options (int argc, char **argv) | |||
| 636 | if (display && strlen (display) == 0) | 638 | if (display && strlen (display) == 0) |
| 637 | display = NULL; | 639 | display = NULL; |
| 638 | 640 | ||
| 641 | #ifdef WINDOWSNT | ||
| 642 | /* Emacs on Windows does not support GUI and console frames in the same | ||
| 643 | instance. So, it makes sense to treat the -t and -c options as | ||
| 644 | equivalent, and open a new frame regardless of whether the running | ||
| 645 | instance is GUI or console. Ideally, we would only set tty = 1 when | ||
| 646 | the instance is running in a console, but alas we don't know that. | ||
| 647 | The simplest workaround is to always ask for a tty frame, and let | ||
| 648 | server.el check whether it makes sense. */ | ||
| 649 | if (tty || !current_frame) | ||
| 650 | { | ||
| 651 | display = (const char *) ttyname; | ||
| 652 | current_frame = 0; | ||
| 653 | tty = 1; | ||
| 654 | } | ||
| 655 | #endif | ||
| 656 | |||
| 639 | /* If no display is available, new frames are tty frames. */ | 657 | /* If no display is available, new frames are tty frames. */ |
| 640 | if (!current_frame && !display) | 658 | if (!current_frame && !display) |
| 641 | tty = 1; | 659 | tty = 1; |
| @@ -652,14 +670,6 @@ decode_options (int argc, char **argv) | |||
| 652 | an empty string"); | 670 | an empty string"); |
| 653 | exit (EXIT_FAILURE); | 671 | exit (EXIT_FAILURE); |
| 654 | } | 672 | } |
| 655 | |||
| 656 | /* TTY frames not supported on Windows. Continue using GUI rather than | ||
| 657 | forcing the user to change their command-line. This is required since | ||
| 658 | tty is set above if certain options are given and $DISPLAY is not set, | ||
| 659 | which is not obvious to users. */ | ||
| 660 | if (tty) | ||
| 661 | tty = 0; | ||
| 662 | |||
| 663 | #endif /* WINDOWSNT */ | 673 | #endif /* WINDOWSNT */ |
| 664 | } | 674 | } |
| 665 | 675 | ||
| @@ -945,32 +955,39 @@ initialize_sockets (void) | |||
| 945 | * the Emacs server: host, port, and authentication string. | 955 | * the Emacs server: host, port, and authentication string. |
| 946 | */ | 956 | */ |
| 947 | static int | 957 | static int |
| 948 | get_server_config (struct sockaddr_in *server, char *authentication) | 958 | get_server_config (const char *config_file, struct sockaddr_in *server, |
| 959 | char *authentication) | ||
| 949 | { | 960 | { |
| 950 | char dotted[32]; | 961 | char dotted[32]; |
| 951 | char *port; | 962 | char *port; |
| 952 | FILE *config = NULL; | 963 | FILE *config = NULL; |
| 953 | 964 | ||
| 954 | if (file_name_absolute_p (server_file)) | 965 | if (file_name_absolute_p (config_file)) |
| 955 | config = fopen (server_file, "rb"); | 966 | config = fopen (config_file, "rb"); |
| 956 | else | 967 | else |
| 957 | { | 968 | { |
| 958 | const char *home = egetenv ("HOME"); | 969 | const char *home = egetenv ("HOME"); |
| 959 | 970 | ||
| 960 | if (home) | 971 | if (home) |
| 961 | { | 972 | { |
| 962 | char *path = alloca (strlen (home) + strlen (server_file) | 973 | char *path = xmalloc (strlen (home) + strlen (config_file) |
| 963 | + EXTRA_SPACE); | 974 | + EXTRA_SPACE); |
| 964 | sprintf (path, "%s/.emacs.d/server/%s", home, server_file); | 975 | strcpy (path, home); |
| 976 | strcat (path, "/.emacs.d/server/"); | ||
| 977 | strcat (path, config_file); | ||
| 965 | config = fopen (path, "rb"); | 978 | config = fopen (path, "rb"); |
| 979 | free (path); | ||
| 966 | } | 980 | } |
| 967 | #ifdef WINDOWSNT | 981 | #ifdef WINDOWSNT |
| 968 | if (!config && (home = egetenv ("APPDATA"))) | 982 | if (!config && (home = egetenv ("APPDATA"))) |
| 969 | { | 983 | { |
| 970 | char *path = alloca (strlen (home) + strlen (server_file) | 984 | char *path = xmalloc (strlen (home) + strlen (config_file) |
| 971 | + EXTRA_SPACE); | 985 | + EXTRA_SPACE); |
| 972 | sprintf (path, "%s/.emacs.d/server/%s", home, server_file); | 986 | strcpy (path, home); |
| 987 | strcat (path, "/.emacs.d/server/"); | ||
| 988 | strcat (path, config_file); | ||
| 973 | config = fopen (path, "rb"); | 989 | config = fopen (path, "rb"); |
| 990 | free (path); | ||
| 974 | } | 991 | } |
| 975 | #endif | 992 | #endif |
| 976 | } | 993 | } |
| @@ -1003,14 +1020,14 @@ get_server_config (struct sockaddr_in *server, char *authentication) | |||
| 1003 | } | 1020 | } |
| 1004 | 1021 | ||
| 1005 | static HSOCKET | 1022 | static HSOCKET |
| 1006 | set_tcp_socket (void) | 1023 | set_tcp_socket (const char *local_server_file) |
| 1007 | { | 1024 | { |
| 1008 | HSOCKET s; | 1025 | HSOCKET s; |
| 1009 | struct sockaddr_in server; | 1026 | struct sockaddr_in server; |
| 1010 | struct linger l_arg = {1, 1}; | 1027 | struct linger l_arg = {1, 1}; |
| 1011 | char auth_string[AUTH_KEY_LENGTH + 1]; | 1028 | char auth_string[AUTH_KEY_LENGTH + 1]; |
| 1012 | 1029 | ||
| 1013 | if (! get_server_config (&server, auth_string)) | 1030 | if (! get_server_config (local_server_file, &server, auth_string)) |
| 1014 | return INVALID_SOCKET; | 1031 | return INVALID_SOCKET; |
| 1015 | 1032 | ||
| 1016 | if (server.sin_addr.s_addr != inet_addr ("127.0.0.1") && !quiet) | 1033 | if (server.sin_addr.s_addr != inet_addr ("127.0.0.1") && !quiet) |
| @@ -1185,7 +1202,7 @@ handle_sigtstp (int signalnum) | |||
| 1185 | send_to_emacs (emacs_socket, "-suspend \n"); | 1202 | send_to_emacs (emacs_socket, "-suspend \n"); |
| 1186 | 1203 | ||
| 1187 | /* Unblock this signal and call the default handler by temporarily | 1204 | /* Unblock this signal and call the default handler by temporarily |
| 1188 | changing the handler and resignalling. */ | 1205 | changing the handler and resignaling. */ |
| 1189 | sigprocmask (SIG_BLOCK, NULL, &set); | 1206 | sigprocmask (SIG_BLOCK, NULL, &set); |
| 1190 | sigdelset (&set, signalnum); | 1207 | sigdelset (&set, signalnum); |
| 1191 | signal (signalnum, SIG_DFL); | 1208 | signal (signalnum, SIG_DFL); |
| @@ -1220,7 +1237,7 @@ init_signals (void) | |||
| 1220 | 1237 | ||
| 1221 | 1238 | ||
| 1222 | static HSOCKET | 1239 | static HSOCKET |
| 1223 | set_local_socket (void) | 1240 | set_local_socket (const char *local_socket_name) |
| 1224 | { | 1241 | { |
| 1225 | HSOCKET s; | 1242 | HSOCKET s; |
| 1226 | struct sockaddr_un server; | 1243 | struct sockaddr_un server; |
| @@ -1238,23 +1255,20 @@ set_local_socket (void) | |||
| 1238 | server.sun_family = AF_UNIX; | 1255 | server.sun_family = AF_UNIX; |
| 1239 | 1256 | ||
| 1240 | { | 1257 | { |
| 1241 | int sock_status = 0; | 1258 | int sock_status; |
| 1242 | int default_sock = !socket_name; | 1259 | int use_tmpdir = 0; |
| 1243 | int saved_errno = 0; | 1260 | int saved_errno; |
| 1244 | const char *server_name = "server"; | 1261 | const char *server_name = local_socket_name; |
| 1245 | const char *tmpdir IF_LINT ( = NULL); | 1262 | const char *tmpdir IF_LINT ( = NULL); |
| 1263 | char *tmpdir_storage = NULL; | ||
| 1264 | char *socket_name_storage = NULL; | ||
| 1246 | 1265 | ||
| 1247 | if (socket_name && !strchr (socket_name, '/') | 1266 | if (!strchr (local_socket_name, '/') && !strchr (local_socket_name, '\\')) |
| 1248 | && !strchr (socket_name, '\\')) | ||
| 1249 | { | 1267 | { |
| 1250 | /* socket_name is a file name component. */ | 1268 | /* socket_name is a file name component. */ |
| 1251 | server_name = socket_name; | 1269 | long uid = geteuid (); |
| 1252 | socket_name = NULL; | 1270 | ptrdiff_t tmpdirlen; |
| 1253 | default_sock = 1; /* Try both UIDs. */ | 1271 | use_tmpdir = 1; |
| 1254 | } | ||
| 1255 | |||
| 1256 | if (default_sock) | ||
| 1257 | { | ||
| 1258 | tmpdir = egetenv ("TMPDIR"); | 1272 | tmpdir = egetenv ("TMPDIR"); |
| 1259 | if (!tmpdir) | 1273 | if (!tmpdir) |
| 1260 | { | 1274 | { |
| @@ -1265,32 +1279,35 @@ set_local_socket (void) | |||
| 1265 | size_t n = confstr (_CS_DARWIN_USER_TEMP_DIR, NULL, (size_t) 0); | 1279 | size_t n = confstr (_CS_DARWIN_USER_TEMP_DIR, NULL, (size_t) 0); |
| 1266 | if (n > 0) | 1280 | if (n > 0) |
| 1267 | { | 1281 | { |
| 1268 | tmpdir = alloca (n); | 1282 | tmpdir = tmpdir_storage = xmalloc (n); |
| 1269 | confstr (_CS_DARWIN_USER_TEMP_DIR, tmpdir, n); | 1283 | confstr (_CS_DARWIN_USER_TEMP_DIR, tmpdir, n); |
| 1270 | } | 1284 | } |
| 1271 | else | 1285 | else |
| 1272 | #endif | 1286 | #endif |
| 1273 | tmpdir = "/tmp"; | 1287 | tmpdir = "/tmp"; |
| 1274 | } | 1288 | } |
| 1275 | socket_name = alloca (strlen (tmpdir) + strlen (server_name) | 1289 | tmpdirlen = strlen (tmpdir); |
| 1276 | + EXTRA_SPACE); | 1290 | socket_name_storage = |
| 1277 | sprintf (socket_name, "%s/emacs%d/%s", | 1291 | xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE); |
| 1278 | tmpdir, (int) geteuid (), server_name); | 1292 | strcpy (socket_name_storage, tmpdir); |
| 1293 | sprintf (socket_name_storage + tmpdirlen, "/emacs%ld/", uid); | ||
| 1294 | strcat (socket_name_storage + tmpdirlen, server_name); | ||
| 1295 | local_socket_name = socket_name_storage; | ||
| 1279 | } | 1296 | } |
| 1280 | 1297 | ||
| 1281 | if (strlen (socket_name) < sizeof (server.sun_path)) | 1298 | if (strlen (local_socket_name) < sizeof (server.sun_path)) |
| 1282 | strcpy (server.sun_path, socket_name); | 1299 | strcpy (server.sun_path, local_socket_name); |
| 1283 | else | 1300 | else |
| 1284 | { | 1301 | { |
| 1285 | message (TRUE, "%s: socket-name %s too long\n", | 1302 | message (TRUE, "%s: socket-name %s too long\n", |
| 1286 | progname, socket_name); | 1303 | progname, local_socket_name); |
| 1287 | fail (); | 1304 | fail (); |
| 1288 | } | 1305 | } |
| 1289 | 1306 | ||
| 1290 | /* See if the socket exists, and if it's owned by us. */ | 1307 | /* See if the socket exists, and if it's owned by us. */ |
| 1291 | sock_status = socket_status (server.sun_path); | 1308 | sock_status = socket_status (server.sun_path); |
| 1292 | saved_errno = errno; | 1309 | saved_errno = errno; |
| 1293 | if (sock_status && default_sock) | 1310 | if (sock_status && use_tmpdir) |
| 1294 | { | 1311 | { |
| 1295 | /* Failing that, see if LOGNAME or USER exist and differ from | 1312 | /* Failing that, see if LOGNAME or USER exist and differ from |
| 1296 | our euid. If so, look for a socket based on the UID | 1313 | our euid. If so, look for a socket based on the UID |
| @@ -1309,19 +1326,23 @@ set_local_socket (void) | |||
| 1309 | if (pw && (pw->pw_uid != geteuid ())) | 1326 | if (pw && (pw->pw_uid != geteuid ())) |
| 1310 | { | 1327 | { |
| 1311 | /* We're running under su, apparently. */ | 1328 | /* We're running under su, apparently. */ |
| 1312 | socket_name = alloca (strlen (tmpdir) + strlen (server_name) | 1329 | long uid = pw->pw_uid; |
| 1313 | + EXTRA_SPACE); | 1330 | ptrdiff_t tmpdirlen = strlen (tmpdir); |
| 1314 | sprintf (socket_name, "%s/emacs%d/%s", | 1331 | char *user_socket_name |
| 1315 | tmpdir, (int) pw->pw_uid, server_name); | 1332 | = xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE); |
| 1316 | 1333 | strcpy (user_socket_name, tmpdir); | |
| 1317 | if (strlen (socket_name) < sizeof (server.sun_path)) | 1334 | sprintf (user_socket_name + tmpdirlen, "/emacs%ld/", uid); |
| 1318 | strcpy (server.sun_path, socket_name); | 1335 | strcat (user_socket_name + tmpdirlen, server_name); |
| 1336 | |||
| 1337 | if (strlen (user_socket_name) < sizeof (server.sun_path)) | ||
| 1338 | strcpy (server.sun_path, user_socket_name); | ||
| 1319 | else | 1339 | else |
| 1320 | { | 1340 | { |
| 1321 | message (TRUE, "%s: socket-name %s too long\n", | 1341 | message (TRUE, "%s: socket-name %s too long\n", |
| 1322 | progname, socket_name); | 1342 | progname, user_socket_name); |
| 1323 | exit (EXIT_FAILURE); | 1343 | exit (EXIT_FAILURE); |
| 1324 | } | 1344 | } |
| 1345 | free (user_socket_name); | ||
| 1325 | 1346 | ||
| 1326 | sock_status = socket_status (server.sun_path); | 1347 | sock_status = socket_status (server.sun_path); |
| 1327 | saved_errno = errno; | 1348 | saved_errno = errno; |
| @@ -1331,6 +1352,9 @@ set_local_socket (void) | |||
| 1331 | } | 1352 | } |
| 1332 | } | 1353 | } |
| 1333 | 1354 | ||
| 1355 | free (socket_name_storage); | ||
| 1356 | free (tmpdir_storage); | ||
| 1357 | |||
| 1334 | switch (sock_status) | 1358 | switch (sock_status) |
| 1335 | { | 1359 | { |
| 1336 | case 1: | 1360 | case 1: |
| @@ -1372,6 +1396,7 @@ static HSOCKET | |||
| 1372 | set_socket (int no_exit_if_error) | 1396 | set_socket (int no_exit_if_error) |
| 1373 | { | 1397 | { |
| 1374 | HSOCKET s; | 1398 | HSOCKET s; |
| 1399 | const char *local_server_file = server_file; | ||
| 1375 | 1400 | ||
| 1376 | INITIALIZE (); | 1401 | INITIALIZE (); |
| 1377 | 1402 | ||
| @@ -1379,7 +1404,7 @@ set_socket (int no_exit_if_error) | |||
| 1379 | /* Explicit --socket-name argument. */ | 1404 | /* Explicit --socket-name argument. */ |
| 1380 | if (socket_name) | 1405 | if (socket_name) |
| 1381 | { | 1406 | { |
| 1382 | s = set_local_socket (); | 1407 | s = set_local_socket (socket_name); |
| 1383 | if ((s != INVALID_SOCKET) || no_exit_if_error) | 1408 | if ((s != INVALID_SOCKET) || no_exit_if_error) |
| 1384 | return s; | 1409 | return s; |
| 1385 | message (TRUE, "%s: error accessing socket \"%s\"\n", | 1410 | message (TRUE, "%s: error accessing socket \"%s\"\n", |
| @@ -1389,30 +1414,29 @@ set_socket (int no_exit_if_error) | |||
| 1389 | #endif | 1414 | #endif |
| 1390 | 1415 | ||
| 1391 | /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */ | 1416 | /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */ |
| 1392 | if (!server_file) | 1417 | if (!local_server_file) |
| 1393 | server_file = egetenv ("EMACS_SERVER_FILE"); | 1418 | local_server_file = egetenv ("EMACS_SERVER_FILE"); |
| 1394 | 1419 | ||
| 1395 | if (server_file) | 1420 | if (local_server_file) |
| 1396 | { | 1421 | { |
| 1397 | s = set_tcp_socket (); | 1422 | s = set_tcp_socket (local_server_file); |
| 1398 | if ((s != INVALID_SOCKET) || no_exit_if_error) | 1423 | if ((s != INVALID_SOCKET) || no_exit_if_error) |
| 1399 | return s; | 1424 | return s; |
| 1400 | 1425 | ||
| 1401 | message (TRUE, "%s: error accessing server file \"%s\"\n", | 1426 | message (TRUE, "%s: error accessing server file \"%s\"\n", |
| 1402 | progname, server_file); | 1427 | progname, local_server_file); |
| 1403 | exit (EXIT_FAILURE); | 1428 | exit (EXIT_FAILURE); |
| 1404 | } | 1429 | } |
| 1405 | 1430 | ||
| 1406 | #ifndef NO_SOCKETS_IN_FILE_SYSTEM | 1431 | #ifndef NO_SOCKETS_IN_FILE_SYSTEM |
| 1407 | /* Implicit local socket. */ | 1432 | /* Implicit local socket. */ |
| 1408 | s = set_local_socket (); | 1433 | s = set_local_socket ("server"); |
| 1409 | if (s != INVALID_SOCKET) | 1434 | if (s != INVALID_SOCKET) |
| 1410 | return s; | 1435 | return s; |
| 1411 | #endif | 1436 | #endif |
| 1412 | 1437 | ||
| 1413 | /* Implicit server file. */ | 1438 | /* Implicit server file. */ |
| 1414 | server_file = "server"; | 1439 | s = set_tcp_socket ("server"); |
| 1415 | s = set_tcp_socket (); | ||
| 1416 | if ((s != INVALID_SOCKET) || no_exit_if_error) | 1440 | if ((s != INVALID_SOCKET) || no_exit_if_error) |
| 1417 | return s; | 1441 | return s; |
| 1418 | 1442 | ||
| @@ -1526,8 +1550,8 @@ start_daemon_and_retry_set_socket (void) | |||
| 1526 | { | 1550 | { |
| 1527 | /* Pass --daemon=socket_name as argument. */ | 1551 | /* Pass --daemon=socket_name as argument. */ |
| 1528 | const char *deq = "--daemon="; | 1552 | const char *deq = "--daemon="; |
| 1529 | char *daemon_arg = alloca (strlen (deq) | 1553 | char *daemon_arg = xmalloc (strlen (deq) |
| 1530 | + strlen (socket_name) + 1); | 1554 | + strlen (socket_name) + 1); |
| 1531 | strcpy (daemon_arg, deq); | 1555 | strcpy (daemon_arg, deq); |
| 1532 | strcat (daemon_arg, socket_name); | 1556 | strcat (daemon_arg, socket_name); |
| 1533 | d_argv[1] = daemon_arg; | 1557 | d_argv[1] = daemon_arg; |
| @@ -1544,8 +1568,6 @@ main (int argc, char **argv) | |||
| 1544 | int rl = 0, needlf = 0; | 1568 | int rl = 0, needlf = 0; |
| 1545 | char *cwd, *str; | 1569 | char *cwd, *str; |
| 1546 | char string[BUFSIZ+1]; | 1570 | char string[BUFSIZ+1]; |
| 1547 | int null_socket_name IF_LINT ( = 0); | ||
| 1548 | int null_server_file IF_LINT ( = 0); | ||
| 1549 | int start_daemon_if_needed; | 1571 | int start_daemon_if_needed; |
| 1550 | int exit_status = EXIT_SUCCESS; | 1572 | int exit_status = EXIT_SUCCESS; |
| 1551 | 1573 | ||
| @@ -1573,14 +1595,6 @@ main (int argc, char **argv) | |||
| 1573 | in case of failure to connect. */ | 1595 | in case of failure to connect. */ |
| 1574 | start_daemon_if_needed = (alternate_editor | 1596 | start_daemon_if_needed = (alternate_editor |
| 1575 | && (alternate_editor[0] == '\0')); | 1597 | && (alternate_editor[0] == '\0')); |
| 1576 | if (start_daemon_if_needed) | ||
| 1577 | { | ||
| 1578 | /* set_socket changes the values for socket_name and | ||
| 1579 | server_file, we need to reset them, if they were NULL before | ||
| 1580 | for the second call to set_socket. */ | ||
| 1581 | null_socket_name = (socket_name == NULL); | ||
| 1582 | null_server_file = (server_file == NULL); | ||
| 1583 | } | ||
| 1584 | 1598 | ||
| 1585 | emacs_socket = set_socket (alternate_editor || start_daemon_if_needed); | 1599 | emacs_socket = set_socket (alternate_editor || start_daemon_if_needed); |
| 1586 | if (emacs_socket == INVALID_SOCKET) | 1600 | if (emacs_socket == INVALID_SOCKET) |
| @@ -1588,13 +1602,6 @@ main (int argc, char **argv) | |||
| 1588 | if (! start_daemon_if_needed) | 1602 | if (! start_daemon_if_needed) |
| 1589 | fail (); | 1603 | fail (); |
| 1590 | 1604 | ||
| 1591 | /* Reset socket_name and server_file if they were NULL | ||
| 1592 | before the set_socket call. */ | ||
| 1593 | if (null_socket_name) | ||
| 1594 | socket_name = NULL; | ||
| 1595 | if (null_server_file) | ||
| 1596 | server_file = NULL; | ||
| 1597 | |||
| 1598 | start_daemon_and_retry_set_socket (); | 1605 | start_daemon_and_retry_set_socket (); |
| 1599 | } | 1606 | } |
| 1600 | 1607 | ||
| @@ -1614,7 +1621,11 @@ main (int argc, char **argv) | |||
| 1614 | /* Send over our environment and current directory. */ | 1621 | /* Send over our environment and current directory. */ |
| 1615 | if (!current_frame) | 1622 | if (!current_frame) |
| 1616 | { | 1623 | { |
| 1624 | #ifndef WINDOWSNT | ||
| 1625 | /* This is defined in stdlib.h on MS-Windows. It's defined in | ||
| 1626 | unistd.h on some POSIX hosts, but not all (Bug#10155). */ | ||
| 1617 | extern char **environ; | 1627 | extern char **environ; |
| 1628 | #endif | ||
| 1618 | int i; | 1629 | int i; |
| 1619 | for (i = 0; environ[i]; i++) | 1630 | for (i = 0; environ[i]; i++) |
| 1620 | { | 1631 | { |
| @@ -1757,7 +1768,7 @@ main (int argc, char **argv) | |||
| 1757 | /* Now, wait for an answer and print any messages. */ | 1768 | /* Now, wait for an answer and print any messages. */ |
| 1758 | while (exit_status == EXIT_SUCCESS) | 1769 | while (exit_status == EXIT_SUCCESS) |
| 1759 | { | 1770 | { |
| 1760 | char *p; | 1771 | char *p, *end_p; |
| 1761 | do | 1772 | do |
| 1762 | { | 1773 | { |
| 1763 | errno = 0; | 1774 | errno = 0; |
| @@ -1772,61 +1783,72 @@ main (int argc, char **argv) | |||
| 1772 | 1783 | ||
| 1773 | string[rl] = '\0'; | 1784 | string[rl] = '\0'; |
| 1774 | 1785 | ||
| 1775 | p = string + strlen (string) - 1; | 1786 | /* Loop over all NL-terminated messages. */ |
| 1776 | while (p > string && *p == '\n') | 1787 | for (end_p = p = string; end_p != NULL && *end_p != '\0'; p = end_p) |
| 1777 | *p-- = 0; | 1788 | { |
| 1789 | end_p = strchr (p, '\n'); | ||
| 1790 | if (end_p != NULL) | ||
| 1791 | *end_p++ = '\0'; | ||
| 1778 | 1792 | ||
| 1779 | if (strprefix ("-emacs-pid ", string)) | 1793 | if (strprefix ("-emacs-pid ", p)) |
| 1780 | { | 1794 | { |
| 1781 | /* -emacs-pid PID: The process id of the Emacs process. */ | 1795 | /* -emacs-pid PID: The process id of the Emacs process. */ |
| 1782 | emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10); | 1796 | emacs_pid = strtol (p + strlen ("-emacs-pid"), NULL, 10); |
| 1783 | } | 1797 | } |
| 1784 | else if (strprefix ("-window-system-unsupported ", string)) | 1798 | else if (strprefix ("-window-system-unsupported ", p)) |
| 1785 | { | 1799 | { |
| 1786 | /* -window-system-unsupported: Emacs was compiled without X | 1800 | /* -window-system-unsupported: Emacs was compiled without X |
| 1787 | support. Try again on the terminal. */ | 1801 | support. Try again on the terminal. */ |
| 1788 | nowait = 0; | 1802 | nowait = 0; |
| 1789 | tty = 1; | 1803 | tty = 1; |
| 1790 | goto retry; | 1804 | goto retry; |
| 1791 | } | 1805 | } |
| 1792 | else if (strprefix ("-print ", string)) | 1806 | else if (strprefix ("-print ", p)) |
| 1793 | { | 1807 | { |
| 1794 | /* -print STRING: Print STRING on the terminal. */ | 1808 | /* -print STRING: Print STRING on the terminal. */ |
| 1795 | str = unquote_argument (string + strlen ("-print ")); | 1809 | str = unquote_argument (p + strlen ("-print ")); |
| 1796 | if (needlf) | 1810 | if (needlf) |
| 1797 | printf ("\n"); | 1811 | printf ("\n"); |
| 1798 | printf ("%s", str); | 1812 | printf ("%s", str); |
| 1799 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; | 1813 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; |
| 1800 | } | 1814 | } |
| 1801 | else if (strprefix ("-error ", string)) | 1815 | else if (strprefix ("-print-nonl ", p)) |
| 1802 | { | 1816 | { |
| 1803 | /* -error DESCRIPTION: Signal an error on the terminal. */ | 1817 | /* -print-nonl STRING: Print STRING on the terminal. |
| 1804 | str = unquote_argument (string + strlen ("-error ")); | 1818 | Used to continue a preceding -print command. */ |
| 1805 | if (needlf) | 1819 | str = unquote_argument (p + strlen ("-print-nonl ")); |
| 1806 | printf ("\n"); | 1820 | printf ("%s", str); |
| 1807 | fprintf (stderr, "*ERROR*: %s", str); | 1821 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; |
| 1808 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; | 1822 | } |
| 1809 | exit_status = EXIT_FAILURE; | 1823 | else if (strprefix ("-error ", p)) |
| 1810 | } | 1824 | { |
| 1825 | /* -error DESCRIPTION: Signal an error on the terminal. */ | ||
| 1826 | str = unquote_argument (p + strlen ("-error ")); | ||
| 1827 | if (needlf) | ||
| 1828 | printf ("\n"); | ||
| 1829 | fprintf (stderr, "*ERROR*: %s", str); | ||
| 1830 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; | ||
| 1831 | exit_status = EXIT_FAILURE; | ||
| 1832 | } | ||
| 1811 | #ifdef SIGSTOP | 1833 | #ifdef SIGSTOP |
| 1812 | else if (strprefix ("-suspend ", string)) | 1834 | else if (strprefix ("-suspend ", p)) |
| 1813 | { | 1835 | { |
| 1814 | /* -suspend: Suspend this terminal, i.e., stop the process. */ | 1836 | /* -suspend: Suspend this terminal, i.e., stop the process. */ |
| 1815 | if (needlf) | 1837 | if (needlf) |
| 1816 | printf ("\n"); | 1838 | printf ("\n"); |
| 1817 | needlf = 0; | 1839 | needlf = 0; |
| 1818 | kill (0, SIGSTOP); | 1840 | kill (0, SIGSTOP); |
| 1819 | } | 1841 | } |
| 1820 | #endif | 1842 | #endif |
| 1821 | else | 1843 | else |
| 1822 | { | 1844 | { |
| 1823 | /* Unknown command. */ | 1845 | /* Unknown command. */ |
| 1824 | if (needlf) | 1846 | if (needlf) |
| 1825 | printf ("\n"); | 1847 | printf ("\n"); |
| 1826 | printf ("*ERROR*: Unknown message: %s", string); | 1848 | needlf = 0; |
| 1827 | needlf = string[0] | 1849 | printf ("*ERROR*: Unknown message: %s\n", p); |
| 1828 | == '\0' ? needlf : string[strlen (string) - 1] != '\n'; | 1850 | } |
| 1829 | } | 1851 | } |
| 1830 | } | 1852 | } |
| 1831 | 1853 | ||
| 1832 | if (needlf) | 1854 | if (needlf) |