|
| 1 | +/* |
| 2 | + * Copyright (c) 2018, United States government as represented by the |
| 3 | + * administrator of the National Aeronautics Space Administration. |
| 4 | + * All rights reserved. This software was created at NASA Glenn |
| 5 | + * Research Center pursuant to government contracts. |
| 6 | + * |
| 7 | + * This is governed by the NASA Open Source Agreement and may be used, |
| 8 | + * distributed and modified only according to the terms of that agreement. |
| 9 | + */ |
| 10 | + |
| 11 | +/** |
| 12 | + * \file osshell.c |
| 13 | + * |
| 14 | + * Purpose: Implements shell-related calls that can be optionally built |
| 15 | + * for distributions that choose to support them. Alternatively |
| 16 | + * build the portable no-shell implementation to exclude this |
| 17 | + * functionality. |
| 18 | + */ |
| 19 | + |
| 20 | +/**************************************************************************************** |
| 21 | + INCLUDE FILES |
| 22 | + ***************************************************************************************/ |
| 23 | + |
| 24 | +#include "os-posix.h" |
| 25 | + |
| 26 | +#include <sys/types.h> |
| 27 | +#include <sys/wait.h> |
| 28 | + |
| 29 | +/**************************************************************************************** |
| 30 | + IMPLEMENTATION-SPECIFIC ROUTINES |
| 31 | + These are specific to this particular operating system |
| 32 | + ****************************************************************************************/ |
| 33 | + |
| 34 | +/*---------------------------------------------------------------- |
| 35 | + * |
| 36 | + * Function: OS_ShellOutputToFile_Impl |
| 37 | + * |
| 38 | + * Purpose: Implemented per internal OSAL API |
| 39 | + * See prototype in os-impl.h for argument/return detail |
| 40 | + * |
| 41 | + *-----------------------------------------------------------------*/ |
| 42 | +int32 OS_ShellOutputToFile_Impl(uint32 file_id, const char* Cmd) |
| 43 | +{ |
| 44 | + pid_t cpid; |
| 45 | + uint32 local_id; |
| 46 | + int wstat; |
| 47 | + const char *shell = getenv("SHELL"); |
| 48 | + |
| 49 | + if (shell == NULL) |
| 50 | + { |
| 51 | + shell = "/bin/sh"; |
| 52 | + } |
| 53 | + |
| 54 | + cpid = fork(); |
| 55 | + if (cpid < 0) |
| 56 | + { |
| 57 | + OS_DEBUG("%s(): Error during fork(): %s\n", __func__, strerror(errno)); |
| 58 | + return OS_ERROR; |
| 59 | + } |
| 60 | + |
| 61 | + if (cpid == 0) |
| 62 | + { |
| 63 | + /* child process */ |
| 64 | + dup2(OS_impl_filehandle_table[file_id].fd, STDOUT_FILENO); |
| 65 | + dup2(OS_impl_filehandle_table[file_id].fd, STDERR_FILENO); |
| 66 | + |
| 67 | + /* close all _other_ filehandles */ |
| 68 | + for (local_id = 0; local_id < OS_MAX_NUM_OPEN_FILES; ++local_id) |
| 69 | + { |
| 70 | + if (OS_global_stream_table[local_id].active_id != 0) |
| 71 | + { |
| 72 | + close(OS_impl_filehandle_table[local_id].fd); |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + execl(shell, "sh", "-c", Cmd, NULL); /* does not return if successful */ |
| 77 | + exit(EXIT_FAILURE); |
| 78 | + } |
| 79 | + |
| 80 | + if (waitpid(cpid, &wstat, 0) != cpid) |
| 81 | + { |
| 82 | + OS_DEBUG("%s(): Error during waitpid(): %s\n", __func__, strerror(errno)); |
| 83 | + return OS_ERROR; |
| 84 | + } |
| 85 | + |
| 86 | + if (!WIFEXITED(wstat) || WEXITSTATUS(wstat) != 0) |
| 87 | + { |
| 88 | + OS_DEBUG("%s(): Error from child process: %d\n", __func__, wstat); |
| 89 | + return OS_ERROR; |
| 90 | + } |
| 91 | + |
| 92 | + return OS_SUCCESS; |
| 93 | +} /* end OS_ShellOutputToFile_Impl */ |
| 94 | + |
0 commit comments