aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorPaul Eggert2018-11-22 23:42:50 -0800
committerPaul Eggert2018-11-22 23:46:14 -0800
commit5daba9d8a55d4fa28600f097490bc675eb848957 (patch)
tree0ecad1fdf29941b093464ca456bad21f8ecb1b31 /lib-src
parent4dc73269561237d04280b0a212eee603f1e73c9f (diff)
downloademacs-5daba9d8a55d4fa28600f097490bc675eb848957.tar.gz
emacs-5daba9d8a55d4fa28600f097490bc675eb848957.zip
emacsclient: tidy socket failure cleanup
* lib-src/emacsclient.c (set_tcp_socket, set_local_socket): Close socket (instead of leaking it) when ‘connect’ fails. (socket_status): Return errno if stat fails and -1 if we don’t own. (set_local_socket): Simplify based on socket_status change.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/emacsclient.c50
1 files changed, 23 insertions, 27 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 6f2fb20ae52..ef510b1f8bc 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -485,7 +485,7 @@ message (bool is_error, const char *format, ...)
485} 485}
486 486
487/* Decode the options from argv and argc. 487/* Decode the options from argv and argc.
488 The global variable `optind' will say how many arguments we used up. */ 488 The global variable 'optind' will say how many arguments we used up. */
489 489
490static void 490static void
491decode_options (int argc, char **argv) 491decode_options (int argc, char **argv)
@@ -584,7 +584,7 @@ decode_options (int argc, char **argv)
584 584
585 /* If the -c option is used (without -t) and no --display argument 585 /* If the -c option is used (without -t) and no --display argument
586 is provided, try $DISPLAY. 586 is provided, try $DISPLAY.
587 Without the -c option, we used to set `display' to $DISPLAY by 587 Without the -c option, we used to set 'display' to $DISPLAY by
588 default, but this changed the default behavior and is sometimes 588 default, but this changed the default behavior and is sometimes
589 inconvenient. So we force users to use "--display $DISPLAY" if 589 inconvenient. So we force users to use "--display $DISPLAY" if
590 they want Emacs to connect to their current display. 590 they want Emacs to connect to their current display.
@@ -1011,6 +1011,7 @@ set_tcp_socket (const char *local_server_file)
1011 if (connect (s, &server.sa, sizeof server.in) != 0) 1011 if (connect (s, &server.sa, sizeof server.in) != 0)
1012 { 1012 {
1013 sock_err_message ("connect"); 1013 sock_err_message ("connect");
1014 CLOSE_SOCKET (s);
1014 return INVALID_SOCKET; 1015 return INVALID_SOCKET;
1015 } 1016 }
1016 1017
@@ -1083,8 +1084,8 @@ find_tty (const char **tty_type, const char **tty_name, bool noabort)
1083# ifndef NO_SOCKETS_IN_FILE_SYSTEM 1084# ifndef NO_SOCKETS_IN_FILE_SYSTEM
1084 1085
1085/* Three possibilities: 1086/* Three possibilities:
1086 2 - can't be `stat'ed (sets errno) 1087 >0 - 'stat' failed with this errno value
1087 1 - isn't owned by us 1088 -1 - isn't owned by us
1088 0 - success: none of the above */ 1089 0 - success: none of the above */
1089 1090
1090static int 1091static int
@@ -1092,11 +1093,11 @@ socket_status (const char *name)
1092{ 1093{
1093 struct stat statbfr; 1094 struct stat statbfr;
1094 1095
1095 if (stat (name, &statbfr) == -1) 1096 if (stat (name, &statbfr) != 0)
1096 return 2; 1097 return errno;
1097 1098
1098 if (statbfr.st_uid != geteuid ()) 1099 if (statbfr.st_uid != geteuid ())
1099 return 1; 1100 return -1;
1100 1101
1101 return 0; 1102 return 0;
1102} 1103}
@@ -1201,8 +1202,6 @@ set_local_socket (const char *local_socket_name)
1201 return INVALID_SOCKET; 1202 return INVALID_SOCKET;
1202 } 1203 }
1203 1204
1204 int sock_status;
1205 int saved_errno;
1206 char const *server_name = local_socket_name; 1205 char const *server_name = local_socket_name;
1207 char const *tmpdir = NULL; 1206 char const *tmpdir = NULL;
1208 char *tmpdir_storage = NULL; 1207 char *tmpdir_storage = NULL;
@@ -1250,8 +1249,7 @@ set_local_socket (const char *local_socket_name)
1250 } 1249 }
1251 1250
1252 /* See if the socket exists, and if it's owned by us. */ 1251 /* See if the socket exists, and if it's owned by us. */
1253 sock_status = socket_status (server.un.sun_path); 1252 int sock_status = socket_status (server.un.sun_path);
1254 saved_errno = errno;
1255 if (sock_status && tmpdir) 1253 if (sock_status && tmpdir)
1256 { 1254 {
1257 /* Failing that, see if LOGNAME or USER exist and differ from 1255 /* Failing that, see if LOGNAME or USER exist and differ from
@@ -1289,10 +1287,7 @@ set_local_socket (const char *local_socket_name)
1289 free (user_socket_name); 1287 free (user_socket_name);
1290 1288
1291 sock_status = socket_status (server.un.sun_path); 1289 sock_status = socket_status (server.un.sun_path);
1292 saved_errno = errno;
1293 } 1290 }
1294 else
1295 errno = saved_errno;
1296 } 1291 }
1297 } 1292 }
1298 1293
@@ -1301,14 +1296,20 @@ set_local_socket (const char *local_socket_name)
1301 1296
1302 switch (sock_status) 1297 switch (sock_status)
1303 { 1298 {
1304 case 1: 1299 case -1:
1305 /* There's a socket, but it isn't owned by us. */ 1300 /* There's a socket, but it isn't owned by us. */
1306 message (true, "%s: Invalid socket owner\n", progname); 1301 message (true, "%s: Invalid socket owner\n", progname);
1307 return INVALID_SOCKET; 1302 break;
1303
1304 case 0:
1305 if (connect (s, &server.sa, sizeof server.un) == 0)
1306 return s;
1307 message (true, "%s: connect: %s\n", progname, strerror (errno));
1308 break;
1308 1309
1309 case 2: 1310 default:
1310 /* `stat' failed */ 1311 /* 'stat' failed. */
1311 if (saved_errno == ENOENT) 1312 if (sock_status == ENOENT)
1312 message (true, 1313 message (true,
1313 ("%s: can't find socket; have you started the server?\n" 1314 ("%s: can't find socket; have you started the server?\n"
1314 "%s: To start the server in Emacs," 1315 "%s: To start the server in Emacs,"
@@ -1317,16 +1318,11 @@ set_local_socket (const char *local_socket_name)
1317 else 1318 else
1318 message (true, "%s: can't stat %s: %s\n", 1319 message (true, "%s: can't stat %s: %s\n",
1319 progname, server.un.sun_path, strerror (sock_status)); 1320 progname, server.un.sun_path, strerror (sock_status));
1320 return INVALID_SOCKET; 1321 break;
1321 } 1322 }
1322 1323
1323 if (connect (s, &server.sa, sizeof server.un) != 0) 1324 CLOSE_SOCKET (s);
1324 { 1325 return INVALID_SOCKET;
1325 message (true, "%s: connect: %s\n", progname, strerror (errno));
1326 return INVALID_SOCKET;
1327 }
1328
1329 return s;
1330} 1326}
1331# endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */ 1327# endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
1332 1328