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; }
gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpointer data) { gint fd, sock; gchar buf[BUFFER_LENGTH]; struct sockaddr_in caddr; socklen_t caddr_len = sizeof(caddr); GtkWidget *window = data; gboolean popup = FALSE; fd = g_io_channel_unix_get_fd(source); sock = accept(fd, (struct sockaddr *)&caddr, &caddr_len); /* first get the command */ while (socket_fd_gets(sock, buf, sizeof(buf)) != -1) { if (strncmp(buf, "open", 4) == 0) { cl_options.readonly = strncmp(buf+4, "ro", 2) == 0; /* open in readonly? */ while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { handle_input_filename(g_strstrip(buf)); } popup = TRUE; } else if (strncmp(buf, "doclist", 7) == 0) { gchar *doc_list = build_document_list(); if (NZV(doc_list)) socket_fd_write_all(sock, doc_list, strlen(doc_list)); else /* send ETX (end-of-text) in case we have no open files, we must send anything * otherwise the client would hang on reading */ socket_fd_write_all(sock, "\3", 1); g_free(doc_list); } else if (strncmp(buf, "line", 4) == 0) { while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { g_strstrip(buf); /* remove \n char */ /* on any error we get 0 which should be safe enough as fallback */ cl_options.goto_line = atoi(buf); } } else if (strncmp(buf, "column", 6) == 0) { while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { g_strstrip(buf); /* remove \n char */ /* on any error we get 0 which should be safe enough as fallback */ cl_options.goto_column = atoi(buf); } } #ifdef G_OS_WIN32 else if (strncmp(buf, "window", 6) == 0) { HWND hwnd = (HWND) gdk_win32_drawable_get_handle( GDK_DRAWABLE(gtk_widget_get_window(window))); socket_fd_write(sock, (gchar *)&hwnd, sizeof(hwnd)); } #endif } if (popup) { #ifdef GDK_WINDOWING_X11 /* Set the proper interaction time on the window. This seems necessary to make * gtk_window_present() really bring the main window into the foreground on some * window managers like Gnome's metacity. * Code taken from Gedit. */ gdk_x11_window_set_user_time(gtk_widget_get_window(window), gdk_x11_get_server_time(gtk_widget_get_window(window))); #endif gtk_window_present(GTK_WINDOW(window)); #ifdef G_OS_WIN32 gdk_window_show(gtk_widget_get_window(window)); #endif } socket_fd_close(sock); return TRUE; }
gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpointer data) { gint fd, sock; gchar buf[BUFFER_LENGTH]; gchar *command = NULL; struct sockaddr_in caddr; socklen_t caddr_len = sizeof(caddr); GtkWidget *window = data; gboolean popup = FALSE; fd = g_io_channel_unix_get_fd(source); sock = accept(fd, (struct sockaddr *)&caddr, &caddr_len); /* 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? */ while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { gsize buf_len = strlen(buf); /* remove trailing newline */ if (buf_len > 0 && buf[buf_len - 1] == '\n') buf[buf_len - 1] = '\0'; handle_input_filename(buf); } popup = TRUE; } else if (strncmp(buf, "doclist", 7) == 0) { gchar *doc_list = build_document_list(); if (!EMPTY(doc_list)) socket_fd_write_all(sock, doc_list, strlen(doc_list)); /* send ETX (end-of-text) so reader knows to stop reading */ socket_fd_write_all(sock, "\3", 1); g_free(doc_list); } else if (strncmp(buf, "line", 4) == 0) { while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { g_strstrip(buf); /* remove \n char */ /* on any error we get 0 which should be safe enough as fallback */ cl_options.goto_line = atoi(buf); } } else if (strncmp(buf, "column", 6) == 0) { while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { g_strstrip(buf); /* remove \n char */ /* on any error we get 0 which should be safe enough as fallback */ cl_options.goto_column = atoi(buf); } } #ifdef G_OS_WIN32 else if (strncmp(buf, "window", 6) == 0) { # if GTK_CHECK_VERSION(3, 0, 0) HWND hwnd = (HWND) gdk_win32_window_get_handle(gtk_widget_get_window(window)); # else HWND hwnd = (HWND) gdk_win32_drawable_get_handle( GDK_DRAWABLE(gtk_widget_get_window(window))); # endif socket_fd_write(sock, (gchar *)&hwnd, sizeof(hwnd)); } #endif } if (popup) { #ifdef GDK_WINDOWING_X11 GdkWindow *x11_window = gtk_widget_get_window(window); /* Set the proper interaction time on the window. This seems necessary to make * gtk_window_present() really bring the main window into the foreground on some * window managers like Gnome's metacity. * Code taken from Gedit. */ # if GTK_CHECK_VERSION(3, 0, 0) if (GDK_IS_X11_WINDOW(x11_window)) # endif { gdk_x11_window_set_user_time(x11_window, gdk_x11_get_server_time(x11_window)); } #endif gtk_window_present(GTK_WINDOW(window)); #ifdef G_OS_WIN32 gdk_window_show(gtk_widget_get_window(window)); #endif } socket_fd_close(sock); return TRUE; }
int main(int argc, char *argv[]) { // parse parameters std::string host; std::string port; int rez = 0; while ( (rez = getopt(argc, argv, "h:p:d:")) != -1) { switch (rez) { case 'h': host = optarg; break; case 'p': port = optarg; break; case 'd': setDirectory(optarg); break; default: break; } } #ifdef ENABLE_SIGNALS // Set action on SIGCHILD { __sigset_t set; sigfillset(&set); struct sigaction action; action.sa_handler = &sigHandler; action.sa_mask = set; action.sa_flags = SA_RESTART; sigaction(SIGCHLD, &action, NULL); } #endif #ifdef ENABLE_DEAMON pid_t pid = fork(); if (pid == 0) { #endif // Create Master Socket int MasterSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int optval = 1; setsockopt(MasterSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); struct sockaddr_in SockAddr; SockAddr.sin_family = AF_INET; SockAddr.sin_port = htons(atoi(port.c_str())); inet_pton(AF_INET, host.c_str(), &(SockAddr.sin_addr)); bind(MasterSocket, (struct sockaddr *)(&SockAddr), sizeof(SockAddr)); listen(MasterSocket, SOMAXCONN); // Create child process for (int i = 0; i < max_child; ++i) { std::pair<pid_t, int> res = make_child(i + 1); children[i] = res.second; process_to_socket.insert(std::make_pair(res.first, i)); } int counter = 0; // Getting incoming connections char buff[] = ""; while (true) { int incoming_socket = accept(MasterSocket, 0, 0); int size = -1; while (size < 0) { size = socket_fd_write(children[counter], buff, sizeof(buff), incoming_socket); counter = (counter + 1) % max_child; } } #ifdef ENABLE_DEAMON } #endif return 0; }