Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

putenv() / getenv() problems 1

Status
Not open for further replies.

mbaranski

Programmer
Nov 3, 2000
421
US
I'm trying to read in a config file, and set the vars as env vars:

/etc/carma.conf :
informix_server=ol_p140
informix_dbname=proteus
informix_username=informix
informix_password=informix
mysql_dbname=proteus
/etc/carma.conf (END)

and the source snippet:
ifstream configFile;
char line[ 512 ];

configFile.open( "/etc/carma.conf", ios::nocreate );
if( !configFile )
{
cerr << &quot;The Config file (/etc/carma.conf) is missing or not viewable!!\n&quot;;
}
while ( configFile.getline( line , 512 , '\n' ) )
{

if( putenv( line ) == -1 )
{
cerr << &quot;Problem with putenv(line)\n&quot;;
}

}
cout << &quot;CREATE DATABASE IF NOT EXISTS &quot; << getenv(&quot;mysql_dbname&quot;) << &quot;;\n&quot;;
cout << &quot;USE &quot; << getenv(&quot;mysql_dbname&quot;) << &quot;;\n&quot;;

Now, every getenv call returns (null) and won't work. Any idea why?! This is frustrating

MWB. As always, I hope that helped!

Disclaimer:
Beware: Studies have shown that research causes cancer in lab rats.
 
This is a snippet from my man page of putenv()

SYNOPSIS
#include <stdlib.h>

int putenv(const char *string);

...

putenv() makes the value of the environment variable name
equal to value by altering an existing variable or creating
a new one. In either case, the string pointed to by string
becomes part of the environment, so altering the string will
change the environment.

...

What this seems to say is that you can't alter the memory that the argument to putenv() points to after you call the function. So every time you call getline() line is changed which also affects the previously set environment variable. This surprises me a bit actually, as it seems like your code *should* work.

You could do something like this I guess:

char *tmp;

while ( configFile.getline( line , 512 , '\n' ) )
{
tmp=(char *)malloc(line.length+1);
strcpy(tmp,line.c_str());
if( putenv( tmp ) == -1 )
{
cerr << &quot;Problem with putenv(line)\n&quot;;
}

}

Since tmp is pointing to new memory on each iteration, you're not stomping all over the previous environment variable.

Anybody else? Do I have this wrong? This seems weird that you should have to do this.

BTW, sorry for my horrendous C'ish C++ :)

Russ
bobbitts@hotmail.com
 
No problem, that makes sense, but it's not good. I ended up using an STL multimap anyway, which seems to work OK. It's basically just a hash data structure that I can store keys and values in

I looked at the man page too, before I posted, but I didn't catch what you said. I have one question about that, though. Wouldn't all of hte environment variables that I set using line have the value of the last one put into it? Doesen't getenv() just get the pointer to the memory location? If so, why do I get null when I request a variable? As always, I hope that helped!

Disclaimer:
Beware: Studies have shown that research causes cancer in lab rats.
 
Perhaps what's happening is that when getline() hits EOF it sets the first element of line to '\0' (an empty string), thus setting the string where all of your environment variables point to to unacceptable values. getenv() returns NULL because it expects to see a 'name=value' pair.

I'm not certain that this is getline()'s behavior (no C++ reference in the immediate vicinity at the time) however.

Russ
bobbitts@hotmail.com
 
yeah, makes sense. I should have used a hash to start with, but it took a little trial and error... As always, I hope that helped!

Disclaimer:
Beware: Studies have shown that research causes cancer in lab rats.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top