LCOV - code coverage report
Current view: top level - src/plugins/shell - shell.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 31 58 53.4 %
Date: 2019-09-12 12:28:41 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief Source for shell plugin
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  *
       8             :  */
       9             : 
      10             : #include "shell.h"
      11             : #include <errno.h>
      12             : #include <kdberrors.h>
      13             : #include <kdbhelper.h>
      14             : #include <stdio.h>
      15             : #include <stdlib.h>
      16             : #include <sys/types.h>
      17             : #include <sys/wait.h>
      18             : #include <unistd.h>
      19             : 
      20             : 
      21           2 : static int executeCommand (const char * cmdline)
      22             : {
      23             :         char * cmd[4];
      24           2 :         cmd[0] = "/bin/sh";
      25           2 :         cmd[1] = "-c";
      26           2 :         cmd[2] = (char *) cmdline;
      27           2 :         cmd[3] = NULL;
      28             : 
      29           2 :         pid_t pid = fork ();
      30           2 :         if (pid == 0)
      31             :         {
      32           0 :                 return execv ("/bin/sh", cmd);
      33             :         }
      34           2 :         else if (pid > 0)
      35             :         {
      36             :                 int status;
      37           2 :                 wait (&status);
      38           2 :                 return WEXITSTATUS (status);
      39             :         }
      40             :         else
      41             :         {
      42             :                 return -1;
      43             :         }
      44             : }
      45             : 
      46          32 : int elektraShellGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
      47             : {
      48          32 :         if (!elektraStrCmp (keyName (parentKey), "system/elektra/modules/shell"))
      49             :         {
      50          31 :                 KeySet * contract =
      51          31 :                         ksNew (30, keyNew ("system/elektra/modules/shell", KEY_VALUE, "shell plugin waits for your orders", KEY_END),
      52             :                                keyNew ("system/elektra/modules/shell/exports", KEY_END),
      53             :                                keyNew ("system/elektra/modules/shell/exports/get", KEY_FUNC, elektraShellGet, KEY_END),
      54             :                                keyNew ("system/elektra/modules/shell/exports/set", KEY_FUNC, elektraShellSet, KEY_END),
      55             :                                keyNew ("system/elektra/modules/shell/exports/error", KEY_FUNC, elektraShellError, KEY_END),
      56             : #include ELEKTRA_README
      57             :                                keyNew ("system/elektra/modules/shell/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END);
      58          31 :                 ksAppend (returned, contract);
      59          31 :                 ksDel (contract);
      60             : 
      61          31 :                 return 1; // success
      62             :         }
      63           1 :         KeySet * config = elektraPluginGetConfig (handle);
      64           1 :         Key * cmdKey = ksLookupByName (config, "/execute/get", KDB_O_NONE);
      65           1 :         Key * expectedReturnKey = ksLookupByName (config, "/execute/get/return", KDB_O_NONE);
      66           1 :         if (cmdKey == NULL)
      67             :                 return 1;
      68             :         else
      69             :         {
      70           0 :                 int retVal = executeCommand (keyString (cmdKey));
      71           0 :                 if (retVal == -1)
      72             :                 {
      73           0 :                         ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Launching childprocess failed. Reason: %s", strerror (errno));
      74           0 :                         return -1;
      75             :                 }
      76           0 :                 else if (expectedReturnKey)
      77             :                 {
      78           0 :                         if (atoi (keyString (expectedReturnKey)) != retVal)
      79             :                         {
      80           0 :                                 ELEKTRA_SET_PLUGIN_MISBEHAVIOR_ERRORF (parentKey,
      81             :                                                                        "Return value of '%s' doesn't match expected exit. Reason: %s",
      82             :                                                                        keyString (cmdKey), keyString (expectedReturnKey));
      83           0 :                                 return -1;
      84             :                         }
      85             :                 }
      86             :         }
      87             :         return 1; // success
      88             : }
      89             : 
      90           2 : int elektraShellSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned ELEKTRA_UNUSED, Key * parentKey)
      91             : {
      92           2 :         KeySet * config = elektraPluginGetConfig (handle);
      93           2 :         Key * cmdKey = ksLookupByName (config, "/execute/set", KDB_O_NONE);
      94           2 :         Key * expectedReturnKey = ksLookupByName (config, "/execute/set/return", KDB_O_NONE);
      95           2 :         if (cmdKey == NULL)
      96             :                 return 1;
      97             :         else
      98             :         {
      99           2 :                 int retVal = executeCommand (keyString (cmdKey));
     100           2 :                 if (retVal == -1)
     101             :                 {
     102           0 :                         ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Launching childprocess failed. Reason: %s", strerror (errno));
     103           0 :                         return -1;
     104             :                 }
     105           2 :                 else if (expectedReturnKey)
     106             :                 {
     107           0 :                         if (atoi (keyString (expectedReturnKey)) != retVal)
     108             :                         {
     109           0 :                                 ELEKTRA_SET_PLUGIN_MISBEHAVIOR_ERRORF (parentKey,
     110             :                                                                        "Return value of '%s' doesn't match expected exit. Reason: %s",
     111             :                                                                        keyString (cmdKey), keyString (expectedReturnKey));
     112           0 :                                 return -1;
     113             :                         }
     114             :                 }
     115             :         }
     116             :         return 1; // success
     117             : }
     118             : 
     119           0 : int elektraShellError (Plugin * handle ELEKTRA_UNUSED, KeySet * returned ELEKTRA_UNUSED, Key * parentKey)
     120             : {
     121           0 :         KeySet * config = elektraPluginGetConfig (handle);
     122           0 :         Key * cmdKey = ksLookupByName (config, "/execute/error", KDB_O_NONE);
     123           0 :         Key * expectedReturnKey = ksLookupByName (config, "/execute/error/return", KDB_O_NONE);
     124           0 :         if (cmdKey == NULL)
     125             :                 return 1;
     126             :         else
     127             :         {
     128           0 :                 int retVal = executeCommand (keyString (cmdKey));
     129           0 :                 if (retVal == -1)
     130             :                 {
     131           0 :                         ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Launching childprocess failed. Reason: %s", strerror (errno));
     132           0 :                         return -1;
     133             :                 }
     134           0 :                 else if (expectedReturnKey)
     135             :                 {
     136           0 :                         if (atoi (keyString (expectedReturnKey)) != retVal)
     137             :                         {
     138           0 :                                 ELEKTRA_SET_PLUGIN_MISBEHAVIOR_ERRORF (parentKey,
     139             :                                                                        "Return value of '%s' doesn't match expected exit. Reason: %s",
     140             :                                                                        keyString (cmdKey), keyString (expectedReturnKey));
     141           0 :                                 return -1;
     142             :                         }
     143             :                 }
     144             :         }
     145             :         return 1; // success
     146             : }
     147             : 
     148          55 : Plugin * ELEKTRA_PLUGIN_EXPORT
     149             : {
     150          55 :         return elektraPluginExport ("shell", ELEKTRA_PLUGIN_GET, &elektraShellGet, ELEKTRA_PLUGIN_SET, &elektraShellSet,
     151             :                                     ELEKTRA_PLUGIN_ERROR, &elektraShellError, ELEKTRA_PLUGIN_END);
     152             : }

Generated by: LCOV version 1.13