\doxysection{src/core/exec.c File Reference}
\label{exec_8c}\index{src/core/exec.c@{src/core/exec.c}}
{\ttfamily \#include \char`\"{}config.\+h\char`\"{}}\newline
{\ttfamily \#include $<$unistd.\+h$>$}\newline
{\ttfamily \#include $<$errno.\+h$>$}\newline
{\ttfamily \#include $<$string.\+h$>$}\newline
{\ttfamily \#include $<$stdio.\+h$>$}\newline
{\ttfamily \#include $<$dirent.\+h$>$}\newline
{\ttfamily \#include $<$sys/types.\+h$>$}\newline
{\ttfamily \#include $<$pwd.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/logging.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/utils.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/exec.\+h$>$}\newline
\doxysubsection*{Macros}
\begin{DoxyCompactItemize}
\item 
\#define \textbf{ \+\_\+\+GNU\+\_\+\+SOURCE}
\end{DoxyCompactItemize}
\doxysubsection*{Functions}
\begin{DoxyCompactItemize}
\item 
static bool \textbf{ str\+\_\+in\+\_\+list} (const char $\ast$$\ast$\textbf{ list}, const char $\ast$key)
\item 
int \textbf{ osmo\+\_\+environment\+\_\+filter} (char $\ast$$\ast$out, size\+\_\+t out\+\_\+len, char $\ast$$\ast$in, const char $\ast$$\ast$whitelist)
\begin{DoxyCompactList}\small\item\em filtered a process environment by whitelist; only copying pointers, no actual strings. \end{DoxyCompactList}\item 
int \textbf{ osmo\+\_\+environment\+\_\+append} (char $\ast$$\ast$out, size\+\_\+t out\+\_\+len, char $\ast$$\ast$in)
\begin{DoxyCompactList}\small\item\em append one environment to another; only copying pointers, not actual strings. \end{DoxyCompactList}\item 
int \textbf{ osmo\+\_\+close\+\_\+all\+\_\+fds\+\_\+above} (int last\+\_\+fd\+\_\+to\+\_\+keep)
\item 
int \textbf{ osmo\+\_\+system\+\_\+nowait2} (const char $\ast$command, const char $\ast$$\ast$env\+\_\+whitelist, char $\ast$$\ast$addl\+\_\+env, const char $\ast$user)
\begin{DoxyCompactList}\small\item\em call an external shell command as \textquotesingle{}user\textquotesingle{} without waiting for it. \end{DoxyCompactList}\item 
int \textbf{ osmo\+\_\+system\+\_\+nowait} (const char $\ast$command, const char $\ast$$\ast$env\+\_\+whitelist, char $\ast$$\ast$addl\+\_\+env)
\begin{DoxyCompactList}\small\item\em call an external shell command without waiting for it. \end{DoxyCompactList}\end{DoxyCompactItemize}
\doxysubsection*{Variables}
\begin{DoxyCompactItemize}
\item 
const char $\ast$ \textbf{ osmo\+\_\+environment\+\_\+whitelist} [$\,$]
\begin{DoxyCompactList}\small\item\em suggested list of environment variables to pass (if they exist) to a sub-\/process/script \end{DoxyCompactList}\item 
char $\ast$$\ast$ \textbf{ environ}
\end{DoxyCompactItemize}


\doxysubsection{Macro Definition Documentation}
\mbox{\label{exec_8c_a369266c24eacffb87046522897a570d5}} 
\index{exec.c@{exec.c}!\_GNU\_SOURCE@{\_GNU\_SOURCE}}
\index{\_GNU\_SOURCE@{\_GNU\_SOURCE}!exec.c@{exec.c}}
\doxysubsubsection{\_GNU\_SOURCE}
{\footnotesize\ttfamily \#define \+\_\+\+GNU\+\_\+\+SOURCE}



\doxysubsection{Function Documentation}
\mbox{\label{exec_8c_a74007aea8c9beff8570913b483b856c6}} 
\index{exec.c@{exec.c}!osmo\_close\_all\_fds\_above@{osmo\_close\_all\_fds\_above}}
\index{osmo\_close\_all\_fds\_above@{osmo\_close\_all\_fds\_above}!exec.c@{exec.c}}
\doxysubsubsection{osmo\_close\_all\_fds\_above()}
{\footnotesize\ttfamily int osmo\+\_\+close\+\_\+all\+\_\+fds\+\_\+above (\begin{DoxyParamCaption}\item[{int}]{last\+\_\+fd\+\_\+to\+\_\+keep }\end{DoxyParamCaption})}



References \textbf{ DLGLOBAL}, \textbf{ LOGL\+\_\+\+ERROR}, and \textbf{ LOGP}.



Referenced by \textbf{ osmo\+\_\+system\+\_\+nowait2()}.

\mbox{\label{exec_8c_a71687348f645b14678c4c7f5d0a6e805}} 
\index{exec.c@{exec.c}!osmo\_environment\_append@{osmo\_environment\_append}}
\index{osmo\_environment\_append@{osmo\_environment\_append}!exec.c@{exec.c}}
\doxysubsubsection{osmo\_environment\_append()}
{\footnotesize\ttfamily int osmo\+\_\+environment\+\_\+append (\begin{DoxyParamCaption}\item[{char $\ast$$\ast$}]{out,  }\item[{size\+\_\+t}]{out\+\_\+len,  }\item[{char $\ast$$\ast$}]{in }\end{DoxyParamCaption})}



append one environment to another; only copying pointers, not actual strings. 

This function is useful if you\textquotesingle{}d like to append soem entries to an environment befoer passing it to exec$\ast$e() functions.

It will append all entries from \textquotesingle{}in\textquotesingle{} to the environment in \textquotesingle{}out\textquotesingle{}, as long as \textquotesingle{}out\textquotesingle{} has space (determined by \textquotesingle{}out\+\_\+len\textquotesingle{}).

Constraints\+: If the same key exists in \textquotesingle{}out\textquotesingle{} and \textquotesingle{}in\textquotesingle{}, duplicate keys are generated. It is a simple append, without any duplicate checks.


\begin{DoxyParams}[1]{Parameters}
\mbox{\texttt{ out}}  & {\em out} & caller-\/allocated array of pointers for the generated output \\
\hline
\mbox{\texttt{ in}}  & {\em out\+\_\+len} & size of out (number of pointers) \\
\hline
\mbox{\texttt{ in}}  & {\em in} & input environment (NULL-\/terminated list of pointers like $\ast$$\ast$environ) \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
number of entries filled in \textquotesingle{}out\textquotesingle{}; negative on error 
\end{DoxyReturn}


References \textbf{ OSMO\+\_\+\+ASSERT}.



Referenced by \textbf{ osmo\+\_\+system\+\_\+nowait2()}.

\mbox{\label{exec_8c_ab1efc7ed7bdb411bb019c6aefb2a0dcb}} 
\index{exec.c@{exec.c}!osmo\_environment\_filter@{osmo\_environment\_filter}}
\index{osmo\_environment\_filter@{osmo\_environment\_filter}!exec.c@{exec.c}}
\doxysubsubsection{osmo\_environment\_filter()}
{\footnotesize\ttfamily int osmo\+\_\+environment\+\_\+filter (\begin{DoxyParamCaption}\item[{char $\ast$$\ast$}]{out,  }\item[{size\+\_\+t}]{out\+\_\+len,  }\item[{char $\ast$$\ast$}]{in,  }\item[{const char $\ast$$\ast$}]{whitelist }\end{DoxyParamCaption})}



filtered a process environment by whitelist; only copying pointers, no actual strings. 

This function is useful if you\textquotesingle{}d like to generate an environment to pass exec$\ast$e() functions. It will create a new environment containing only those entries whose keys (as per environment convention KEY=VALUE) are contained in the whitelist. The function will not copy the actual strings, but just create a new pointer array, pointing to the same memory as the input strings.

Constraints\+: Keys up to a maximum length of 255 characters are supported.


\begin{DoxyParams}[1]{Parameters}
\mbox{\texttt{ out}}  & {\em out} & caller-\/allocated array of pointers for the generated output \\
\hline
\mbox{\texttt{ in}}  & {\em out\+\_\+len} & size of out (number of pointers) \\
\hline
\mbox{\texttt{ in}}  & {\em in} & input environment (NULL-\/terminated list of pointers like $\ast$$\ast$environ) \\
\hline
\mbox{\texttt{ in}}  & {\em whitelist} & whitelist of permitted keys in environment (like $\ast$$\ast$environ) \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
number of entries filled in \textquotesingle{}out\textquotesingle{}; negtive on error 
\end{DoxyReturn}


References \textbf{ ARRAY\+\_\+\+SIZE}, \textbf{ OSMO\+\_\+\+ASSERT}, and \textbf{ str\+\_\+in\+\_\+list()}.



Referenced by \textbf{ osmo\+\_\+system\+\_\+nowait2()}.

\mbox{\label{exec_8c_a680be9aef4deaf60a5a9d47677a6feca}} 
\index{exec.c@{exec.c}!osmo\_system\_nowait@{osmo\_system\_nowait}}
\index{osmo\_system\_nowait@{osmo\_system\_nowait}!exec.c@{exec.c}}
\doxysubsubsection{osmo\_system\_nowait()}
{\footnotesize\ttfamily int osmo\+\_\+system\+\_\+nowait (\begin{DoxyParamCaption}\item[{const char $\ast$}]{command,  }\item[{const char $\ast$$\ast$}]{env\+\_\+whitelist,  }\item[{char $\ast$$\ast$}]{addl\+\_\+env }\end{DoxyParamCaption})}



call an external shell command without waiting for it. 

This mimics the behavior of system(3), with the following differences\+:
\begin{DoxyItemize}
\item it doesn\textquotesingle{}t wait for completion of the child process
\item it closes all non-\/stdio file descriptors by iterating /proc/self/fd
\item it constructs a reduced environment where only whitelisted keys survive
\item it (optionally) appends additional variables to the environment
\end{DoxyItemize}


\begin{DoxyParams}[1]{Parameters}
\mbox{\texttt{ in}}  & {\em command} & the shell command to be executed, see system(3) \\
\hline
\mbox{\texttt{ in}}  & {\em env\+\_\+whitelist} & A white-\/list of keys for environment variables \\
\hline
\mbox{\texttt{ in}}  & {\em addl\+\_\+env} & any additional environment variables to be appended \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
PID of generated child process; negative on error 
\end{DoxyReturn}


References \textbf{ osmo\+\_\+system\+\_\+nowait2()}.

\mbox{\label{exec_8c_a75cce23ee8e0c96dcec47ff5d1465373}} 
\index{exec.c@{exec.c}!osmo\_system\_nowait2@{osmo\_system\_nowait2}}
\index{osmo\_system\_nowait2@{osmo\_system\_nowait2}!exec.c@{exec.c}}
\doxysubsubsection{osmo\_system\_nowait2()}
{\footnotesize\ttfamily int osmo\+\_\+system\+\_\+nowait2 (\begin{DoxyParamCaption}\item[{const char $\ast$}]{command,  }\item[{const char $\ast$$\ast$}]{env\+\_\+whitelist,  }\item[{char $\ast$$\ast$}]{addl\+\_\+env,  }\item[{const char $\ast$}]{user }\end{DoxyParamCaption})}



call an external shell command as \textquotesingle{}user\textquotesingle{} without waiting for it. 

This mimics the behavior of system(3), with the following differences\+:
\begin{DoxyItemize}
\item it doesn\textquotesingle{}t wait for completion of the child process
\item it closes all non-\/stdio file descriptors by iterating /proc/self/fd
\item it constructs a reduced environment where only whitelisted keys survive
\item it (optionally) appends additional variables to the environment
\item it (optionally) changes the user ID to that of \textquotesingle{}user\textquotesingle{} (requires execution as root)
\end{DoxyItemize}


\begin{DoxyParams}[1]{Parameters}
\mbox{\texttt{ in}}  & {\em command} & the shell command to be executed, see system(3) \\
\hline
\mbox{\texttt{ in}}  & {\em env\+\_\+whitelist} & A white-\/list of keys for environment variables \\
\hline
\mbox{\texttt{ in}}  & {\em addl\+\_\+env} & any additional environment variables to be appended \\
\hline
\mbox{\texttt{ in}}  & {\em user} & name of the user to which we should switch before executing the command \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
PID of generated child process; negative on error 
\end{DoxyReturn}


References \textbf{ ARRAY\+\_\+\+SIZE}, \textbf{ DLGLOBAL}, \textbf{ environ}, \textbf{ LOGL\+\_\+\+ERROR}, \textbf{ LOGP}, \textbf{ osmo\+\_\+close\+\_\+all\+\_\+fds\+\_\+above()}, \textbf{ osmo\+\_\+environment\+\_\+append()}, and \textbf{ osmo\+\_\+environment\+\_\+filter()}.



Referenced by \textbf{ osmo\+\_\+system\+\_\+nowait()}.

\mbox{\label{exec_8c_a0e612d16e78285a46edbd00191932ac9}} 
\index{exec.c@{exec.c}!str\_in\_list@{str\_in\_list}}
\index{str\_in\_list@{str\_in\_list}!exec.c@{exec.c}}
\doxysubsubsection{str\_in\_list()}
{\footnotesize\ttfamily static bool str\+\_\+in\+\_\+list (\begin{DoxyParamCaption}\item[{const char $\ast$$\ast$}]{list,  }\item[{const char $\ast$}]{key }\end{DoxyParamCaption})\hspace{0.3cm}{\ttfamily [static]}}



References \textbf{ list}.



Referenced by \textbf{ osmo\+\_\+environment\+\_\+filter()}.



\doxysubsection{Variable Documentation}
\mbox{\label{exec_8c_aa006daaf11f1e2e45a6ababaf463212b}} 
\index{exec.c@{exec.c}!environ@{environ}}
\index{environ@{environ}!exec.c@{exec.c}}
\doxysubsubsection{environ}
{\footnotesize\ttfamily char$\ast$$\ast$ environ\hspace{0.3cm}{\ttfamily [extern]}}



Referenced by \textbf{ osmo\+\_\+system\+\_\+nowait2()}.

\mbox{\label{exec_8c_ab522083bcb56160c2fc73abeac9ca6a3}} 
\index{exec.c@{exec.c}!osmo\_environment\_whitelist@{osmo\_environment\_whitelist}}
\index{osmo\_environment\_whitelist@{osmo\_environment\_whitelist}!exec.c@{exec.c}}
\doxysubsubsection{osmo\_environment\_whitelist}
{\footnotesize\ttfamily const char$\ast$ osmo\+\_\+environment\+\_\+whitelist[$\,$]}

{\bfseries Initial value\+:}
\begin{DoxyCode}{0}
\DoxyCodeLine{= \{}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}USER"{}}, \textcolor{stringliteral}{"{}LOGNAME"{}}, \textcolor{stringliteral}{"{}HOME"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}LANG"{}}, \textcolor{stringliteral}{"{}LC\_ALL"{}}, \textcolor{stringliteral}{"{}LC\_COLLATE"{}}, \textcolor{stringliteral}{"{}LC\_CTYPE"{}}, \textcolor{stringliteral}{"{}LC\_MESSAGES"{}}, \textcolor{stringliteral}{"{}LC\_MONETARY"{}}, \textcolor{stringliteral}{"{}LC\_NUMERIC"{}}, \textcolor{stringliteral}{"{}LC\_TIME"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}PATH"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}PWD"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}SHELL"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}TERM"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}TMPDIR"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}LD\_LIBRARY\_PATH"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}LD\_PRELOAD"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}POSIXLY\_CORRECT"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}HOSTALIASES"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}TZ"{}}, \textcolor{stringliteral}{"{}TZDIR"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}TERMCAP"{}},}
\DoxyCodeLine{        \textcolor{stringliteral}{"{}COLUMNS"{}}, \textcolor{stringliteral}{"{}LINES"{}},}
\DoxyCodeLine{        NULL}
\DoxyCodeLine{\}}

\end{DoxyCode}


suggested list of environment variables to pass (if they exist) to a sub-\/process/script 

