I know this is a bit off topic for what is suppose to be posted on stack overflow but wanted to know if these examples are well done.
setenv:
includes: #include <stdlib.h>
declaration: int setenv(const char *v_name, const char *v_value, int overwrite);
returns: If successful returns zero, otherwise returns -1, with errno set to indicate the cause of the error.
getenv:
includes: #include <stdlib.h>
declaration: char *getenv(const char *name)
returns: If successful returns a pointer to the value in the environment, or NULL if there is no match.
Examples
char *ppath
is used as a variable in the following examples.
Example 1: This example shows what happens when the overwrite
parameter is a non-zero and v_name
has a value.
ppath = getenv("PWD"); //puts the environment of $PWD into ppath
if(ppath == NULL) //error checking
perror("getenv");
cout << "$PWD = " << ppath << endl; //prints the environment of $PWD
Output of this code is $PWD = /class/classes/username/CS100
this is because the char variable ppath
is getting the
environment from getenv("PWD")
and the environment of $PWD
is /class/classes/username/CS100
. Therefore ppath
points to that
environment. There is also proper error checking to make sure that $PWD
has a environment and if it does not perror
is called.
ppath = getenv("HOME"); //gets the environment of the $HOME
if(ppath == NULL) //error checking
perror("getenv");
cout << "$HOME = " << ppath << endl; //prints the environment of $PWD
Output of this code is $HOME = /class/classes/username
this is because the char variable ppath
is getting the
environment from getenv("HOME")
and the environment of $HOME
is /class/classes/username
. Therefore ppath
points to that
environment. There is also proper error checking to make sure that $HOME
has a environment and if it does not perror
is called.
if(-1==setenv("PWD",ppath,1)) //since the overwrite parameter is non-zero it replaces environment
perror("setenv"); //of $PWD with the value of ppath which is defined by the environment
//of $HOME
This is to change the environment of $PWD
in this case it take the value that the ppath
is pointing to which in this case is /class/classes/username
which is also $HOME
. The overwrite
parameter is non-zero, so it replaces the environment of $PWD
to ppath
ppath = getenv("PWD"); //gets the environment of $PWD
if(ppath == NULL) //error checking
perror("getenv");
cout << "$PWD = " << ppath << endl; //the value should now be the same as the value of $HOME
Output of this code is $PWD = /class/classes/username
this is because the char variable ppath
is getting the
environment from getenv("PWD")
and the environment of $PWD
is /class/classes/username
. Therefore ppath
points to that
environment. There is also proper error checking to make sure that $PWD
has a environment and if it does not perror
is called. The full output of example 1 is as follows.
Output 1:
$PWD = /class/classes/username/CS100
$HOME = /class/classes/username
$PWD = /class/classes/username
Example 2: This example shows what happens when the overwrite
parameter is a non-zero and v_name
has a blank value as in v_name = ""
so an empty string.
ppath = getenv("PWD");
if(ppath == NULL)
perror("getenv");
cout << "$PWD = " << ppath << endl; //in this case ppath ="" because the environment of $PWD is not set
Output of the following code will be $PWD =
this is because the environment of $PWD
is set to ""
in this case, it makes the ppath
point to an empty string. Hence the reason it does not throw an error, however if $PWD
was an undefined variable then perror
is called.
ppath = getenv("HOME");
if(ppath == NULL)
perror("getenv");
cout << "$HOME = " << ppath << endl;
Output: of this code is $HOME = /class/classes/username
this is because the char variable ppath
is getting the
environment from getenv("HOME")
and the environment of $HOME
is /class/classes/username
. Therefore ppath
points to that
environment. There is also proper error checking to make sure that $HOME
has an environment and if it does not perror
is called.
if(-1==setenv("PWD",ppath,1)) //since the overwrite parameter is non-zero it replaces environment
perror("setenv"); //of $PWD with the value of ppath which is defined by the environment
//of $HOME
Since the overwrite
parameter is 1 it does not matter what the $PWD
it is set to ppath
as defined in the earlier example.
ppath = getenv("PWD");
if(ppath == NULL)
perror("getenv");
cout << "$PWD = " << ppath << endl; //the value should now be the same as the value of $HOME
The output of the following code is $PWD = /class/classes/username
this is because setenv
changed the value of $PWD
as defined in the past code block, to ppath
.
Output 2:
$PWD =
$HOME = /class/classes/username
$PWD = /class/classes/username
Example 3: This example shows what happens when the overwrite
parameter is a zero and v_name does have a value.
ppath = getenv("PWD");
if(ppath == NULL)
perror("getenv");
cout << "$PWD = " << ppath << endl;
In this case ppath
is set to the environment of $PWD
. The output of this code block is
$PWD = /class/classes/username/CS100
.
ppath = getenv("HOME");
if(ppath == NULL)
perror("getenv");
cout << "$HOME = " << ppath << endl;
In this code block ppath
is set to the environment of $HOME
. The output of the following code block will be
$HOME = /class/classes/username
.
if(-1==setenv("PWD",ppath,0)) //since the overwrite parameter is zero it does not replaces
perror("setenv"); //environment of $PWD with ppath.
Here there is a new case where the overwrite
parameter is zero. In this case it does not matter what ppath
is because the
zero flag makes it so that the $PWD
is not replaced by the ppath
, unless $PWD
was a undefined variable, in which case
$PWD
would be given the value of ppath
.
ppath = getenv("PWD");
if(ppath == NULL)
perror("getenv");
cout << "$PWD = " << ppath << endl; //the value should not be changed.
The output of this code block is $PWD = /class/classes/username/CS100
. This is because setenv
did not change the
environment of $PWD
because of the overwrite
parameter.
Output 3:
$PWD = /class/classes/username/CS100
$HOME = /class/classes/username
$PWD = /class/classes/username/CS100
Example 4: This example shows what happens when the overwrite
parameter is a zero or a non-zero and v_name
is a parameter that is not defined in the environment.
ppath = getenv("HOME");
if(ppath == NULL)
perror("getenv");
cout << "$HOME = " << ppath << endl;
In this case ppath is given the environment of $HOME
, there is also proper error checking done. The output of the code
block is $HOME = /class/classes/username
.
if(-1==setenv("random_name",ppath,0)) //since the overwrite parameter is zero and the variable
perror("setenv"); //$random_name is undefined, setenv makes the environment of
//$random_variable is the value of ppath. If the case where
//there is a undefined variable the setenv behaves the
//same way regardless of a non-zero or zero overwrites parameter.
In this case the overwrite
parameter is still zero, but the v_name
is not declared so this is where the overwrite
parameter of zero is helpful. In this case random_name
is set to ppath
which is pointing to the environment of $HOME
which is /class/classes/username
.
ppath = getenv("random_name"); //gets the value of $PWD
if(ppath == NULL)
perror("getenv");
cout << "$random_name = " << ppath << endl; //the value should now be the same as the value of $HOME
The ppath
is contains the environment of $random_name
which is set by the setenv
in the previous code block. The output
of this code block is $random_name = /class/classes/username
Output 4:
$HOME = /class/classes/username
$random_name = /class/classes/username
You are using C++; you can declare variables easily as you write. Indeed, both C99 and C11 also allow you to declare variables when they're used.
Example 1
Actually, it is very hard to spot the code in Example 1 that has anything to do with the
overwrite
parameter.You shouldn't use
ppath
when you've established that it is NULL; this is a pervasive problem. And these days, shouldn't you usenullptr
since this is C++? I think this could be:If you state that you're coding for backwards compatibility, I've no major problem with using NULL or
0
instead ofnullptr
.In fact, you have the almost identical block of code three times; you need to write a function:
This is a direct transliteration of the original code. It also shows why
perror()
is a bad function; it is hard to make the error message meaningful (it won't include the variable name). Add to that the fact that the POSIX specification forgetenv()
does not specify thaterrno
is set bygetenv()
, and we should revise the code to:You can then call:
Etc. I'm not convinced that the code referencing
$HOME
is relevant; you really don't use it.Personally, I dislike (intensely) the back-to-front comparison style you use in the code for
setenv()
. When Yoda I want like to speak…Note that setting the environment variable
$PWD
alone does not change the current working directory.Example 2
Your example 2 does not clearly show the
v_name
set to an empty string. However, that is a case covered by the POSIX specification forsetenv()
. This time, an error is defined (errno
will be set toEINVAL
).There is so much repeated code, again, it is hard to spot what's interesting.
Example 3
You say:
I think you mean:
This is probably applicable previously, too.
Example 4
You say:
The comment doesn't match the code.
Style on SO
You should make a heading for each example with
###
as the line prefix. You might or might not have a super-heading## Examples
. You might mimic the style of a manual page for the function outline, or you might simply omit everything except the synopsis, referring to where the function behaviour is defined.As written, it is extremely hard to find the 4 examples (it was only late in the process of answering that I realized there were four examples rather than three). You have a lot of repetition. You also have a good deal of noise (the code referencing
$HOME
is basically noise.