omprog: add ability to pass rsyslog's environment to script

Up until 8.37.0, rsyslog provides an empty environment to the spawned
program. This seems to work in existing use case. However, there are
use cases where rsyslog's environment should be inherited, at least
this is needed for the testbench. There, we need to have access to
the output file name, which is now dynamically be generated to support
parallel test execution. We assume environment access would also be
useful for other use cases as well.

see also https://github.com/rsyslog/rsyslog/issues/2921
This commit is contained in:
Rainer Gerhards 2018-08-13 08:15:21 +02:00
parent 2a355c779d
commit f13bbf22cc
No known key found for this signature in database
GPG Key ID: 0CB6B2A8BE80B499

View File

@ -6,7 +6,7 @@
*
* File begun on 2009-04-01 by RGerhards
*
* Copyright 2009-2017 Adiscon GmbH.
* Copyright 2009-2018 Adiscon GmbH.
*
* This file is part of rsyslog.
*
@ -50,6 +50,8 @@ MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
MODULE_CNFNAME("omprog")
extern char **environ; /* POSIX environment ptr, by std not in a header... (see man 7 environ) */
/* internal structures
*/
DEF_OMOD_STATIC_DATA
@ -66,6 +68,7 @@ typedef struct _instanceData {
uchar *szTemplateName; /* assigned output template */
int bConfirmMessages; /* does the program provide feedback via stdout? */
int bUseTransactions; /* send begin/end transaction marks to program? */
int bUseNULLEnvironment; /* use an empty environment (vs. rsyslog's)? */
uchar *szBeginTransactionMark; /* mark message for begin transaction */
uchar *szCommitTransactionMark; /* mark message for commit transaction */
int bForceSingleInst; /* only a single wrkr instance of program permitted? */
@ -96,6 +99,7 @@ static configSettings_t cs;
/* action (instance) parameters */
static struct cnfparamdescr actpdescr[] = {
{ "binary", eCmdHdlrString, CNFPARAM_REQUIRED },
{ "hideEnvironment", eCmdHdlrBinary, 0 },
{ "confirmMessages", eCmdHdlrBinary, 0 },
{ "useTransactions", eCmdHdlrBinary, 0 },
{ "beginTransactionMark", eCmdHdlrString, 0 },
@ -198,7 +202,8 @@ execBinary(wrkrInstanceData_t *pWrkrData, int fdStdin, int fdStdout, int fdStder
alarm(0);
/* finally exec child */
iRet = execve((char*)pWrkrData->pData->szBinary, pWrkrData->pData->aParams, newenviron);
iRet = execve((char*)pWrkrData->pData->szBinary, pWrkrData->pData->aParams,
(pWrkrData->pData->bUseNULLEnvironment) ? newenviron : environ);
if(iRet == -1) {
/* Note: this will go to stdout of the **child**, so rsyslog will never
* see it except when stdout is captured. If we use the plugin interface,
@ -789,6 +794,7 @@ setInstParamDefaults(instanceData *pData)
pData->iParams = 0;
pData->bConfirmMessages = 0;
pData->bUseTransactions = 0;
pData->bUseNULLEnvironment = 1;
pData->szBeginTransactionMark = NULL;
pData->szCommitTransactionMark = NULL;
pData->bForceSingleInst = 0;
@ -833,6 +839,8 @@ CODESTARTnewActInst
if(!strcmp(actpblk.descr[i].name, "binary")) {
CHKiRet(split_binary_parameters(&pData->szBinary, &pData->aParams, &pData->iParams,
pvals[i].val.d.estr));
} else if(!strcmp(actpblk.descr[i].name, "hideEnvironment")) {
pData->bUseNULLEnvironment = (int) pvals[i].val.d.n;
} else if(!strcmp(actpblk.descr[i].name, "confirmMessages")) {
pData->bConfirmMessages = (int) pvals[i].val.d.n;
} else if(!strcmp(actpblk.descr[i].name, "useTransactions")) {