Revision: 798 http://svn.sourceforge.net/geany/?rev=798&view=rev Author: eht16 Date: 2006-09-07 08:51:24 -0700 (Thu, 07 Sep 2006)
Log Message: ----------- Moved the socket code from main.c to socket.c. Remove an unchanged empty document when loading a new file (closes #1545129).
Modified Paths: -------------- trunk/ChangeLog trunk/src/callbacks.c trunk/src/document.c trunk/src/main.c trunk/src/main.h
Added Paths: ----------- trunk/src/socket.c trunk/src/socket.h
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2006-09-06 18:26:08 UTC (rev 797) +++ trunk/ChangeLog 2006-09-07 15:51:24 UTC (rev 798) @@ -1,3 +1,11 @@ +2006-09-07 Enrico Tröger enrico.troeger@uvena.de + + * src/socket.c, src/main.c, src/callbacks.c: + Moved the socket code from main.c to socket.c. + * src/document.c: Remove an unchanged empty document when loading a + new file (closes #1545129). + + 2006-09-06 Enrico Tröger enrico.troeger@uvena.de
* src/callbacks.c, src/document.c, src/ui_utils.c, src/sci_cb.c:
Modified: trunk/src/callbacks.c =================================================================== --- trunk/src/callbacks.c 2006-09-06 18:26:08 UTC (rev 797) +++ trunk/src/callbacks.c 2006-09-07 15:51:24 UTC (rev 798) @@ -60,7 +60,11 @@ # include "vte.h" #endif
+#ifdef HAVE_SOCKET +# include "socket.h" +#endif
+ // represents the state while closing all tabs(used to prevent notebook switch page signals) static gboolean closing_all = FALSE;
@@ -2464,7 +2468,7 @@ { gint idx = document_get_cur_idx(); if (idx == -1 || ! doc_list[idx].is_valid) return; - sci_cb_do_comment(idx); + sci_cb_do_comment(idx, -1); }
@@ -2474,7 +2478,7 @@ { gint idx = document_get_cur_idx(); if (idx == -1 || ! doc_list[idx].is_valid) return; - sci_cb_do_uncomment(idx); + sci_cb_do_uncomment(idx, -1); }
Modified: trunk/src/document.c =================================================================== --- trunk/src/document.c 2006-09-06 18:26:08 UTC (rev 797) +++ trunk/src/document.c 2006-09-07 15:51:24 UTC (rev 798) @@ -231,10 +231,18 @@ PangoFontDescription *pfd; gchar *title, *fname; GtkTreeIter iter; - gint new_idx = document_get_new_idx(); + gint new_idx; document *this; gint tabnum;
+ if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)) == 1) + { + gint idx = document_get_cur_idx(); + // remove the empty document and open a new one + if (doc_list[idx].file_name == NULL && ! doc_list[idx].changed) document_remove(0); + } + + new_idx = document_get_new_idx(); if (new_idx == -1) return -1;
this = &(doc_list[new_idx]);
Modified: trunk/src/main.c =================================================================== --- trunk/src/main.c 2006-09-06 18:26:08 UTC (rev 797) +++ trunk/src/main.c 2006-09-07 15:51:24 UTC (rev 798) @@ -25,20 +25,12 @@ #include <time.h> #include <sys/types.h> #include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> #include <errno.h> #include <string.h> #include <stdlib.h>
#include "geany.h"
-#ifdef HAVE_SOCKET -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#endif - #include "main.h" #include "interface.h" #include "support.h" @@ -59,6 +51,10 @@ #include "sci_cb.h" #include "search.h"
+#ifdef HAVE_SOCKET +# include "socket.h" +#endif + #ifdef HAVE_VTE # include "vte.h" #endif @@ -66,37 +62,7 @@ #define N_(String) (String)
-#ifdef HAVE_SOCKET -static struct -{ - gboolean ignore_socket; - gchar *file_name; - GIOChannel *read_ioc; - gint lock_socket; - gint lock_socket_tag; -} socket_info; -static gboolean ignore_socket = FALSE;
-static gint socket_init(gint argc, gchar **argv); - -static gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpointer data); - -#ifdef G_OS_WIN32 -static gint socket_fd_connect_inet (gushort port); -static gint socket_fd_open_inet (gushort port); -#endif -static gint socket_fd_connect_unix (const gchar *path); -static gint socket_fd_open_unix (const gchar *path); - -static gint socket_fd_write (gint sock, const gchar *buf, gint len); -static gint socket_fd_write_all (gint sock, const gchar *buf, gint len); -static gint socket_fd_gets (gint sock, gchar *buf, gint len); -static gint socket_fd_check_io (gint fd, GIOCondition cond); -static gint socket_fd_read (gint sock, gchar *buf, gint len); -static gint socket_fd_recv (gint fd, gchar *buf, gint len, gint flags); -static gint socket_fd_close (gint sock); -#endif - CommandLineOptions cl_options; // fields initialised in parse_command_line_options
static gboolean debug_mode = FALSE; @@ -108,6 +74,9 @@ static gboolean no_vte = FALSE; static gchar *lib_vte = NULL; #endif +#ifdef HAVE_SOCKET +static gboolean ignore_socket = FALSE; +#endif static gboolean generate_datafiles = FALSE;
static GOptionEntry entries[] = @@ -674,436 +643,3 @@ return 0; }
- -#ifdef HAVE_SOCKET -/* (Unix domain) socket support to replace the old FIFO code - * (taken from Sylpheed, thanks) */ -static gint socket_init(gint argc, gchar **argv) -{ - gint sock; - -#ifdef G_OS_WIN32 - HANDLE hmutex; - - hmutex = CreateMutexA(NULL, FALSE, "Geany"); - if (! hmutex) - { - geany_debug("cannot create Mutex\n"); - return -1; - } - if (GetLastError() != ERROR_ALREADY_EXISTS) - { - sock = socket_fd_open_inet(REMOTE_CMD_PORT); - if (sock < 0) - return 0; - return sock; - } - - sock = socket_fd_connect_inet(REMOTE_CMD_PORT); - if (sock < 0) - return -1; -#else - - if (socket_info.file_name == NULL) - socket_info.file_name = g_strdup_printf("%s%cgeany_socket", app->configdir, G_DIR_SEPARATOR); - - sock = socket_fd_connect_unix(socket_info.file_name); - if (sock < 0) - { - unlink(socket_info.file_name); - return socket_fd_open_unix(socket_info.file_name); - } -#endif - - // remote command mode, here we have another running instance and want to use it - if (argc > 1) - { - gint i; - gchar *filename; - - geany_debug("using running instance of Geany"); - - socket_fd_write_all(sock, "open\n", 5); - - for(i = 1; i < argc && argv[i] != NULL; i++) - { - filename = get_argv_filename(argv[i]); - - if (filename != NULL) - { - socket_fd_write_all(sock, filename, strlen(filename)); - socket_fd_write_all(sock, "\n", 1); - g_free(filename); - } - } - socket_fd_write_all(sock, ".\n", 2); - } - - socket_fd_close(sock); - return -1; -} - - -gint socket_finalize(void) -{ - if (socket_info.lock_socket < 0) return -1; - - if (socket_info.lock_socket_tag > 0) - g_source_remove(socket_info.lock_socket_tag); - if (socket_info.read_ioc) - { - g_io_channel_shutdown(socket_info.read_ioc, FALSE, NULL); - g_io_channel_unref(socket_info.read_ioc); - socket_info.read_ioc = NULL; - } - -#ifndef G_OS_WIN32 - unlink(socket_info.file_name); - g_free(socket_info.file_name); -#endif - - return 0; -} - - -#ifdef G_OS_WIN32 -#define SockDesc SOCKET -#define SOCKET_IS_VALID(s) ((s) != INVALID_SOCKET) -#else -#define SockDesc gint -#define SOCKET_IS_VALID(s) ((s) >= 0) -#define INVALID_SOCKET (-1) -#endif - - -static gint socket_fd_connect_unix(const gchar *path) -{ -#ifdef G_OS_UNIX - gint sock; - struct sockaddr_un addr; - - sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - { - perror("fd_connect_unix(): socket"); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); - - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) - { - socket_fd_close(sock); - return -1; - } - - return sock; -#else - return -1; -#endif -} - - -static gint socket_fd_open_unix(const gchar *path) -{ -#ifdef G_OS_UNIX - gint sock; - struct sockaddr_un addr; - gint val; - - sock = socket(PF_UNIX, SOCK_STREAM, 0); - - if (sock < 0) - { - perror("sock_open_unix(): socket"); - return -1; - } - - val = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) - { - perror("setsockopt"); - socket_fd_close(sock); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); - - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) - { - perror("bind"); - socket_fd_close(sock); - return -1; - } - - if (listen(sock, 1) < 0) - { - perror("listen"); - socket_fd_close(sock); - return -1; - } - - return sock; -#else - return -1; -#endif -} - - -static gint socket_fd_close(gint fd) -{ -#ifdef G_OS_WIN32 - return closesocket(fd); -#else - return close(fd); -#endif -} - - -#ifdef G_OS_WIN32 -static gint socket_fd_open_inet(gushort port) -{ - SockDesc sock; - struct sockaddr_in addr; - gint val; - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (! SOCKET_IS_VALID(sock)) - { -#ifdef G_OS_WIN32 - geany_debug("fd_open_inet(): socket() failed: %ld\n", WSAGetLastError()); -#else - perror("fd_open_inet(): socket"); -#endif - return -1; - } - - val = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) - { - perror("setsockopt"); - socket_fd_close(sock); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) - { - perror("bind"); - socket_fd_close(sock); - return -1; - } - - if (listen(sock, 1) < 0) - { - perror("listen"); - socket_fd_close(sock); - return -1; - } - - return sock; -} - - -static gint socket_fd_connect_inet(gushort port) -{ - SockDesc sock; - struct sockaddr_in addr; - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (! SOCKET_IS_VALID(sock)) - { -#ifdef G_OS_WIN32 - geany_debug("fd_connect_inet(): socket() failed: %ld\n", WSAGetLastError()); -#else - perror("fd_connect_inet(): socket"); -#endif - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) - { - socket_fd_close(sock); - return -1; - } - - return sock; -} -#endif - - -static gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpointer data) -{ - gint fd, sock; - gchar buf[4096]; - struct sockaddr_in caddr; - guint caddr_len; - - caddr_len = sizeof(caddr); - - fd = g_io_channel_unix_get_fd(source); - sock = accept(fd, (struct sockaddr *)&caddr, &caddr_len); - - // first get the command - if (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && strncmp(buf, "open", 4) == 0) - { - geany_debug("remote command: open"); - while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') - { - g_strstrip(buf); // remove \n char - - if (g_file_test(buf, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK)) - document_open_file(-1, buf, 0, FALSE, NULL, NULL); - else - geany_debug("got data from socket, but it does not look like a filename"); - } - gtk_window_deiconify(GTK_WINDOW(app->window)); - gtk_window_present(GTK_WINDOW(app->window)); - } - - socket_fd_close(sock); - - return TRUE; -} - - -static gint socket_fd_gets(gint fd, gchar *buf, gint len) -{ - gchar *newline, *bp = buf; - gint n; - - if (--len < 1) - return -1; - do - { - if ((n = socket_fd_recv(fd, bp, len, MSG_PEEK)) <= 0) - return -1; - if ((newline = memchr(bp, '\n', n)) != NULL) - n = newline - bp + 1; - if ((n = socket_fd_read(fd, bp, n)) < 0) - return -1; - bp += n; - len -= n; - } while (! newline && len); - - *bp = '\0'; - return bp - buf; -} - - -static gint socket_fd_recv(gint fd, gchar *buf, gint len, gint flags) -{ - if (socket_fd_check_io(fd, G_IO_IN) < 0) - return -1; - - return recv(fd, buf, len, flags); -} - - -static gint socket_fd_read(gint fd, gchar *buf, gint len) -{ - if (socket_fd_check_io(fd, G_IO_IN) < 0) - return -1; - -#ifdef G_OS_WIN32 - return recv(fd, buf, len, 0); -#else - return read(fd, buf, len); -#endif -} - - -static gint socket_fd_check_io(gint fd, GIOCondition cond) -{ - struct timeval timeout; - fd_set fds; - gint flags; - - timeout.tv_sec = 60; - timeout.tv_usec = 0; - -#ifdef G_OS_UNIX - // checking for non-blocking mode - - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) - { - perror("fcntl"); - return 0; - } - - if ((flags & O_NONBLOCK) != 0) - return 0; -#endif - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - if (cond == G_IO_IN) - { - select(fd + 1, &fds, NULL, NULL, &timeout); - } - else - { - select(fd + 1, NULL, &fds, NULL, &timeout); - } - - if (FD_ISSET(fd, &fds)) - { - return 0; - } - else - { - geany_debug("Socket IO timeout\n"); - return -1; - } -} - - -static gint socket_fd_write_all(gint fd, const gchar *buf, gint len) -{ - gint n, wrlen = 0; - - while (len) - { - n = socket_fd_write(fd, buf, len); - if (n <= 0) - return -1; - len -= n; - wrlen += n; - buf += n; - } - - return wrlen; -} - - -gint socket_fd_write(gint fd, const gchar *buf, gint len) -{ - if (socket_fd_check_io(fd, G_IO_OUT) < 0) - return -1; - -#ifdef G_OS_WIN32 - return send(fd, buf, len, 0); -#else - return write(fd, buf, len); -#endif -} - - -#endif - -
Modified: trunk/src/main.h =================================================================== --- trunk/src/main.h 2006-09-06 18:26:08 UTC (rev 797) +++ trunk/src/main.h 2006-09-07 15:51:24 UTC (rev 798) @@ -33,10 +33,8 @@ extern CommandLineOptions cl_options;
-#ifdef HAVE_SOCKET -gint socket_finalize(); -#endif - void geany_debug(gchar const *format, ...);
+gchar *get_argv_filename(const gchar *filename); + #endif
Added: trunk/src/socket.c =================================================================== --- trunk/src/socket.c (rev 0) +++ trunk/src/socket.c 2006-09-07 15:51:24 UTC (rev 798) @@ -0,0 +1,487 @@ +/* + * socket.h - this file is part of Geany, a fast and lightweight IDE + * + * Copyright 2006 Enrico Tröger enrico.troeger@uvena.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $Id$ + */ + + +#include "geany.h" + +#ifdef HAVE_SOCKET + +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <unistd.h> +#include <fcntl.h> + +#include "main.h" +#include "socket.h" +#include "document.h" + + + +#ifdef G_OS_WIN32 +static gint socket_fd_connect_inet (gushort port); +static gint socket_fd_open_inet (gushort port); +#endif +static gint socket_fd_connect_unix (const gchar *path); +static gint socket_fd_open_unix (const gchar *path); + +static gint socket_fd_write (gint sock, const gchar *buf, gint len); +static gint socket_fd_write_all (gint sock, const gchar *buf, gint len); +static gint socket_fd_gets (gint sock, gchar *buf, gint len); +static gint socket_fd_check_io (gint fd, GIOCondition cond); +static gint socket_fd_read (gint sock, gchar *buf, gint len); +static gint socket_fd_recv (gint fd, gchar *buf, gint len, gint flags); +static gint socket_fd_close (gint sock); + + + +/* (Unix domain) socket support to replace the old FIFO code + * (taken from Sylpheed, thanks) */ +gint socket_init(gint argc, gchar **argv) +{ + gint sock; + +#ifdef G_OS_WIN32 + HANDLE hmutex; + + hmutex = CreateMutexA(NULL, FALSE, "Geany"); + if (! hmutex) + { + geany_debug("cannot create Mutex\n"); + return -1; + } + if (GetLastError() != ERROR_ALREADY_EXISTS) + { + sock = socket_fd_open_inet(REMOTE_CMD_PORT); + if (sock < 0) + return 0; + return sock; + } + + sock = socket_fd_connect_inet(REMOTE_CMD_PORT); + if (sock < 0) + return -1; +#else + + if (socket_info.file_name == NULL) + socket_info.file_name = g_strdup_printf("%s%cgeany_socket", app->configdir, G_DIR_SEPARATOR); + + sock = socket_fd_connect_unix(socket_info.file_name); + if (sock < 0) + { + unlink(socket_info.file_name); + return socket_fd_open_unix(socket_info.file_name); + } +#endif + + // remote command mode, here we have another running instance and want to use it + if (argc > 1) + { + gint i; + gchar *filename; + + geany_debug("using running instance of Geany"); + + socket_fd_write_all(sock, "open\n", 5); + + for(i = 1; i < argc && argv[i] != NULL; i++) + { + filename = get_argv_filename(argv[i]); + + if (filename != NULL) + { + socket_fd_write_all(sock, filename, strlen(filename)); + socket_fd_write_all(sock, "\n", 1); + g_free(filename); + } + } + socket_fd_write_all(sock, ".\n", 2); + } + + socket_fd_close(sock); + return -1; +} + + +gint socket_finalize(void) +{ + if (socket_info.lock_socket < 0) return -1; + + if (socket_info.lock_socket_tag > 0) + g_source_remove(socket_info.lock_socket_tag); + if (socket_info.read_ioc) + { + g_io_channel_shutdown(socket_info.read_ioc, FALSE, NULL); + g_io_channel_unref(socket_info.read_ioc); + socket_info.read_ioc = NULL; + } + +#ifndef G_OS_WIN32 + unlink(socket_info.file_name); + g_free(socket_info.file_name); +#endif + + return 0; +} + + +#ifdef G_OS_WIN32 +#define SockDesc SOCKET +#define SOCKET_IS_VALID(s) ((s) != INVALID_SOCKET) +#else +#define SockDesc gint +#define SOCKET_IS_VALID(s) ((s) >= 0) +#define INVALID_SOCKET (-1) +#endif + + +static gint socket_fd_connect_unix(const gchar *path) +{ +#ifdef G_OS_UNIX + gint sock; + struct sockaddr_un addr; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + { + perror("fd_connect_unix(): socket"); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + socket_fd_close(sock); + return -1; + } + + return sock; +#else + return -1; +#endif +} + + +static gint socket_fd_open_unix(const gchar *path) +{ +#ifdef G_OS_UNIX + gint sock; + struct sockaddr_un addr; + gint val; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + + if (sock < 0) + { + perror("sock_open_unix(): socket"); + return -1; + } + + val = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) + { + perror("setsockopt"); + socket_fd_close(sock); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); + + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + perror("bind"); + socket_fd_close(sock); + return -1; + } + + if (listen(sock, 1) < 0) + { + perror("listen"); + socket_fd_close(sock); + return -1; + } + + return sock; +#else + return -1; +#endif +} + + +static gint socket_fd_close(gint fd) +{ +#ifdef G_OS_WIN32 + return closesocket(fd); +#else + return close(fd); +#endif +} + + +#ifdef G_OS_WIN32 +static gint socket_fd_open_inet(gushort port) +{ + SockDesc sock; + struct sockaddr_in addr; + gint val; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (! SOCKET_IS_VALID(sock)) + { +#ifdef G_OS_WIN32 + geany_debug("fd_open_inet(): socket() failed: %ld\n", WSAGetLastError()); +#else + perror("fd_open_inet(): socket"); +#endif + return -1; + } + + val = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) + { + perror("setsockopt"); + socket_fd_close(sock); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + perror("bind"); + socket_fd_close(sock); + return -1; + } + + if (listen(sock, 1) < 0) + { + perror("listen"); + socket_fd_close(sock); + return -1; + } + + return sock; +} + + +static gint socket_fd_connect_inet(gushort port) +{ + SockDesc sock; + struct sockaddr_in addr; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (! SOCKET_IS_VALID(sock)) + { +#ifdef G_OS_WIN32 + geany_debug("fd_connect_inet(): socket() failed: %ld\n", WSAGetLastError()); +#else + perror("fd_connect_inet(): socket"); +#endif + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + socket_fd_close(sock); + return -1; + } + + return sock; +} +#endif + + +gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpointer data) +{ + gint fd, sock; + gchar buf[4096]; + struct sockaddr_in caddr; + guint caddr_len; + + caddr_len = sizeof(caddr); + + fd = g_io_channel_unix_get_fd(source); + sock = accept(fd, (struct sockaddr *)&caddr, &caddr_len); + + // first get the command + if (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && strncmp(buf, "open", 4) == 0) + { + geany_debug("remote command: open"); + while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') + { + g_strstrip(buf); // remove \n char + + if (g_file_test(buf, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK)) + document_open_file(-1, buf, 0, FALSE, NULL, NULL); + else + geany_debug("got data from socket, but it does not look like a filename"); + } + gtk_window_deiconify(GTK_WINDOW(app->window)); + gtk_window_present(GTK_WINDOW(app->window)); + } + + socket_fd_close(sock); + + return TRUE; +} + + +static gint socket_fd_gets(gint fd, gchar *buf, gint len) +{ + gchar *newline, *bp = buf; + gint n; + + if (--len < 1) + return -1; + do + { + if ((n = socket_fd_recv(fd, bp, len, MSG_PEEK)) <= 0) + return -1; + if ((newline = memchr(bp, '\n', n)) != NULL) + n = newline - bp + 1; + if ((n = socket_fd_read(fd, bp, n)) < 0) + return -1; + bp += n; + len -= n; + } while (! newline && len); + + *bp = '\0'; + return bp - buf; +} + + +static gint socket_fd_recv(gint fd, gchar *buf, gint len, gint flags) +{ + if (socket_fd_check_io(fd, G_IO_IN) < 0) + return -1; + + return recv(fd, buf, len, flags); +} + + +static gint socket_fd_read(gint fd, gchar *buf, gint len) +{ + if (socket_fd_check_io(fd, G_IO_IN) < 0) + return -1; + +#ifdef G_OS_WIN32 + return recv(fd, buf, len, 0); +#else + return read(fd, buf, len); +#endif +} + + +static gint socket_fd_check_io(gint fd, GIOCondition cond) +{ + struct timeval timeout; + fd_set fds; + gint flags; + + timeout.tv_sec = 60; + timeout.tv_usec = 0; + +#ifdef G_OS_UNIX + // checking for non-blocking mode + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + { + perror("fcntl"); + return 0; + } + + if ((flags & O_NONBLOCK) != 0) + return 0; +#endif + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + if (cond == G_IO_IN) + { + select(fd + 1, &fds, NULL, NULL, &timeout); + } + else + { + select(fd + 1, NULL, &fds, NULL, &timeout); + } + + if (FD_ISSET(fd, &fds)) + { + return 0; + } + else + { + geany_debug("Socket IO timeout\n"); + return -1; + } +} + + +static gint socket_fd_write_all(gint fd, const gchar *buf, gint len) +{ + gint n, wrlen = 0; + + while (len) + { + n = socket_fd_write(fd, buf, len); + if (n <= 0) + return -1; + len -= n; + wrlen += n; + buf += n; + } + + return wrlen; +} + + +gint socket_fd_write(gint fd, const gchar *buf, gint len) +{ + if (socket_fd_check_io(fd, G_IO_OUT) < 0) + return -1; + +#ifdef G_OS_WIN32 + return send(fd, buf, len, 0); +#else + return write(fd, buf, len); +#endif +} + + +#endif + +
Added: trunk/src/socket.h =================================================================== --- trunk/src/socket.h (rev 0) +++ trunk/src/socket.h 2006-09-07 15:51:24 UTC (rev 798) @@ -0,0 +1,44 @@ +/* + * socket.h - this file is part of Geany, a fast and lightweight IDE + * + * Copyright 2006 Enrico Troeger enrico.troeger@uvena.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $Id$ + */ + + +#ifndef GEANY_SOCKET_H +#define GEANY_SOCKET_H 1 + + +struct +{ + gboolean ignore_socket; + gchar *file_name; + GIOChannel *read_ioc; + gint lock_socket; + gint lock_socket_tag; +} socket_info; + +gint socket_init(gint argc, gchar **argv); + +gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpointer data); + +gint socket_finalize(); + + +#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.