Skip to content
Snippets Groups Projects
Commit e241c0d3 authored by Simon McVittie's avatar Simon McVittie
Browse files

PvPortalListener: Take over responsibility for info fd and stdout


Any service that has a similar protocol for signalling when it is
ready to receive requests is going to need something quite similar
to this.

Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent 21bde9a7
No related branches found
No related tags found
1 merge request!170Preparation for input portal
...@@ -60,8 +60,7 @@ typedef GDBusServer AutoDBusServer; ...@@ -60,8 +60,7 @@ typedef GDBusServer AutoDBusServer;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(AutoDBusServer, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(AutoDBusServer, g_object_unref)
static PvPortalListener *global_listener; static PvPortalListener *global_listener;
static FILE *original_stdout = NULL;
static FILE *info_fh = NULL;
static GHashTable *lock_env_hash = NULL; static GHashTable *lock_env_hash = NULL;
static GDBusConnection *session_bus = NULL; static GDBusConnection *session_bus = NULL;
static GHashTable *client_pid_data_hash = NULL; static GHashTable *client_pid_data_hash = NULL;
...@@ -69,20 +68,6 @@ static guint name_owner_id = 0; ...@@ -69,20 +68,6 @@ static guint name_owner_id = 0;
static GMainLoop *main_loop; static GMainLoop *main_loop;
static PvLauncher1 *launcher; static PvLauncher1 *launcher;
/*
* Close the --info-fd, and also close standard output (if different).
*/
static void
close_info_fh (void)
{
if (info_fh == original_stdout)
original_stdout = NULL;
else
g_clear_pointer (&original_stdout, fclose);
g_clear_pointer (&info_fh, fclose);
}
static void static void
skeleton_died_cb (gpointer data) skeleton_died_cb (gpointer data)
{ {
...@@ -634,10 +619,7 @@ on_name_acquired (GDBusConnection *connection, ...@@ -634,10 +619,7 @@ on_name_acquired (GDBusConnection *connection,
if (*ret == EX_UNAVAILABLE) if (*ret == EX_UNAVAILABLE)
{ {
*ret = 0; *ret = 0;
g_assert (info_fh != NULL); pv_portal_listener_close_info_fh (global_listener, name);
fprintf (info_fh, "bus_name=%s\n", name);
fflush (info_fh);
close_info_fh ();
} }
} }
...@@ -1158,32 +1140,14 @@ main (int argc, ...@@ -1158,32 +1140,14 @@ main (int argc,
G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO, G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO,
cli_log_func, (void *) g_get_prgname ()); cli_log_func, (void *) g_get_prgname ());
original_stdout = _srt_divert_stdout_to_stderr (error); if (!pv_portal_listener_set_up_info_fd (global_listener,
opt_info_fd,
if (original_stdout == NULL) error))
{ {
ret = EX_OSERR; ret = EX_OSERR;
goto out; goto out;
} }
if (opt_info_fd > 0) /* < 0 means unset, and 0 is stdout itself */
{
info_fh = fdopen (opt_info_fd, "w");
if (info_fh == NULL)
{
glnx_null_throw_errno_prefix (error,
"Unable to create a stdio wrapper for fd %d",
opt_info_fd);
ret = EX_OSERR;
goto out;
}
}
else
{
info_fh = original_stdout;
}
lock_env_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); lock_env_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
if (opt_lock_env_fd >= 0) if (opt_lock_env_fd >= 0)
...@@ -1392,17 +1356,14 @@ main (int argc, ...@@ -1392,17 +1356,14 @@ main (int argc,
} }
if (opt_socket != NULL) if (opt_socket != NULL)
fprintf (info_fh, "socket=%s\n", opt_socket); fprintf (global_listener->info_fh, "socket=%s\n", opt_socket);
if (server != NULL) if (server != NULL)
fprintf (info_fh, "dbus_address=%s\n", fprintf (global_listener->info_fh, "dbus_address=%s\n",
g_dbus_server_get_client_address (server)); g_dbus_server_get_client_address (server));
if (opt_bus_name == NULL) if (opt_bus_name == NULL)
{ pv_portal_listener_close_info_fh (global_listener, NULL);
fflush (info_fh);
close_info_fh ();
}
g_debug ("Entering main loop"); g_debug ("Entering main loop");
...@@ -1440,7 +1401,6 @@ out: ...@@ -1440,7 +1401,6 @@ out:
ret = EX_UNAVAILABLE; ret = EX_UNAVAILABLE;
g_clear_error (&local_error); g_clear_error (&local_error);
close_info_fh ();
g_debug ("Exiting with status %d", ret); g_debug ("Exiting with status %d", ret);
return ret; return ret;
......
...@@ -48,12 +48,67 @@ pv_portal_listener_init (PvPortalListener *self) ...@@ -48,12 +48,67 @@ pv_portal_listener_init (PvPortalListener *self)
pv_get_current_dirs (NULL, &self->original_cwd_l); pv_get_current_dirs (NULL, &self->original_cwd_l);
} }
/*
* Divert stdout to stderr, and set up the --info-fd to be the
* original stdout or a specified fd.
*/
gboolean
pv_portal_listener_set_up_info_fd (PvPortalListener *self,
int fd,
GError **error)
{
self->original_stdout = _srt_divert_stdout_to_stderr (error);
if (self->original_stdout == NULL)
return FALSE;
if (fd > 0) /* < 0 means unset, and 0 is stdout itself */
{
self->info_fh = fdopen (fd, "w");
if (self->info_fh == NULL)
return glnx_throw_errno_prefix (error,
"Unable to create a stdio wrapper for fd %d",
fd);
}
else
{
self->info_fh = self->original_stdout;
}
return TRUE;
}
/*
* If @bus_name is non-NULL, print it to the info fd. Then
* close the --info-fd, and also close standard output (if different).
*/
void
pv_portal_listener_close_info_fh (PvPortalListener *self,
const char *bus_name)
{
if (self->info_fh != NULL)
{
if (bus_name != NULL)
fprintf (self->info_fh, "bus_name=%s\n", bus_name);
fflush (self->info_fh);
}
if (self->info_fh == self->original_stdout)
self->original_stdout = NULL;
else
g_clear_pointer (&self->original_stdout, fclose);
g_clear_pointer (&self->info_fh, fclose);
}
static void static void
pv_portal_listener_dispose (GObject *object) pv_portal_listener_dispose (GObject *object)
{ {
PvPortalListener *self = PV_PORTAL_LISTENER (object); PvPortalListener *self = PV_PORTAL_LISTENER (object);
(void) self; pv_portal_listener_close_info_fh (self, NULL);
G_OBJECT_CLASS (pv_portal_listener_parent_class)->dispose (object); G_OBJECT_CLASS (pv_portal_listener_parent_class)->dispose (object);
} }
......
...@@ -51,9 +51,18 @@ struct _PvPortalListener ...@@ -51,9 +51,18 @@ struct _PvPortalListener
{ {
GObject parent; GObject parent;
GStrv original_environ; GStrv original_environ;
FILE *original_stdout;
FILE *info_fh;
gchar *original_cwd_l; gchar *original_cwd_l;
}; };
PvPortalListener *pv_portal_listener_new (void); PvPortalListener *pv_portal_listener_new (void);
gboolean pv_portal_listener_set_up_info_fd (PvPortalListener *self,
int fd,
GError **error);
void pv_portal_listener_close_info_fh (PvPortalListener *self,
const char *bus_name);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PvPortalListener, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (PvPortalListener, g_object_unref)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment