How to get environment variable from FastCGI C++ binary during startup - c++

I have a FastCGI application that loads and processes a lot of data during its startup. And I want it to get some environment variable to determine its input data path, but as much as I understand so far, environment pointer envp comes with the request.
I want to do getenv before the very first request, say directly after FCGX_Init(). Is it possible?

Yeah, as it turnes out, the lighttpd's counterpart to -initial-env is "bin-environment" array in the fastcgi.server section of lighttpd.conf. The values defined there are accessible for getenv() from the very beginning of execution.

Related

How to return a command from a c++ application to parent terminal?

Is it possible to run a c++ application from a terminal and on certain conditions return a command back into the terminal from which it was called from? For instance, if I were to run an application within my terminal and after my selections; my application needs to change my PATH by running an export command such as:
(USING BASH)
export PATH=.:/home/User/application/bin:$PATH
After I'm done and before my application completely closes can I make the application change my terminals local environment variables with the above command? Does Qt offer a way of doing this? Thanks in advance for any help!
No, you cannot change parent application environment.
Why? When your parent app started yours (probably using system()), it actually fork()ed - child process was born as to be almost exact replica of parent, and then that child used execve() call, which completely replaced executable image of that process with executable image of your application (for scripts it would be image of interpreter like bash).
In addition to that, that process also prepared few more things. One is list of open files, starting with file handles 0,1,2 (stdin, stdout, stderr). Also, it created memory block (which belongs to child process address space) which contains environment variables (as key=value pairs).
Because environment block belongs to your process, you can change your own environment as you please. But, it is impossible for your process to change environment memory block of parent (or any other process for that matter). The only way to possibly achieve this would be to use IPC (inter-process communication) and gently ask parent to do this task inside of it, but parent must be actively listening (on local or network socket) and be willing to fulfill such request from somebody, and child is not any special compared to any other process in that regard.
This also reason why you can change environment in bash using some shell script, but ONLY using source or . bash macro - because it is processed by bash itself, without starting any external process.
However, you cannot change environment by executing any other program or script for reasons stated above.
The common solution is to have your application print the result to standard output, then have the invoker pass it to its environment. A textbook example is ssh-agent which prints an environment variable assigment; you usually invoke it with eval $(ssh-agent)

Difference: Environment Variables & Registry Keys

What is the difference between a Registry Key & an Environment Variable?
I think Environment Variables are only something found in windows OS? And I hear thats its very easy to change these so its not good to trust them? Are Registry Keys just as easy to change?
Are Registry keys stored in the kernal?
My most important question is: I know that the environment variables let me know the path to %APPDATA, the current users name, the path to program files, the version of Windows OS running, etc. BUT do the Registry keys also contain this kind of data - can I also find out this information by looking at the registry keys?
Both are used to configure programs. The biggest difference is that environment variables are stored in memory, registry keys are stored in a file. Which explains many of their properties:
Environment variable values are lost as soon as the process that writes them terminates.
A process cannot update the environment variable values of another process. With one important exception: the environment for a process is created by the process that starts it. The lpEnvironment argument of CreateProcess(). This is how a parent process configures the child processes it starts.
The space for storing environment variables is severely limited, 64KB max.
Environment variables do not have user scope like registry keys do, they'll have the same value for any user, unless the parent process takes care of it explicitly.
Environment variable values cannot be secured.
Accessing environment variables is fast. With the caveat that searching for a variable is an O(n) operation since they don't have a hierarchical organization nor an index. The limited environment size makes that unnecessary. Windows heavily optimizes registry key access however.
Another important difference:
Environment variables are loaded to the process when it starts. So if you change them after the process is running, the process won't see that.
And about your other question:
User Variables: HKEY_CURRENT_USER\Environment
System Variables: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
An article about the default system variables:
http://vlaurie.com/computers2/Articles/environment.htm
What is the difference between a Registry Key & an Environment
Variable?
Registry Keys are stored permanently in special file. Environment Variables are stored in memory of the process, but some of them (System Environment Variables) are loaded from registry on process start.

C++, Visual-Studio: Is it possible to create an executable that would set up enviroment variables and than execute?

For my programm to run I need system variable defited. I vant to be capable to set it and restart my app immidiatly or, if it is set do nothing. how to create such app with visual studio C++?
Use a wrapper application that sets the environment variable, then launches the main app.
Does SetEnvironmentVariable work?
First of all, it's not clear why the "restart" is necessary. The application can decide what to do based on whether environment variable is set or not, and it can also set it (SetEnvironmentVariable). Of course, you can always create a new process (CreateProcess) with your application name and end the current process, but something smells wrong with this design.

Accessing environment variable in a fastcgi application

I have writen a fastcGI application using C and C++
I have a free function that returns a string, if a specific environment variable has not been set. The function looks like this:
namespace
{
std::string getNameString()
{
char * datastr_ = getenv(MY_ENVAR.c_str());
if (datastr_)
return std::string(datastr_);
return DEFAULT_NAME;
}
};
I then carry out the following steps (in the order given below)
I have edited my /etc/environment and added the appropriate environment variable
I confirm that the variable has been set by typing printenv on the console
I stop and then start the apache daemon
When I debug my application, I find that the environment variable has not been set. I suspect that the environment under which the fastcgi application is running may different from the environment 'normal' applications run under.
Does anyone know how to retrieve environment variable in a fastcgi app?
I suspect that fastcgi processes are spawned in a "cleaned" environment by default, given your observations. Apache certainly provides a way of setting environment variables for fastcgi. This has the added bonus of being slightly less cryptic too (who expects a webservice to behave differently when /etc/environment is changed?), like this you keep "web config things" with "web config things".
You could look here http://httpd.apache.org/docs/current/env.html and try to set the env variable in the apache process. I have assumed latest apache version.

How can I change Windows shell (cmd.exe) environment variables from C++?

I would like to write a program that sets an environment variable in an instance of the shell (cmd.exe) it was called from. The idea is that I could store some state in this variable and then use it again on a subsequent call.
I know there are commands like SetEnvironmentVariable, but my understanding is that those only change the variable for the current process and won't modify the calling shell's variables.
Specifically what I would like to be able to do is create a command that can bounce between two directories. Pushd/Popd can go to a directory and back, but don't have a way of returning a 2nd time to the originally pushed directory.
MSDN states the following:
Calling SetEnvironmentVariable has no
effect on the system environment
variables. To programmatically add or
modify system environment variables,
add them to the
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session
Manager\Environment registry key, then
broadcast a WM_SETTINGCHANGE message
with lParam set to the string
"Environment". This allows
applications, such as the shell, to
pick up your updates. Note that the
values of the environment variables
listed in this key are limited to 1024
characters.
Considering that there are two levels of environment - System and Process - changing those in the shell would constitute changing the environment of another process. I don't believe that this is possible.
A common techniques is the write an env file, that is then "call"ed from the script.
del env.var
foo.exe ## writes to env.var
call env.var
In Windows when one process creates another, it can simply let the child inherit the current environment strings, or it can give the new child process a modified, or even completely new environment.
See the full info for the CreateProccess() win32 API
There is no supported way for a child process to reach back to the parent process and change the parent's environment.
That being said, with CMD scripts and PowerShell, the parent command shell can take output from the child process and update its own environment. This is a common technique.
personly, I don't like any kind of complex CMD scripts - they are a bitch to write an debug. You may want to do this in PowerShell - there is a learning curve to be sure, but it is much richer.
There is a way...
Just inject your code into parent process and call SetEnvironmentVariableA inside
cmd's process memory. After injecting just free the allocated memory.