From eb16c037431da14d4f1c396357f82f2b35e76e23 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 9 Oct 2015 16:20:22 -0700 Subject: Remove egg-spawn In looking for places where gnome-keyring-daemon potentially spawns subprocesses, I found this piece of unused code. Remove it. https://bugzilla.gnome.org/show_bug.cgi?id=756324 --- egg/Makefile.am | 7 +- egg/egg-spawn.c | 377 ------------------------------------------------------- egg/egg-spawn.h | 65 ---------- egg/test-spawn.c | 297 ------------------------------------------- po/POTFILES.in | 1 - 5 files changed, 1 insertion(+), 746 deletions(-) delete mode 100644 egg/egg-spawn.c delete mode 100644 egg/egg-spawn.h delete mode 100644 egg/test-spawn.c diff --git a/egg/Makefile.am b/egg/Makefile.am index 38083289..9e081eb7 100644 --- a/egg/Makefile.am +++ b/egg/Makefile.am @@ -33,7 +33,6 @@ libegg_la_SOURCES = \ egg/egg-openssl.c egg/egg-openssl.h \ egg/egg-unix-credentials.c egg/egg-unix-credentials.h \ egg/egg-secure-memory.c egg/egg-secure-memory.h \ - egg/egg-spawn.c egg/egg-spawn.h \ egg/egg-symkey.c egg/egg-symkey.h \ egg/egg-testing.c egg/egg-testing.h \ egg/egg-timegm.c egg/egg-timegm.h \ @@ -132,8 +131,7 @@ egg_TESTS = \ test-armor \ test-openssl \ test-dh \ - test-file-tracker \ - test-spawn + test-file-tracker test_asn1_SOURCES = egg/test-asn1.c egg/test.asn.h test_asn1_LDADD = $(egg_LIBS) @@ -177,8 +175,5 @@ test_openssl_LDADD = $(egg_LIBS) test_dh_SOURCES = egg/test-dh.c test_dh_LDADD = $(egg_LIBS) -test_spawn_SOURCES = egg/test-spawn.c -test_spawn_LDADD = $(egg_LIBS) - check_PROGRAMS += $(egg_TESTS) TESTS += $(egg_TESTS) diff --git a/egg/egg-spawn.c b/egg/egg-spawn.c deleted file mode 100644 index 46f409ba..00000000 --- a/egg/egg-spawn.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * gnome-keyring - * - * Copyright (C) 2009 Stefan Walter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * . - */ - -#include "config.h" - -#include "egg-spawn.h" - -#include - -#include -#include -#include - -#include -#include - -typedef struct _CallbackSource { - GSource source; - EggSpawnCallbacks callbacks; - GPollFD polls[3]; -} CallbackSource; - -static void -close_fd (int *fd) -{ - g_assert (fd); - if (*fd >= 0) - close (*fd); - *fd = -1; -} - -static void -close_poll (GSource *source, GPollFD *poll) -{ - g_source_remove_poll (source, poll); - close_fd (&poll->fd); - poll->revents = 0; -} - -static gboolean -unused_callback (gpointer data) -{ - /* Never called */ - g_assert_not_reached (); - return FALSE; -} - -static gboolean -cb_source_prepare (GSource *source, gint *timeout_) -{ - CallbackSource *cb_source = (CallbackSource*)source; - gint i; - - for (i = 0; i < 3; ++i) { - if (cb_source->polls[i].fd >= 0) - return FALSE; - } - - /* If none of the FDs are valid, then process immediately */ - return TRUE; -} - -static gboolean -cb_source_check (GSource *source) -{ - CallbackSource *cb_source = (CallbackSource*)source; - gint i; - - for (i = 0; i < 3; ++i) { - if (cb_source->polls[i].fd >= 0 && cb_source->polls[i].revents != 0) - return TRUE; - } - return FALSE; -} - -static void -cb_source_finalize (GSource *source) -{ - CallbackSource *cb_source = (CallbackSource*)source; - gint i; - - for (i = 0; i < 3; ++i) - close_fd (&cb_source->polls[i].fd); -} - -static gboolean -cb_source_dispatch (GSource *source, GSourceFunc unused, gpointer user_data) -{ - CallbackSource *cb_source = (CallbackSource*)source; - GPollFD *poll; - gint i; - - /* Standard input */ - poll = &cb_source->polls[0]; - if (poll->fd >= 0 && poll->revents != 0) { - g_assert (cb_source->callbacks.standard_input); - if (!(cb_source->callbacks.standard_input) (poll->fd, user_data)) - close_poll (source, poll); - } - - /* Standard output */ - poll = &cb_source->polls[1]; - if (poll->fd >= 0 && poll->revents != 0) { - g_assert (cb_source->callbacks.standard_output); - if (!(cb_source->callbacks.standard_output) (poll->fd, user_data)) - close_poll (source, poll); - } - - /* Standard error */ - poll = &cb_source->polls[2]; - if (poll->fd >= 0 && poll->revents != 0) { - g_assert (cb_source->callbacks.standard_error); - if (!(cb_source->callbacks.standard_error) (poll->fd, user_data)) - close_poll (source, poll); - } - - for (i = 0; i < 3; ++i) { - if (cb_source->polls[i].fd >= 0) - return TRUE; - } - - /* All input and output is done */ - if (cb_source->callbacks.completed) - (cb_source->callbacks.completed) (user_data); - return FALSE; -} - -static GSourceFuncs cb_source_funcs = { - cb_source_prepare, - cb_source_check, - cb_source_dispatch, - cb_source_finalize, -}; - -guint -egg_spawn_async_with_callbacks (const gchar *working_directory, gchar **argv, - gchar **envp, GSpawnFlags flags, GPid *child_pid, - EggSpawnCallbacks *cbs, gpointer user_data, - GMainContext *context, GError **error) -{ - gint in_fd, out_fd, err_fd; - CallbackSource *cb_source; - GSource *source; - guint tag; - - g_return_val_if_fail (argv != NULL, FALSE); - g_return_val_if_fail ((cbs && cbs->standard_input == NULL) || - !(flags & G_SPAWN_CHILD_INHERITS_STDIN), 0); - g_return_val_if_fail ((cbs && cbs->standard_output == NULL) || - !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), 0); - g_return_val_if_fail ((cbs && cbs->standard_error == NULL) || - !(flags & G_SPAWN_STDERR_TO_DEV_NULL), 0); - - in_fd = out_fd = err_fd = -1; - - if (!g_spawn_async_with_pipes (working_directory, argv, envp, flags, - cbs ? cbs->child_setup : NULL, - user_data, child_pid, - cbs && cbs->standard_input ? &in_fd : NULL, - cbs && cbs->standard_output ? &out_fd : NULL, - cbs && cbs->standard_error ? &err_fd : NULL, - error)) - return 0; - - source = g_source_new (&cb_source_funcs, sizeof (CallbackSource)); - - cb_source = (CallbackSource*)source; - if (cbs != NULL) - memcpy (&cb_source->callbacks, cbs, sizeof (EggSpawnCallbacks)); - - cb_source->polls[0].fd = in_fd; - if (in_fd >= 0) { - g_assert (cb_source->callbacks.standard_input); - cb_source->polls[0].events = G_IO_ERR | G_IO_OUT; - g_source_add_poll (source, &cb_source->polls[0]); - } - cb_source->polls[1].fd = out_fd; - if (out_fd >= 0) { - g_assert (cb_source->callbacks.standard_output); - cb_source->polls[1].events = G_IO_ERR | G_IO_HUP | G_IO_IN; - g_source_add_poll (source, &cb_source->polls[1]); - } - cb_source->polls[2].fd = err_fd; - if (err_fd >= 0) { - g_assert (cb_source->callbacks.standard_error); - cb_source->polls[2].events = G_IO_ERR | G_IO_HUP | G_IO_IN; - g_source_add_poll (source, &cb_source->polls[2]); - } - - if (context == NULL) - context = g_main_context_default (); - g_source_set_callback (source, unused_callback, user_data, - cbs ? cbs->finalize_func : NULL); - tag = g_source_attach (source, context); - g_source_unref (source); - - return tag; -} - -gboolean -egg_spawn_sync_with_callbacks (const gchar *working_directory, gchar **argv, - gchar **envp, GSpawnFlags flags, GPid *child_pid, - EggSpawnCallbacks *cbs, gpointer user_data, - gint *exit_status, GError **error) -{ - gint in_fd, out_fd, err_fd, max_fd; - fd_set read_fds, write_fds; - gboolean failed = FALSE; - gint status; - GPid pid; - gint ret; - - g_return_val_if_fail (argv != NULL, FALSE); - g_return_val_if_fail ((cbs && cbs->standard_input == NULL) || - !(flags & G_SPAWN_CHILD_INHERITS_STDIN), 0); - g_return_val_if_fail ((cbs && cbs->standard_output == NULL) || - !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), 0); - g_return_val_if_fail ((cbs && cbs->standard_error == NULL) || - !(flags & G_SPAWN_STDERR_TO_DEV_NULL), 0); - - in_fd = out_fd = err_fd = -1; - - if (exit_status) - flags |= G_SPAWN_DO_NOT_REAP_CHILD; - - if (!g_spawn_async_with_pipes (working_directory, argv, envp, flags, - cbs ? cbs->child_setup : NULL, - user_data, &pid, - cbs && cbs->standard_input ? &in_fd : NULL, - cbs && cbs->standard_output ? &out_fd : NULL, - cbs && cbs->standard_error ? &err_fd : NULL, - error)) - return FALSE; - - if (child_pid) - *child_pid = pid; - - max_fd = MAX (in_fd, MAX (out_fd, err_fd)) + 1; - - while (in_fd >= 0 || out_fd >= 0 || err_fd >= 0) { - - FD_ZERO (&write_fds); - if (in_fd >= 0) - FD_SET (in_fd, &write_fds); - FD_ZERO (&read_fds); - if (out_fd >= 0) - FD_SET (out_fd, &read_fds); - if (err_fd >= 0) - FD_SET (err_fd, &read_fds); - - ret = select (max_fd, &read_fds, &write_fds, NULL, NULL); - if (ret < 0 && errno != EINTR) { - failed = TRUE; - g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ, - _("Unexpected error in select() reading data from a child process (%s)"), - g_strerror (errno)); - break; - } - - if (in_fd >= 0 && FD_ISSET (in_fd, &write_fds)) { - g_assert (cbs && cbs->standard_input); - if (!(cbs->standard_input) (in_fd, user_data)) - close_fd (&in_fd); - } - if (out_fd >= 0 && FD_ISSET (out_fd, &read_fds)) { - g_assert (cbs && cbs->standard_output); - if (!(cbs->standard_output) (out_fd, user_data)) - close_fd (&out_fd); - } - if (err_fd >= 0 && FD_ISSET (err_fd, &read_fds)) { - g_assert (cbs && cbs->standard_error); - if (!(cbs->standard_error) (err_fd, user_data)) - close_fd (&err_fd); - } - } - - if (in_fd >= 0) - close_fd (&in_fd); - if (out_fd >= 0) - close_fd (&out_fd); - if (err_fd >= 0) - close_fd (&err_fd); - - if (!failed) { - if (cbs && cbs->completed) - (cbs->completed) (user_data); - } - -again: - ret = waitpid (pid, &status, 0); - if (ret < 0) { - if (errno == EINTR) - goto again; - else if (errno == ECHILD) { - if (exit_status) - g_warning ("In call to g_spawn_sync(), exit status of a child process was requested but SIGCHLD action was set to SIG_IGN and ECHILD was received by waitpid(), so exit status can't be returned. This is a bug in the program calling g_spawn_sync(); either don't request the exit status, or don't set the SIGCHLD action."); - else - ; /* We don't need the exit status. */ - } else if (!failed) { /* avoid error pileups */ - failed = TRUE; - g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ, - _("Unexpected error in waitpid() (%s)"), - g_strerror (errno)); - } - } else { - if (exit_status) - *exit_status = status; - } - - if (!child_pid) - g_spawn_close_pid (pid); - - if (cbs && cbs->finalize_func) - (cbs->finalize_func) (user_data); - - return !failed; -} - -gssize -egg_spawn_write_input (int fd, gconstpointer data, gsize n_data) -{ - gssize result; - - g_return_val_if_fail (fd >= 0, -1); - - for (;;) { - result = write (fd, data, n_data); - if (result < 0) { - if (errno == EINTR) - continue; - else if (errno == EAGAIN) - result = 0; - } - break; - } - - return result; -} - -gssize -egg_spawn_read_output (int fd, gpointer data, gsize n_data) -{ - gssize result; - - g_return_val_if_fail (fd >= 0, -1); - - for (;;) { - result = read (fd, data, n_data); - if (result < 0) { - if (errno == EINTR) - continue; - else if (errno == EAGAIN) - result = 0; - } - break; - } - - return result; -} - diff --git a/egg/egg-spawn.h b/egg/egg-spawn.h deleted file mode 100644 index c611d4e6..00000000 --- a/egg/egg-spawn.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* egg-sub-process.h - spawn a subprocess and perform IO - - Copyright (C) 2009 Stefan Walter - - Gnome keyring 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. - - Gnome keyring 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., 675 Mass Ave, Cambridge, MA 02139, USA. - - Author: Stef Walter -*/ - -#ifndef EGG_SPAWN_H_ -#define EGG_SUB_PROCESS_H_ - -#include - -G_BEGIN_DECLS - -typedef struct _EggSpawnCallbacks { - gboolean (*standard_input) (int fd, gpointer user_data); - gboolean (*standard_output) (int fd, gpointer user_data); - gboolean (*standard_error) (int fd, gpointer user_data); - void (*completed) (gpointer user_data); - GDestroyNotify finalize_func; - GSpawnChildSetupFunc child_setup; -} EggSpawnCallbacks; - -guint egg_spawn_async_with_callbacks (const gchar *working_directory, - gchar **argv, - gchar **envp, - GSpawnFlags flags, - GPid *child_pid, - EggSpawnCallbacks *callbacks, - gpointer user_data, - GMainContext *context, - GError **error); - -gboolean egg_spawn_sync_with_callbacks (const gchar *working_directory, - gchar **argv, - gchar **envp, - GSpawnFlags flags, - GPid *child_pid, - EggSpawnCallbacks *callbacks, - gpointer user_data, - gint *exit_status, - GError **error); - -gssize egg_spawn_write_input (int fd, gconstpointer data, gsize n_data); - -gssize egg_spawn_read_output (int fd, gpointer data, gsize n_data); - -G_END_DECLS - -#endif /*EGG_SPAWN_H_*/ diff --git a/egg/test-spawn.c b/egg/test-spawn.c deleted file mode 100644 index 2a0fec18..00000000 --- a/egg/test-spawn.c +++ /dev/null @@ -1,297 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* unit-test-dh.c: Test egg-spawn.c - - Copyright (C) 2009 Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - . - - Author: Stef Walter -*/ - -#include "config.h" - -#include "egg/egg-spawn.h" -#include "egg/egg-testing.h" - -#include - -#include -#include -#include -#include -#include - -typedef struct _EchoData { - gint index; - gchar *output; - gchar *error; - gboolean finalized; - gboolean completed; - gboolean is_async; - pid_t parent_pid; -} EchoData; - -static gboolean -want_input (gint fd, gpointer user_data) -{ - EchoData *data = user_data; - gchar *buffer; - - g_assert (data); - if (data->index == 85) - return FALSE; - - g_assert (data->index >= 80); - g_assert (data->index < 85); - - buffer = g_strdup_printf ("%d\n", data->index); - if (egg_spawn_write_input (fd, (guchar*)buffer, strlen (buffer)) < 0) - g_assert_not_reached (); - g_free (buffer); - ++data->index; - return TRUE; -} - -static gboolean -have_output (gint fd, gpointer user_data) -{ - EchoData *data = user_data; - gchar buffer[1024]; - gssize length; - gchar *output; - - g_assert (data); - - length = egg_spawn_read_output (fd, (guchar*)buffer, 1023); - g_assert (length >= 0); - - buffer[length] = 0; - output = g_strconcat (data->output ? data->output : "", buffer, NULL); - g_free (data->output); - data->output = output; - - return (length > 0); -} - -static gboolean -have_error (gint fd, gpointer user_data) -{ - EchoData *data = user_data; - gchar buffer[1024]; - gssize length; - gchar *error; - - g_assert (data); - - length = egg_spawn_read_output (fd, (guchar*)buffer, 1023); - g_assert (length >= 0); - - buffer[length] = 0; - error = g_strconcat (data->error ? data->error : "", buffer, NULL); - g_free (data->error); - data->error = error; - - return (length > 0); -} - -static void -completed_func (gpointer user_data) -{ - EchoData *data = user_data; - g_assert (data); - g_assert (!data->finalized); - g_assert (!data->completed); - data->completed = TRUE; - if (data->is_async) - egg_test_wait_stop (); -} - -static void -finalize_func (gpointer user_data) -{ - EchoData *data = user_data; - g_assert (!data->finalized); - data->finalized = 1; -} - -static void -child_setup (gpointer user_data) -{ - EchoData *data = user_data; - g_assert (data->parent_pid != getpid ()); -} - -static EggSpawnCallbacks echo_callbacks = { - want_input, - have_output, - have_error, - completed_func, - finalize_func, - child_setup, -}; - -static char* echo_argv[] = { - "/bin/sh", - "./echo-script.sh", - NULL -}; - -static char* error_argv[] = { - "/nonexistent", - NULL -}; - -static EggSpawnCallbacks null_callbacks = { - NULL, - NULL, - NULL, - completed_func, - finalize_func, - child_setup, -}; - -static void -test_sync (void) -{ - GError *error = NULL; - gboolean ret; - gint exit_status; - EchoData data; - GPid pid = 0; - - memset (&data, 0, sizeof (data)); - data.parent_pid = getpid(); - data.index = 80; - - ret = egg_spawn_sync_with_callbacks (SRCDIR "/egg/fixtures", - echo_argv, NULL, 0, &pid, - &echo_callbacks, &data, - &exit_status, &error); - g_assert (ret == TRUE); - g_assert (pid != 0); - g_assert (WIFEXITED (exit_status)); - g_assert_cmpint (WEXITSTATUS(exit_status), ==, 3); - g_assert (error == NULL); - g_assert (data.finalized); - g_assert (data.completed); - g_assert_cmpstr (data.output, ==, "80 81 82 83 84\n"); - g_assert_cmpstr (data.error, ==, "1\n2\n3\n4\n5\n"); - g_free (data.error); - g_free (data.output); -} - -static void -test_sync_error (void) -{ - GError *error = NULL; - gboolean ret; - - ret = egg_spawn_sync_with_callbacks (SRCDIR "/egg/fixtures", - error_argv, NULL, 0, NULL, - NULL, NULL, - NULL, &error); - g_assert (ret == FALSE); - g_assert (error != NULL); - g_clear_error (&error); -} - - -static void -test_async (void) -{ - GError *error = NULL; - EchoData data; - guint ret; - GPid pid; - - memset (&data, 0, sizeof (data)); - data.parent_pid = getpid(); - data.index = 80; - data.is_async = TRUE; - - ret = egg_spawn_async_with_callbacks (SRCDIR "/egg/fixtures", - echo_argv, NULL, 0, &pid, - &echo_callbacks, &data, - NULL, &error); - g_assert (ret != 0); - g_assert (error == NULL); - g_assert (!data.finalized); - - egg_test_wait_until (2000); - - g_assert (data.finalized); - g_assert (data.completed); - g_assert_cmpstr (data.output, ==, "80 81 82 83 84\n"); - g_assert_cmpstr (data.error, ==, "1\n2\n3\n4\n5\n"); - g_free (data.error); - g_free (data.output); -} - -static void -test_async_none (void) -{ - GError *error = NULL; - EchoData data; - guint ret; - - memset (&data, 0, sizeof (data)); - data.parent_pid = getpid(); - data.is_async = TRUE; - - ret = egg_spawn_async_with_callbacks (SRCDIR "/egg/fixtures", - echo_argv, NULL, 0, NULL, - &null_callbacks, &data, - NULL, &error); - g_assert (ret != 0); - g_assert (error == NULL); - g_assert (!data.finalized); - - egg_test_wait_until (2000); - - g_assert (data.finalized); - g_assert (data.completed); - g_assert (!data.output); - g_free (data.error); - g_free (data.output); -} - -static void -test_async_error (void) -{ - GError *error = NULL; - guint ret; - - ret = egg_spawn_async_with_callbacks (SRCDIR "/egg/fixtures", - error_argv, NULL, 0, NULL, - NULL, NULL, - NULL, &error); - g_assert (ret == 0); - g_assert (error != NULL); - g_clear_error (&error); -} - -int -main (int argc, char **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/spawn/sync", test_sync); - g_test_add_func ("/spawn/sync_error", test_sync_error); - g_test_add_func ("/spawn/async", test_async); - g_test_add_func ("/spawn/async_none", test_async_none); - g_test_add_func ("/spawn/async_error", test_async_error); - - return egg_tests_run_in_thread_with_loop (); -} diff --git a/po/POTFILES.in b/po/POTFILES.in index 6d1a337e..ed293327 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -10,7 +10,6 @@ daemon/login/gkd-login.c daemon/org.gnome.keyring.service.in egg/dotlock.c egg/egg-oid.c -egg/egg-spawn.c pkcs11/gkm/gkm-certificate.c pkcs11/secret-store/gkm-secret-collection.c pkcs11/ssh-store/gkm-ssh-private-key.c -- cgit v1.2.1