LCOV - code coverage report
Current view: top level - portable - portabled-operation.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 71 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 3 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 62 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "alloc-util.h"
       4                 :            : #include "fd-util.h"
       5                 :            : #include "portabled-operation.h"
       6                 :            : #include "process-util.h"
       7                 :            : 
       8                 :          0 : static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdata) {
       9                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
      10                 :          0 :         Operation *o = userdata;
      11                 :            :         int r;
      12                 :            : 
      13         [ #  # ]:          0 :         assert(o);
      14         [ #  # ]:          0 :         assert(si);
      15                 :            : 
      16         [ #  # ]:          0 :         log_debug("Operating " PID_FMT " is now complete with code=%s status=%i",
      17                 :            :                   o->pid,
      18                 :            :                   sigchld_code_to_string(si->si_code), si->si_status);
      19                 :            : 
      20                 :          0 :         o->pid = 0;
      21                 :            : 
      22         [ #  # ]:          0 :         if (si->si_code != CLD_EXITED) {
      23                 :          0 :                 r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
      24                 :          0 :                 goto fail;
      25                 :            :         }
      26                 :            : 
      27         [ #  # ]:          0 :         if (si->si_status == EXIT_SUCCESS)
      28                 :          0 :                 r = 0;
      29         [ #  # ]:          0 :         else if (read(o->errno_fd, &r, sizeof(r)) != sizeof(r)) { /* Try to acquire error code for failed operation */
      30                 :          0 :                 r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child failed.");
      31                 :          0 :                 goto fail;
      32                 :            :         }
      33                 :            : 
      34         [ #  # ]:          0 :         if (o->done) {
      35                 :            :                 /* A completion routine is set for this operation, call it. */
      36                 :          0 :                 r = o->done(o, r, &error);
      37         [ #  # ]:          0 :                 if (r < 0) {
      38         [ #  # ]:          0 :                         if (!sd_bus_error_is_set(&error))
      39                 :          0 :                                 sd_bus_error_set_errno(&error, r);
      40                 :            : 
      41                 :          0 :                         goto fail;
      42                 :            :                 }
      43                 :            : 
      44                 :            :         } else {
      45                 :            :                 /* The default operation when done is to simply return an error on failure or an empty success
      46                 :            :                  * message on success. */
      47         [ #  # ]:          0 :                 if (r < 0) {
      48                 :          0 :                         sd_bus_error_set_errno(&error, r);
      49                 :          0 :                         goto fail;
      50                 :            :                 }
      51                 :            : 
      52                 :          0 :                 r = sd_bus_reply_method_return(o->message, NULL);
      53         [ #  # ]:          0 :                 if (r < 0)
      54         [ #  # ]:          0 :                         log_error_errno(r, "Failed to reply to message: %m");
      55                 :            :         }
      56                 :            : 
      57                 :          0 :         operation_free(o);
      58                 :          0 :         return 0;
      59                 :            : 
      60                 :          0 : fail:
      61                 :          0 :         r = sd_bus_reply_method_error(o->message, &error);
      62         [ #  # ]:          0 :         if (r < 0)
      63         [ #  # ]:          0 :                 log_error_errno(r, "Failed to reply to message: %m");
      64                 :            : 
      65                 :          0 :         operation_free(o);
      66                 :          0 :         return 0;
      67                 :            : }
      68                 :            : 
      69                 :          0 : int operation_new(Manager *manager, pid_t child, sd_bus_message *message, int errno_fd, Operation **ret) {
      70                 :            :         Operation *o;
      71                 :            :         int r;
      72                 :            : 
      73         [ #  # ]:          0 :         assert(manager);
      74         [ #  # ]:          0 :         assert(child > 1);
      75         [ #  # ]:          0 :         assert(message);
      76         [ #  # ]:          0 :         assert(errno_fd >= 0);
      77                 :            : 
      78                 :          0 :         o = new0(Operation, 1);
      79         [ #  # ]:          0 :         if (!o)
      80                 :          0 :                 return -ENOMEM;
      81                 :            : 
      82                 :          0 :         o->extra_fd = -1;
      83                 :            : 
      84                 :          0 :         r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
      85         [ #  # ]:          0 :         if (r < 0) {
      86                 :          0 :                 free(o);
      87                 :          0 :                 return r;
      88                 :            :         }
      89                 :            : 
      90                 :          0 :         o->pid = child;
      91                 :          0 :         o->message = sd_bus_message_ref(message);
      92                 :          0 :         o->errno_fd = errno_fd;
      93                 :            : 
      94   [ #  #  #  # ]:          0 :         LIST_PREPEND(operations, manager->operations, o);
      95                 :          0 :         manager->n_operations++;
      96                 :          0 :         o->manager = manager;
      97                 :            : 
      98         [ #  # ]:          0 :         log_debug("Started new operation " PID_FMT ".", child);
      99                 :            : 
     100                 :            :         /* At this point we took ownership of both the child and the errno file descriptor! */
     101                 :            : 
     102         [ #  # ]:          0 :         if (ret)
     103                 :          0 :                 *ret = o;
     104                 :            : 
     105                 :          0 :         return 0;
     106                 :            : }
     107                 :            : 
     108                 :          0 : Operation *operation_free(Operation *o) {
     109         [ #  # ]:          0 :         if (!o)
     110                 :          0 :                 return NULL;
     111                 :            : 
     112                 :          0 :         sd_event_source_unref(o->event_source);
     113                 :            : 
     114                 :          0 :         safe_close(o->errno_fd);
     115                 :          0 :         safe_close(o->extra_fd);
     116                 :            : 
     117         [ #  # ]:          0 :         if (o->pid > 1)
     118                 :          0 :                 (void) sigkill_wait(o->pid);
     119                 :            : 
     120                 :          0 :         sd_bus_message_unref(o->message);
     121                 :            : 
     122         [ #  # ]:          0 :         if (o->manager) {
     123   [ #  #  #  #  :          0 :                 LIST_REMOVE(operations, o->manager->operations, o);
             #  #  #  # ]
     124                 :          0 :                 o->manager->n_operations--;
     125                 :            :         }
     126                 :            : 
     127                 :          0 :         return mfree(o);
     128                 :            : }

Generated by: LCOV version 1.14