Branch data Line data Source code
1 : : /* libsecret - GLib wrapper for Secret Service
2 : : *
3 : : * Copyright 2011 Red Hat Inc.
4 : : *
5 : : * This program is free software: you can redistribute it and/or modify
6 : : * it under the terms of the GNU Lesser General Public License as published
7 : : * by the Free Software Foundation; either version 2 of the licence or (at
8 : : * your option) any later version.
9 : : *
10 : : * See the included COPYING file for more information.
11 : : *
12 : : * Author: Stef Walter <stefw@gnome.org>
13 : : */
14 : :
15 : :
16 : : #include "config.h"
17 : :
18 : : #include "mock-service.h"
19 : :
20 : : #include "secret-private.h"
21 : :
22 : : #include <errno.h>
23 : : #include <stdio.h>
24 : : #include <string.h>
25 : :
26 : : #ifdef __linux
27 : : #include <sys/prctl.h>
28 : : #endif
29 : :
30 : : static gchar *service_name = NULL;
31 : : static GPid pid = 0;
32 : :
33 : : static void
34 : 0 : on_python_child_setup (gpointer user_data)
35 : : {
36 : : #ifdef __linux
37 : 0 : prctl (PR_SET_PDEATHSIG, 15);
38 : : #endif
39 : 0 : }
40 : :
41 : : static gchar *
42 : 146 : read_until_end (int fd,
43 : : GError **error)
44 : : {
45 : : GString *data;
46 : : gsize len;
47 : : gssize ret;
48 : : gchar *pos;
49 : :
50 : 146 : data = g_string_new ("");
51 : :
52 : : for (;;) {
53 : 146 : len = data->len;
54 : 146 : g_string_set_size (data, len + 256);
55 : 146 : ret = read (fd, data->str + len, 256);
56 [ - + ]: 146 : if (ret < 0) {
57 [ # # ]: 0 : if (errno != EAGAIN) {
58 : 0 : g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
59 : 0 : "Couldn't read from mock service: %s", g_strerror (errno));
60 : 0 : g_string_free (data, TRUE);
61 : 0 : return NULL;
62 : : }
63 [ - + ]: 146 : } else if (ret == 0) {
64 : 0 : g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Remote closed the output");
65 : 0 : g_string_free (data, TRUE);
66 : 0 : return NULL;
67 : : } else {
68 : 146 : data->len = len + ret;
69 : 146 : data->str[data->len] = '\0';
70 : : }
71 : :
72 : 146 : pos = strchr (data->str, '\n');
73 [ + - ]: 146 : if (pos) {
74 : 146 : g_string_set_size (data, pos - data->str);
75 : 146 : break;
76 : : }
77 : : }
78 : :
79 : 146 : return g_string_free (data, FALSE);
80 : : }
81 : :
82 : : static const gchar *
83 : 146 : service_start (const gchar *mock_script,
84 : : GError **error)
85 : : {
86 : : GSpawnFlags flags;
87 : : gboolean ret;
88 : : gint output;
89 : :
90 : 146 : gchar *argv[] = {
91 : : "python3", (gchar *)mock_script,
92 : : NULL
93 : : };
94 : :
95 [ - + ]: 146 : g_return_val_if_fail (mock_script != NULL, FALSE);
96 [ + - - + ]: 146 : g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
97 : :
98 : 146 : g_free (service_name);
99 : 146 : service_name = NULL;
100 : :
101 : 146 : flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD;
102 : 146 : ret = g_spawn_async_with_pipes (SRCDIR, argv, NULL, flags, on_python_child_setup, NULL, &pid,
103 : : NULL, &output, NULL, error);
104 : :
105 [ + - ]: 146 : if (ret) {
106 : 146 : service_name = read_until_end (output, error);
107 [ + - ]: 146 : if (service_name) {
108 : 146 : g_strstrip (service_name);
109 [ - + ]: 146 : g_assert_cmpstr (service_name, !=, "");
110 : 146 : g_setenv ("SECRET_SERVICE_BUS_NAME", service_name, TRUE);
111 : : }
112 : 146 : close (output);
113 : : }
114 : :
115 : 146 : return service_name;
116 : : }
117 : :
118 : : const gchar *
119 : 146 : mock_service_start (const gchar *mock_script,
120 : : GError **error)
121 : : {
122 : : gchar *path;
123 : : const gchar *name;
124 : :
125 : 146 : path = g_build_filename (SRCDIR, "libsecret", mock_script, NULL);
126 : 146 : name = service_start (path, error);
127 : 146 : g_free (path);
128 : :
129 : 146 : return name;
130 : : }
131 : :
132 : : void
133 : 146 : mock_service_stop (void)
134 : : {
135 [ + + ]: 288 : while (g_main_context_iteration (NULL, FALSE));
136 : :
137 [ + - ]: 146 : if (pid) {
138 [ - + ]: 146 : if (kill (pid, SIGTERM) < 0) {
139 [ # # ]: 0 : if (errno != ESRCH)
140 : 0 : g_warning ("kill() failed: %s", g_strerror (errno));
141 : : }
142 : :
143 : 146 : g_spawn_close_pid (pid);
144 : 146 : pid = 0;
145 : : }
146 : :
147 [ - + ]: 146 : while (g_main_context_iteration (NULL, FALSE));
148 : 146 : g_unsetenv ("SECRET_SERVICE_BUS_NAME");
149 : 146 : }
|