LCOV - code coverage report
Current view: top level - libsecret - mock-service.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 44 57 77.2 %
Date: 2024-02-08 14:44:34 Functions: 4 5 80.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 14 30 46.7 %

           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 : }

Generated by: LCOV version 1.14