Branch: refs/heads/master Author: Enrico Tröger enrico.troeger@uvena.de Committer: GitHub noreply@github.com Date: Sun, 07 Apr 2019 09:41:24 UTC Commit: 00a568824978704ff11906e9f2e23fef79f83f8e https://github.com/geany/geany/commit/00a568824978704ff11906e9f2e23fef79f83f...
Log Message: ----------- Merge pull request #2111 from eht16/win32_socket_handling
Improve IPC socket handling
Modified Paths: -------------- src/libmain.c src/socket.c
Modified: src/libmain.c 14 lines changed, 12 insertions(+), 2 deletions(-) =================================================================== @@ -1174,8 +1174,18 @@ gint main_lib(gint argc, gchar **argv)
ui_set_statusbar(TRUE, _("This is Geany %s."), main_get_version_string()); if (config_dir_result != 0) - ui_set_statusbar(TRUE, _("Configuration directory could not be created (%s)."), - g_strerror(config_dir_result)); + { + const gchar *message = _("Configuration directory could not be created (%s)."); + ui_set_statusbar(TRUE, message, g_strerror(config_dir_result)); + g_warning(message, g_strerror(config_dir_result)); + } + if (socket_info.lock_socket == -1) + { + const gchar *message = + _("IPC socket could not be created, see Help->Debug Messages for details."); + ui_set_statusbar(TRUE, message); + g_warning(message); + }
/* apply all configuration options */ apply_settings();
Modified: src/socket.c 83 lines changed, 62 insertions(+), 21 deletions(-) =================================================================== @@ -85,6 +85,7 @@ # include <ws2tcpip.h> #endif #include <string.h> +#include <errno.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> @@ -271,7 +272,7 @@ gint socket_init(gint argc, gchar **argv) * For now we use one port number, that is we support only one instance at all. */ sock = socket_fd_open_inet(REMOTE_CMD_PORT); if (sock < 0) - return 0; + return -1; return sock; }
@@ -325,15 +326,16 @@ gint socket_init(gint argc, gchar **argv)
/* remote command mode, here we have another running instance and want to use it */
-#ifdef G_OS_WIN32 - /* first we send a request to retrieve the window handle and focus the window */ - socket_fd_write_all(sock, "window\n", 7); - if (socket_fd_read(sock, (gchar *)&hwnd, sizeof(hwnd)) == sizeof(hwnd)) - SetForegroundWindow(hwnd); -#endif /* now we send the command line args */ if (argc > 1) { +#ifdef G_OS_WIN32 + /* first we send a request to retrieve the window handle and focus the window */ + socket_fd_write_all(sock, "window\n", 7); + if (socket_fd_read(sock, (gchar *)&hwnd, sizeof(hwnd)) == sizeof(hwnd)) + SetForegroundWindow(hwnd); +#endif + send_open_command(sock, argc, argv); }
@@ -375,6 +377,20 @@ gint socket_finalize(void) }
+static void log_error(const gchar *message_prefix, gint error_code) +{ +#ifdef G_OS_WIN32 + error_code = error_code == -1 ? WSAGetLastError(): error_code; + gchar *error_message = g_win32_error_message(error_code); +#else + error_code = error_code == -1 ? errno: error_code; + gchar *error_message = g_strdup(g_strerror(error_code)); +#endif + g_warning("%s: %d: %s", message_prefix, error_code, error_message); + g_free(error_message); +} + + #ifdef G_OS_UNIX static gint socket_fd_connect_unix(const gchar *path) { @@ -384,7 +400,7 @@ static gint socket_fd_connect_unix(const gchar *path) sock = socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { - perror("fd_connect_unix(): socket"); + log_error("Failed to create IPC socket", errno); return -1; }
@@ -410,17 +426,16 @@ static gint socket_fd_open_unix(const gchar *path) gchar *real_path;
sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - perror("sock_open_unix(): socket"); + log_error("Failed to create IPC socket", errno); return -1; }
val = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { - perror("setsockopt"); + log_error("Failed to set IPC socket option", errno); socket_fd_close(sock); return -1; } @@ -441,7 +456,13 @@ static gint socket_fd_open_unix(const gchar *path) /* create a symlink in e.g. ~/.config/geany/geany_socket_hostname__0 to /tmp/geany_socket.499602d2 */ else if (symlink(real_path, path) != 0) { - perror("symlink"); + gint saved_errno = errno; + gchar* message = g_strdup_printf( + "Failed to create IPC socket symlink %s -> %s)", + real_path, + path); + log_error(message, saved_errno); + g_free(message); socket_fd_close(sock); return -1; } @@ -452,14 +473,20 @@ static gint socket_fd_open_unix(const gchar *path)
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - perror("bind"); + gint saved_errno = errno; + gchar* message = g_strdup_printf("Failed to bind IPC socket (%s)", real_path); + log_error(message, saved_errno); + g_free(message); socket_fd_close(sock); return -1; }
if (listen(sock, 1) < 0) { - perror("listen"); + gint saved_errno = errno; + gchar* message = g_strdup_printf("Failed to listen on IPC socket (%s)", real_path); + log_error(message, saved_errno); + g_free(message); socket_fd_close(sock); return -1; } @@ -492,14 +519,14 @@ static gint socket_fd_open_inet(gushort port) sock = socket(AF_INET, SOCK_STREAM, 0); if (G_UNLIKELY(! SOCKET_IS_VALID(sock))) { - geany_debug("fd_open_inet(): socket() failed: %d\n", WSAGetLastError()); + log_error("Failed to create IPC socket", -1); return -1; }
val = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) + if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, &val, sizeof(val)) < 0) { - perror("setsockopt"); + log_error("Failed to set IPC socket exclusive option", -1); socket_fd_close(sock); return -1; } @@ -511,14 +538,20 @@ static gint socket_fd_open_inet(gushort port)
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - perror("bind"); + gint saved_errno = WSAGetLastError(); + gchar* message = g_strdup_printf("Failed to bind IPC socket (127.0.0.1:%d)", port); + log_error(message, saved_errno); + g_free(message); socket_fd_close(sock); return -1; }
if (listen(sock, 1) < 0) { - perror("listen"); + gint saved_errno = WSAGetLastError(); + gchar* message = g_strdup_printf("Failed to listen on IPC socket (127.0.0.1:%d)", port); + log_error(message, saved_errno); + g_free(message); socket_fd_close(sock); return -1; } @@ -535,7 +568,7 @@ static gint socket_fd_connect_inet(gushort port) sock = socket(AF_INET, SOCK_STREAM, 0); if (G_UNLIKELY(! SOCKET_IS_VALID(sock))) { - geany_debug("fd_connect_inet(): socket() failed: %d\n", WSAGetLastError()); + log_error("Failed to create IPC socket", -1); return -1; }
@@ -546,6 +579,10 @@ static gint socket_fd_connect_inet(gushort port)
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + gint saved_errno = WSAGetLastError(); + gchar* message = g_strdup_printf("Failed to connect to IPC socket (127.0.0.1:%d)", port); + log_error(message, saved_errno); + g_free(message); socket_fd_close(sock); return -1; } @@ -612,6 +649,7 @@ gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpoint { gint fd, sock; gchar buf[BUFFER_LENGTH]; + gchar *command = NULL; struct sockaddr_in caddr; socklen_t caddr_len = sizeof(caddr); GtkWidget *window = data; @@ -623,6 +661,9 @@ gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpoint /* first get the command */ while (socket_fd_gets(sock, buf, sizeof(buf)) != -1) { + command = g_strdup(buf); + geany_debug("Received IPC command from remote instance: %s", g_strstrip(command)); + g_free(command); if (strncmp(buf, "open", 4) == 0) { cl_options.readonly = strncmp(buf+4, "ro", 2) == 0; /* open in readonly? */ @@ -769,7 +810,7 @@ static gint socket_fd_check_io(gint fd, GIOCondition cond) flags = fcntl(fd, F_GETFL, 0); if (flags < 0) { - perror("fcntl"); + log_error("fcntl() failed", errno); return 0; } if ((flags & O_NONBLOCK) != 0)
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).