Com: avoid intentional memory leak in epicsEnvSet
Switch default impl. to setenv/unsetenv Switch WIN32 to use _putenv_s On vxWorks putenv() is documented to make a copy. log error, but never halt, if env (un)set not possible. RTEMS <4.10 compat where unsetenv() returns void.
This commit is contained in:
@@ -1,72 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* SPDX-License-Identifier: EPICS
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* osdEnv.c */
|
||||
/*
|
||||
* Author: Eric Norum
|
||||
* Date: May 7, 2001
|
||||
*
|
||||
* Routines to modify/display environment variables and EPICS parameters
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* Starting in Mac OS X 10.5 (Leopard) shared libraries and
|
||||
* bundles don't have direct access to environ (man environ).
|
||||
*/
|
||||
#include <crt_externs.h>
|
||||
#define environ (*_NSGetEnviron())
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include "envDefs.h"
|
||||
#include "iocsh.h"
|
||||
|
||||
/*
|
||||
* Set the value of an environment variable
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
{
|
||||
if (!name) return;
|
||||
iocshEnvClear(name);
|
||||
setenv(name, value, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unset an environment variable
|
||||
*/
|
||||
|
||||
LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
||||
{
|
||||
iocshEnvClear(name);
|
||||
unsetenv(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show the value of the specified, or all, environment variables
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
||||
{
|
||||
if (name == NULL) {
|
||||
extern char **environ;
|
||||
char **sp;
|
||||
|
||||
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++)
|
||||
printf ("%s\n", *sp);
|
||||
}
|
||||
else {
|
||||
const char *cp = getenv (name);
|
||||
if (cp == NULL)
|
||||
printf ("%s is not an environment variable.\n", name);
|
||||
else
|
||||
printf ("%s=%s\n", name, cp);
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* SPDX-License-Identifier: EPICS
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* osdEnv.c */
|
||||
/*
|
||||
* Author: Eric Norum
|
||||
* Date: May 7, 2001
|
||||
*
|
||||
* Routines to modify/display environment variables and EPICS parameters
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include "envDefs.h"
|
||||
#include "osiUnistd.h"
|
||||
#include "iocsh.h"
|
||||
|
||||
/*
|
||||
* Set the value of an environment variable
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
{
|
||||
iocshEnvClear(name);
|
||||
setenv(name, value, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unset an environment variable
|
||||
*/
|
||||
|
||||
LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
||||
{
|
||||
iocshEnvClear(name);
|
||||
unsetenv(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show the value of the specified, or all, environment variables
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
||||
{
|
||||
if (name == NULL) {
|
||||
extern char **environ;
|
||||
char **sp;
|
||||
|
||||
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++)
|
||||
printf ("%s\n", *sp);
|
||||
}
|
||||
else {
|
||||
const char *cp = getenv (name);
|
||||
if (cp == NULL)
|
||||
printf ("%s is not an environment variable.\n", name);
|
||||
else
|
||||
printf ("%s=%s\n", name, cp);
|
||||
}
|
||||
}
|
||||
@@ -21,12 +21,19 @@
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include "errlog.h"
|
||||
#include "cantProceed.h"
|
||||
#include "envDefs.h"
|
||||
#include "osiUnistd.h"
|
||||
#include "epicsFindSymbol.h"
|
||||
#include "iocsh.h"
|
||||
|
||||
static
|
||||
void setEnv(const char *name, const char *value)
|
||||
{
|
||||
errno_t err = _putenv_s(name, value);
|
||||
if(err)
|
||||
errlogPrintf("Can't set environment %s=\"%s\" : %d\n", name, value, (int)err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the value of an environment variable
|
||||
* Leaks memory, but the assumption is that this routine won't be
|
||||
@@ -34,25 +41,8 @@
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
iocshEnvClear(name);
|
||||
|
||||
cp = mallocMustSucceed (strlen (name) + strlen (value) + 2, "epicsEnvSet");
|
||||
strcpy (cp, name);
|
||||
strcat (cp, "=");
|
||||
strcat (cp, value);
|
||||
if (putenv (cp) < 0) {
|
||||
errPrintf(
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Failed to set environment parameter \"%s\" to \"%s\": %s\n",
|
||||
name,
|
||||
value,
|
||||
strerror (errno));
|
||||
free (cp);
|
||||
}
|
||||
setEnv(name, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -63,8 +53,7 @@ LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
||||
{
|
||||
iocshEnvClear(name);
|
||||
if (getenv(name) != NULL)
|
||||
epicsEnvSet((char*)name, "");
|
||||
setEnv(name, "");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -20,13 +20,25 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include "epicsVersion.h"
|
||||
#include "errlog.h"
|
||||
#include "cantProceed.h"
|
||||
#include "envDefs.h"
|
||||
#include "osiUnistd.h"
|
||||
#include "epicsFindSymbol.h"
|
||||
#include "iocsh.h"
|
||||
|
||||
#ifdef __rtems__
|
||||
# include <rtems.h>
|
||||
# define RTEMS_VERSION_INT VERSION_INT(__RTEMS_MAJOR__, __RTEMS_MINOR__, 0, 0)
|
||||
#endif
|
||||
|
||||
#if defined(__RTEMS_MAJOR__) && RTEMS_VERSION_INT<VERSION_INT(4,10,0,0)
|
||||
/* newlib w/ RTEMS <=4.9 returns void */
|
||||
# define unSetEnv(name) ({unsetenv(name); 0;})
|
||||
#else
|
||||
# define unSetEnv(name) unsetenv(name)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the value of an environment variable
|
||||
* Leaks memory, but the assumption is that this routine won't be
|
||||
@@ -34,26 +46,9 @@
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (!name) return;
|
||||
iocshEnvClear(name);
|
||||
|
||||
cp = mallocMustSucceed (strlen (name) + strlen (value) + 2, "epicsEnvSet");
|
||||
strcpy (cp, name);
|
||||
strcat (cp, "=");
|
||||
strcat (cp, value);
|
||||
if (putenv (cp) < 0) {
|
||||
errPrintf(
|
||||
-1L,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Failed to set environment parameter \"%s\" to \"%s\": %s\n",
|
||||
name,
|
||||
value,
|
||||
strerror (errno));
|
||||
free (cp);
|
||||
}
|
||||
if(setenv(name, value, 1))
|
||||
errlogPrintf("setenv(\"%s\", \"%s\") -> %d\n", name, value, errno);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -64,8 +59,8 @@ LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
||||
{
|
||||
iocshEnvClear(name);
|
||||
if (getenv(name) != NULL)
|
||||
putenv((char*)name);
|
||||
if(unSetEnv(name))
|
||||
errlogPrintf("unsetenv(\"%s\") -> %d\n", name, errno);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* SPDX-License-Identifier: EPICS
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* osdEnv.c */
|
||||
/*
|
||||
* Author: Eric Norum
|
||||
* Date: May 7, 2001
|
||||
*
|
||||
* Routines to modify/display environment variables and EPICS parameters
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include <errlog.h>
|
||||
#include <cantProceed.h>
|
||||
#include <envDefs.h>
|
||||
#include <osiUnistd.h>
|
||||
#include "epicsFindSymbol.h"
|
||||
#include <iocsh.h>
|
||||
|
||||
/*
|
||||
* Set the value of an environment variable
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
{
|
||||
if (!name) return;
|
||||
iocshEnvClear(name);
|
||||
setenv(name, value, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unset an environment variable
|
||||
*/
|
||||
|
||||
LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
||||
{
|
||||
iocshEnvClear(name);
|
||||
unsetenv(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show the value of the specified, or all, environment variables
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
||||
{
|
||||
if (name == NULL) {
|
||||
extern char **environ;
|
||||
char **sp;
|
||||
|
||||
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++)
|
||||
printf ("%s\n", *sp);
|
||||
}
|
||||
else {
|
||||
const char *cp = getenv (name);
|
||||
if (cp == NULL)
|
||||
printf ("%s is not an environment variable.\n", name);
|
||||
else
|
||||
printf ("%s=%s\n", name, cp);
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* SPDX-License-Identifier: EPICS
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* osdEnv.c */
|
||||
/*
|
||||
* Author: Eric Norum
|
||||
* Date: May 7, 2001
|
||||
*
|
||||
* Routines to modify/display environment variables and EPICS parameters
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include "envDefs.h"
|
||||
#include "osiUnistd.h"
|
||||
#include "iocsh.h"
|
||||
|
||||
/*
|
||||
* Set the value of an environment variable
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
{
|
||||
iocshEnvClear(name);
|
||||
setenv(name, value, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unset an environment variable
|
||||
*/
|
||||
|
||||
LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
|
||||
{
|
||||
iocshEnvClear(name);
|
||||
unsetenv(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show the value of the specified, or all, environment variables
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
|
||||
{
|
||||
if (name == NULL) {
|
||||
extern char **environ;
|
||||
char **sp;
|
||||
|
||||
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++)
|
||||
printf ("%s\n", *sp);
|
||||
}
|
||||
else {
|
||||
const char *cp = getenv (name);
|
||||
if (cp == NULL)
|
||||
printf ("%s is not an environment variable.\n", name);
|
||||
else
|
||||
printf ("%s=%s\n", name, cp);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <ctype.h>
|
||||
#include <envLib.h>
|
||||
|
||||
#include "cantProceed.h"
|
||||
#include "epicsFindSymbol.h"
|
||||
#include "epicsStdio.h"
|
||||
#include "errlog.h"
|
||||
@@ -35,25 +34,32 @@
|
||||
*/
|
||||
LIBCOM_API void epicsStdCall epicsEnvSet (const char *name, const char *value)
|
||||
{
|
||||
char *cp;
|
||||
size_t alen = (!name || !value) ? 2u : strlen(name) + strlen(value) + 2u; /* <NAME> '=' <VALUE> '\0' */
|
||||
const int onstack = alen <= 512u; /* use on-stack dynamic array for small strings */
|
||||
char stackarr[ onstack ? alen : 1u]; /* gcc specific dynamic array */
|
||||
char *allocd = onstack ? NULL : malloc(alen);
|
||||
char *cp = onstack ? stackarr : allocd;
|
||||
|
||||
if (!name) {
|
||||
if (!name || !value) {
|
||||
printf ("Usage: epicsEnvSet \"name\", \"value\"\n");
|
||||
return;
|
||||
}
|
||||
|
||||
iocshEnvClear(name);
|
||||
} else if(!cp) {
|
||||
errlogPrintf("epicsEnvSet(\"%s\", \"%s\" insufficient memory\n", name, value);
|
||||
|
||||
cp = mallocMustSucceed (strlen (name) + strlen (value) + 2, "epicsEnvSet");
|
||||
strcpy (cp, name);
|
||||
strcat (cp, "=");
|
||||
strcat (cp, value);
|
||||
if (putenv (cp) < 0) {
|
||||
errPrintf(-1L, __FILE__, __LINE__,
|
||||
"Failed to set environment parameter \"%s\" to \"%s\": %s\n",
|
||||
name, value, strerror (errno));
|
||||
free (cp);
|
||||
} else {
|
||||
int err;
|
||||
|
||||
strcpy (cp, name);
|
||||
strcat (cp, "=");
|
||||
strcat (cp, value);
|
||||
|
||||
iocshEnvClear(name);
|
||||
|
||||
if((err=putenv(cp)) < 0)
|
||||
errlogPrintf("epicsEnvSet(\"%s\", \"%s\" -> %d\n", name, value, err);
|
||||
}
|
||||
/* from at least vxWorks 5.5 putenv() is making a copy, so we can free */
|
||||
free (allocd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user