Agrego la factory basada en sockets unix y un bloqueo de archivos.
parent
0c216e68f6
commit
bf285963f3
|
@ -775,6 +775,8 @@ static gchar **terminal_app_profile_list_from_dir (TerminalApp *app) {
|
||||||
|
|
||||||
g_ptr_array_add (builder_str, NULL);
|
g_ptr_array_add (builder_str, NULL);
|
||||||
profile_list = (gchar **) g_ptr_array_free (builder_str, FALSE);
|
profile_list = (gchar **) g_ptr_array_free (builder_str, FALSE);
|
||||||
|
|
||||||
|
g_dir_close (dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
//g_ptr_array_unref (builder_str);
|
//g_ptr_array_unref (builder_str);
|
||||||
|
|
452
src/terminal.c
452
src/terminal.c
|
@ -26,6 +26,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
|
@ -34,6 +35,11 @@
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
#include "terminal-accels.h"
|
#include "terminal-accels.h"
|
||||||
#include "terminal-app.h"
|
#include "terminal-app.h"
|
||||||
#include "terminal-debug.h"
|
#include "terminal-debug.h"
|
||||||
|
@ -41,9 +47,12 @@
|
||||||
#include "terminal-options.h"
|
#include "terminal-options.h"
|
||||||
#include "terminal-util.h"
|
#include "terminal-util.h"
|
||||||
|
|
||||||
#define TERMINAL_FACTORY_SERVICE_NAME_PREFIX "org.mate.Terminal.Display"
|
#define TERMINAL_FACTORY_UNIX_FOLDER "gatuno-terminal"
|
||||||
#define TERMINAL_FACTORY_SERVICE_PATH "/org/mate/Terminal/Factory"
|
#define TERMINAL_FACTORY_SERVICE_NAME_PREFIX "factory"
|
||||||
#define TERMINAL_FACTORY_INTERFACE_NAME "org.mate.Terminal.Factory"
|
|
||||||
|
int factory_fd_lock = -1;
|
||||||
|
int factory_unix_fd = -1;
|
||||||
|
guint factory_unix_watch = 0;
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
ay_to_string (GVariant *variant,
|
ay_to_string (GVariant *variant,
|
||||||
|
@ -130,181 +139,101 @@ typedef struct
|
||||||
int argc;
|
int argc;
|
||||||
} OwnData;
|
} OwnData;
|
||||||
|
|
||||||
static void
|
gboolean unix_socket_dgram_recv (GIOChannel *source, GIOCondition condition, gpointer data) {
|
||||||
method_call_cb (GDBusConnection *connection,
|
char *message = NULL, byte;
|
||||||
const char *sender,
|
int message_len;
|
||||||
const char *object_path,
|
int s;
|
||||||
const char *interface_name,
|
|
||||||
const char *method_name,
|
|
||||||
GVariant *parameters,
|
|
||||||
GDBusMethodInvocation *invocation,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
if (g_strcmp0 (method_name, "HandleArguments") == 0)
|
|
||||||
{
|
|
||||||
TerminalOptions *options = NULL;
|
|
||||||
GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
|
|
||||||
char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
|
|
||||||
int initial_workspace = -1;
|
|
||||||
char **envv = NULL, **argv = NULL;
|
|
||||||
int argc;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
g_variant_get (parameters, "(@ay@ay@ay@ayi@ay)",
|
TerminalOptions *options = NULL;
|
||||||
&v_wd, &v_display, &v_sid, &v_envv, &initial_workspace, &v_argv);
|
GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
|
||||||
|
char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
|
||||||
|
int initial_workspace = -1;
|
||||||
|
char **envv = NULL, **argv = NULL;
|
||||||
|
int argc;
|
||||||
|
GError *error = NULL;
|
||||||
|
GVariant *parameters;
|
||||||
|
|
||||||
working_directory = ay_to_string (v_wd, &error);
|
s = g_io_channel_unix_get_fd (source);
|
||||||
if (error)
|
|
||||||
goto out;
|
|
||||||
display_name = ay_to_string (v_display, &error);
|
|
||||||
if (error)
|
|
||||||
goto out;
|
|
||||||
startup_id = ay_to_string (v_sid, &error);
|
|
||||||
if (error)
|
|
||||||
goto out;
|
|
||||||
envv = ay_to_strv (v_envv, NULL);
|
|
||||||
argv = ay_to_strv (v_argv, &argc);
|
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
message_len = recvfrom (s, &byte, 1, MSG_TRUNC | MSG_PEEK, NULL, NULL);
|
||||||
"Factory invoked with working-dir='%s' display='%s' startup-id='%s'"
|
|
||||||
"workspace='%d'\n",
|
|
||||||
working_directory ? working_directory : "(null)",
|
|
||||||
display_name ? display_name : "(null)",
|
|
||||||
startup_id ? startup_id : "(null)",
|
|
||||||
initial_workspace);
|
|
||||||
|
|
||||||
options = terminal_options_parse (working_directory,
|
message = g_malloc (message_len);
|
||||||
display_name,
|
|
||||||
startup_id,
|
|
||||||
envv,
|
|
||||||
TRUE,
|
|
||||||
TRUE,
|
|
||||||
&argc, &argv,
|
|
||||||
&error,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (options != NULL)
|
if (message == NULL) {
|
||||||
{
|
return TRUE;
|
||||||
options->initial_workspace = initial_workspace;
|
}
|
||||||
|
|
||||||
terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
|
message_len = recvfrom (s, message, message_len, 0, NULL, NULL);
|
||||||
terminal_options_free (options);
|
if (message_len < 0) {
|
||||||
}
|
g_free (message);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters = g_variant_new_from_data (G_VARIANT_TYPE ("(ayayayayiay)"), message, message_len, FALSE, NULL, NULL);
|
||||||
|
|
||||||
|
g_variant_get (parameters, "(@ay@ay@ay@ayi@ay)",
|
||||||
|
&v_wd, &v_display, &v_sid, &v_envv, &initial_workspace, &v_argv);
|
||||||
|
|
||||||
|
working_directory = ay_to_string (v_wd, &error);
|
||||||
|
if (error)
|
||||||
|
goto out;
|
||||||
|
display_name = ay_to_string (v_display, &error);
|
||||||
|
if (error)
|
||||||
|
goto out;
|
||||||
|
startup_id = ay_to_string (v_sid, &error);
|
||||||
|
if (error)
|
||||||
|
goto out;
|
||||||
|
envv = ay_to_strv (v_envv, NULL);
|
||||||
|
argv = ay_to_strv (v_argv, &argc);
|
||||||
|
|
||||||
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
||||||
|
"Factory invoked with working-dir='%s' display='%s' startup-id='%s'"
|
||||||
|
"workspace='%d'\n",
|
||||||
|
working_directory ? working_directory : "(null)",
|
||||||
|
display_name ? display_name : "(null)",
|
||||||
|
startup_id ? startup_id : "(null)",
|
||||||
|
initial_workspace);
|
||||||
|
|
||||||
|
options = terminal_options_parse (working_directory,
|
||||||
|
display_name,
|
||||||
|
startup_id,
|
||||||
|
envv,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
&argc, &argv,
|
||||||
|
&error,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (options != NULL) {
|
||||||
|
options->initial_workspace = initial_workspace;
|
||||||
|
|
||||||
|
terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
|
||||||
|
terminal_options_free (options);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
g_variant_unref (v_wd);
|
g_variant_unref (v_wd);
|
||||||
g_free (working_directory);
|
g_free (working_directory);
|
||||||
g_variant_unref (v_display);
|
g_variant_unref (v_display);
|
||||||
g_free (display_name);
|
g_free (display_name);
|
||||||
g_variant_unref (v_sid);
|
g_variant_unref (v_sid);
|
||||||
g_free (startup_id);
|
g_free (startup_id);
|
||||||
g_variant_unref (v_envv);
|
g_variant_unref (v_envv);
|
||||||
g_strfreev (envv);
|
g_strfreev (envv);
|
||||||
g_variant_unref (v_argv);
|
g_variant_unref (v_argv);
|
||||||
g_strfreev (argv);
|
g_strfreev (argv);
|
||||||
|
|
||||||
if (error == NULL)
|
if (error != NULL) {
|
||||||
{
|
|
||||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bus_acquired_cb (GDBusConnection *connection,
|
|
||||||
const char *name,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
static const char dbus_introspection_xml[] =
|
|
||||||
"<node name='/org/mate/Terminal'>"
|
|
||||||
"<interface name='org.mate.Terminal.Factory'>"
|
|
||||||
"<method name='HandleArguments'>"
|
|
||||||
"<arg type='ay' name='working_directory' direction='in' />"
|
|
||||||
"<arg type='ay' name='display_name' direction='in' />"
|
|
||||||
"<arg type='ay' name='startup_id' direction='in' />"
|
|
||||||
"<arg type='ay' name='environment' direction='in' />"
|
|
||||||
"<arg type='i' name='workspace' direction='in' />"
|
|
||||||
"<arg type='ay' name='arguments' direction='in' />"
|
|
||||||
"</method>"
|
|
||||||
"</interface>"
|
|
||||||
"</node>";
|
|
||||||
|
|
||||||
static const GDBusInterfaceVTable interface_vtable =
|
|
||||||
{
|
|
||||||
method_call_cb,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
OwnData *data = (OwnData *) user_data;
|
|
||||||
GDBusNodeInfo *introspection_data;
|
|
||||||
guint registration_id;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
|
||||||
"Bus %s acquired\n", name);
|
|
||||||
|
|
||||||
introspection_data = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
|
|
||||||
g_assert (introspection_data != NULL);
|
|
||||||
|
|
||||||
registration_id = g_dbus_connection_register_object (connection,
|
|
||||||
TERMINAL_FACTORY_SERVICE_PATH,
|
|
||||||
introspection_data->interfaces[0],
|
|
||||||
&interface_vtable,
|
|
||||||
NULL, NULL,
|
|
||||||
&error);
|
|
||||||
g_dbus_node_info_unref (introspection_data);
|
|
||||||
|
|
||||||
if (registration_id == 0)
|
|
||||||
{
|
|
||||||
g_printerr ("Failed to register object: %s\n", error->message);
|
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
data->exit_code = EXIT_FAILURE;
|
|
||||||
gtk_main_quit ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (message);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
name_acquired_cb (GDBusConnection *connection,
|
static void send_ask_open (const char *name, OwnData *data)
|
||||||
const char *name,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
OwnData *data = (OwnData *) user_data;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
|
||||||
"Acquired the name %s on the session bus\n", name);
|
|
||||||
|
|
||||||
if (data->options == NULL)
|
|
||||||
{
|
|
||||||
/* Name re-acquired!? */
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!terminal_app_handle_options (terminal_app_get (), data->options, TRUE /* do resume */, &error))
|
|
||||||
{
|
|
||||||
g_printerr ("Failed to handle options: %s\n", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
data->exit_code = EXIT_FAILURE;
|
|
||||||
gtk_main_quit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
terminal_options_free (data->options);
|
|
||||||
data->options = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
name_lost_cb (GDBusConnection *connection,
|
|
||||||
const char *name,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
OwnData *data = (OwnData *) user_data;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char **envv;
|
char **envv;
|
||||||
int i;
|
int i;
|
||||||
|
@ -313,23 +242,22 @@ name_lost_cb (GDBusConnection *connection,
|
||||||
GString *string;
|
GString *string;
|
||||||
char *s;
|
char *s;
|
||||||
gsize len;
|
gsize len;
|
||||||
|
struct sockaddr_un unix_dest;
|
||||||
|
int fd_u, ret;
|
||||||
|
|
||||||
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
|
||||||
"Lost the name %s on the session bus\n", name);
|
"Sending message to %s on the unix socket\n", name);
|
||||||
|
|
||||||
/* Couldn't get the connection? No way to continue! */
|
|
||||||
if (connection == NULL)
|
|
||||||
{
|
|
||||||
data->exit_code = EXIT_FAILURE;
|
|
||||||
gtk_main_quit ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->options == NULL)
|
if (data->options == NULL)
|
||||||
{
|
{
|
||||||
/* Already handled */
|
/* Already handled */
|
||||||
data->exit_code = EXIT_SUCCESS;
|
data->exit_code = EXIT_SUCCESS;
|
||||||
gtk_main_quit ();
|
return;
|
||||||
|
}
|
||||||
|
fd_u = socket (AF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
if (fd_u < 0) {
|
||||||
|
data->exit_code = EXIT_FAILURE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +302,21 @@ name_lost_cb (GDBusConnection *connection,
|
||||||
g_variant_builder_add (&builder, "@ay",
|
g_variant_builder_add (&builder, "@ay",
|
||||||
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
|
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
|
||||||
|
|
||||||
value = g_dbus_connection_call_sync (connection,
|
GVariant *todo;
|
||||||
|
todo = g_variant_builder_end (&builder);
|
||||||
|
|
||||||
|
unix_dest.sun_family = AF_UNIX;
|
||||||
|
g_snprintf (unix_dest.sun_path, sizeof (unix_dest.sun_path), "%s%s%s%s%s", g_get_user_runtime_dir (), G_DIR_SEPARATOR_S, TERMINAL_FACTORY_UNIX_FOLDER, G_DIR_SEPARATOR_S, name);
|
||||||
|
|
||||||
|
g_free (subcadena);
|
||||||
|
ret = sendto (fd_u, g_variant_get_data (todo), g_variant_get_size (todo), 0, (struct sockaddr *) &unix_dest, sizeof (unix_dest));
|
||||||
|
if (ret < 0) {
|
||||||
|
g_printerr ("Failed to forward arguments: \n");
|
||||||
|
data->exit_code = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
close (fd_u);
|
||||||
|
/*value = g_dbus_connection_call_sync (connection,
|
||||||
data->factory_name,
|
data->factory_name,
|
||||||
TERMINAL_FACTORY_SERVICE_PATH,
|
TERMINAL_FACTORY_SERVICE_PATH,
|
||||||
TERMINAL_FACTORY_INTERFACE_NAME,
|
TERMINAL_FACTORY_INTERFACE_NAME,
|
||||||
|
@ -384,29 +326,17 @@ name_lost_cb (GDBusConnection *connection,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
&error);
|
&error);*/
|
||||||
if (value == NULL)
|
g_variant_unref (todo);
|
||||||
{
|
data->exit_code = EXIT_SUCCESS;
|
||||||
g_printerr ("Failed to forward arguments: %s\n", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
data->exit_code = EXIT_FAILURE;
|
|
||||||
gtk_main_quit ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_variant_unref (value);
|
|
||||||
data->exit_code = EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
terminal_options_free (data->options);
|
terminal_options_free (data->options);
|
||||||
data->options = NULL;
|
data->options = NULL;
|
||||||
|
|
||||||
gtk_main_quit ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Settings storage works as follows:
|
/* Settings storage works as follows:
|
||||||
* /apps/mate-terminal/global/
|
* ~/.config/gatuno-terminal/config
|
||||||
* /apps/mate-terminal/profiles/Foo/
|
* ~/.config/gatuno-terminal/profiles/Foo/
|
||||||
*
|
*
|
||||||
* It's somewhat tricky to manage the profiles/ dir since we need to track
|
* It's somewhat tricky to manage the profiles/ dir since we need to track
|
||||||
* the list of profiles, but GSettings doesn't have a concept of notifying that
|
* the list of profiles, but GSettings doesn't have a concept of notifying that
|
||||||
|
@ -482,8 +412,11 @@ get_factory_name_for_display (const char *display_name)
|
||||||
{
|
{
|
||||||
GString *name;
|
GString *name;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
int len;
|
||||||
|
|
||||||
name = g_string_sized_new (strlen (TERMINAL_FACTORY_SERVICE_NAME_PREFIX) + strlen (display_name) + 1 /* NUL */);
|
len = strlen (TERMINAL_FACTORY_SERVICE_NAME_PREFIX) + strlen (display_name) + 10 /* NUL */;
|
||||||
|
|
||||||
|
name = g_string_sized_new (len);
|
||||||
g_string_append (name, TERMINAL_FACTORY_SERVICE_NAME_PREFIX);
|
g_string_append (name, TERMINAL_FACTORY_SERVICE_NAME_PREFIX);
|
||||||
|
|
||||||
for (p = display_name; *p; ++p)
|
for (p = display_name; *p; ++p)
|
||||||
|
@ -500,6 +433,83 @@ get_factory_name_for_display (const char *display_name)
|
||||||
return g_string_free (name, FALSE);
|
return g_string_free (name, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void create_factory_unix_socket_folder (void) {
|
||||||
|
char path[8192];
|
||||||
|
|
||||||
|
g_snprintf (path, sizeof (path), "%s%s%s", g_get_user_runtime_dir (), G_DIR_SEPARATOR_S, TERMINAL_FACTORY_UNIX_FOLDER);
|
||||||
|
|
||||||
|
/* Crear el directorio de los sockets unix */
|
||||||
|
g_mkdir_with_parents (path, 0700);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_lock_factory (char *factory_name) {
|
||||||
|
char path[8192];
|
||||||
|
struct flock fl;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
g_snprintf (path, sizeof (path), "%s%s%s%s%s.lock", g_get_user_runtime_dir (), G_DIR_SEPARATOR_S, TERMINAL_FACTORY_UNIX_FOLDER, G_DIR_SEPARATOR_S, factory_name);
|
||||||
|
|
||||||
|
fd = open (path, O_RDWR | O_CREAT, 0600);
|
||||||
|
|
||||||
|
fl.l_start = 0;
|
||||||
|
fl.l_len = 0;
|
||||||
|
fl.l_type = F_WRLCK;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
if (fcntl(fd, F_SETLK, &fl) < 0) {
|
||||||
|
//fputs("Another instance of this program is running.\n", stderr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory_fd_lock = fd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_lock_factory (void) {
|
||||||
|
if (factory_fd_lock != -1) {
|
||||||
|
close (factory_fd_lock);
|
||||||
|
factory_fd_lock = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_bind_factory_unix_socket (char *factory_name) {
|
||||||
|
int s, ret;
|
||||||
|
struct sockaddr_un name;
|
||||||
|
|
||||||
|
s = socket (AF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
if (s < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
name.sun_family = AF_UNIX;
|
||||||
|
g_snprintf (name.sun_path, sizeof (name.sun_path), "%s%s%s%s%s", g_get_user_runtime_dir (), G_DIR_SEPARATOR_S, TERMINAL_FACTORY_UNIX_FOLDER, G_DIR_SEPARATOR_S, factory_name);
|
||||||
|
|
||||||
|
unlink (name.sun_path);
|
||||||
|
|
||||||
|
ret = bind (s, (struct sockaddr *) &name, sizeof (name));
|
||||||
|
if (ret < 0) {
|
||||||
|
close (s);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_factory_unix_socket (char *factory_name) {
|
||||||
|
struct sockaddr_un name;
|
||||||
|
if (factory_unix_fd != -1) {
|
||||||
|
g_source_remove (factory_unix_watch);
|
||||||
|
factory_unix_watch = 0;
|
||||||
|
|
||||||
|
close (factory_unix_fd);
|
||||||
|
factory_unix_fd = -1;
|
||||||
|
|
||||||
|
g_snprintf (name.sun_path, sizeof (name.sun_path), "%s%s%s%s%s", g_get_user_runtime_dir (), G_DIR_SEPARATOR_S, TERMINAL_FACTORY_UNIX_FOLDER, G_DIR_SEPARATOR_S, factory_name);
|
||||||
|
unlink (name.sun_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_initial_workspace (void)
|
get_initial_workspace (void)
|
||||||
{
|
{
|
||||||
|
@ -611,29 +621,65 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
OwnData *data;
|
OwnData *data;
|
||||||
guint owner_id;
|
guint owner_id;
|
||||||
|
GError * error = NULL;
|
||||||
data = g_new (OwnData, 1);
|
data = g_new (OwnData, 1);
|
||||||
data->factory_name = get_factory_name_for_display (display_name);
|
data->factory_name = get_factory_name_for_display (display_name);
|
||||||
data->options = options;
|
data->options = options;
|
||||||
data->exit_code = -1;
|
data->exit_code = -1;
|
||||||
data->argv = argv_copy;
|
data->argv = argv_copy;
|
||||||
data->argc = argc_copy;
|
data->argc = argc_copy;
|
||||||
|
GIOChannel *io_channel;
|
||||||
|
|
||||||
gtk_init(&argc, &argv);
|
gtk_init(&argc, &argv);
|
||||||
options->initial_workspace = get_initial_workspace ();
|
options->initial_workspace = get_initial_workspace ();
|
||||||
|
|
||||||
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
|
/* El proceso del factory funciona así:
|
||||||
data->factory_name,
|
* Si me pidieron usar el factory, intentar conseguir el candado.
|
||||||
G_BUS_NAME_OWNER_FLAGS_NONE,
|
* Si obtenemos el candado, poner el socket a la escucha.
|
||||||
bus_acquired_cb,
|
* Si obtenemos el socket a la escucha, somos el factory. Lanzar terminal
|
||||||
name_acquired_cb,
|
* Si no consigo el socket a la escucha, error. Lanzar terminal como si no hubiera factory.
|
||||||
name_lost_cb,
|
* Si no obtengo el candado, enviar mensaje a la otra terminal.
|
||||||
data, NULL);
|
*/
|
||||||
|
create_factory_unix_socket_folder ();
|
||||||
|
|
||||||
gtk_main ();
|
if (get_lock_factory (data->factory_name) == 0) {
|
||||||
|
factory_unix_fd = do_bind_factory_unix_socket (data->factory_name);
|
||||||
|
|
||||||
|
if (factory_unix_fd >= 0) {
|
||||||
|
/* Soy la factory */
|
||||||
|
_terminal_debug_print (TERMINAL_DEBUG_FACTORY, "Acquired the name %s on the unix socket\n", data->factory_name);
|
||||||
|
/* Instalar un vigilador del socket unix */
|
||||||
|
io_channel = g_io_channel_unix_new (factory_unix_fd);
|
||||||
|
|
||||||
|
factory_unix_watch = g_io_add_watch (io_channel, G_IO_IN, unix_socket_dgram_recv, NULL);
|
||||||
|
} else {
|
||||||
|
/* ¿Tengo lock pero no pude conseguir el socket unix? Raro, soltar el lock, puesto que no puedo recibir las peticiones del factory */
|
||||||
|
release_lock_factory ();
|
||||||
|
|
||||||
|
/* Correr la terminal de a solas */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Correr la terminal */
|
||||||
|
if (!terminal_app_handle_options (terminal_app_get (), data->options, TRUE /* do resume */, &error))
|
||||||
|
{
|
||||||
|
g_printerr ("Failed to handle options: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
data->exit_code = EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
terminal_options_free (data->options);
|
||||||
|
data->options = NULL;
|
||||||
|
|
||||||
|
gtk_main ();
|
||||||
|
}
|
||||||
|
|
||||||
|
release_factory_unix_socket (data->factory_name);
|
||||||
|
release_lock_factory ();
|
||||||
|
} else {
|
||||||
|
/* Ya hay otra factory corriendo, enviar el mensaje */
|
||||||
|
send_ask_open (data->factory_name, data);
|
||||||
|
}
|
||||||
|
|
||||||
ret = data->exit_code;
|
ret = data->exit_code;
|
||||||
g_bus_unown_name (owner_id);
|
|
||||||
|
|
||||||
g_free (data->factory_name);
|
g_free (data->factory_name);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
|
|
Loading…
Reference in New Issue