GetCommandLine linux *true* equivalent - c++

Similar question to Linux equivalent of GetCommandLine and CommandLineToArgv
Is it possible to get the raw command line in linux? The file /proc/self/cmdline is destroyd.
./a.out files="file 1","file 2" param="2"
prints
./a.outfiles=file 1,file 2param=2
which is junk
Escaping command line does work for all arguments but the first.
./a.out files=\"fil 1\",\"fil 2\"\ param=\"2\"
prints
./a.outfiles="fil1","fil2" param="2"

You can't do that. The command line arguments are actually passed to the new process as individual strings. See the linux kernel source:
kernel_execve
Note that kernel_execve(...) takes a const char *argv[] - so there is no such thing as a long string commandline in Linux - it's the layer above that needs to split the arguments into separate components.
Edit: actually, the system call is here:
excve system call
But the statement above still applies. The parameter for argv is already split by the time the kernel gets it from the C-library call to exec.
It is the responsibility of the "starter of the program" (typically a shell, but doesn't have to be) to produce the argv[] array. It will do the "globbing" (expansion of wildcard filenames to the actual files that it matches) and stripping of quotations, variable replacement and so on.
I would also point out that although there are several variants of "exec" in the C library, there is only one way into the kernel. All variants end up in the execve system call that I linked to above. The other variants are simply because the caller may not fancy splitting arguments into invdividual elements, so the C library "helps out" by doing that for the programmer. Similarly for passing an environment array to the new program - if the programmer don't need specific environment, he/she can just call the variant that automatically take the parent process env.

Related

Dealing with special characters in CLI11

I have code like the following
flags->add_option("--name", name_, "The name.")->required();
I want to be able to pass strings like "aa$p$aa" to the --name parameter. However, this does not seem to work with CLI11, and the name gets truncated to just "aa". I need to escape the $ characters to properly read the strings. So aa\$p\$aa works fine, and I get the expected string ("aa$p$aa").
Changing the function to add_flag() does not work either.
Is there a way to be able to pass arbitrary strings to a parameter as with either function calls above?
Your operating system takes the command you type in and executes the given program, passing the parameters to it.
The interpolation, and the handling of $ characters in typed-in commands is handled by your operating system as part of executing the typed-in command. Your compiled C++ program receives the transformed arguments, as parameters. Your C++ program has no means to control what has happened before it was even executed.

How much memory is allocated for argv[]? [duplicate]

This question already has answers here:
where command line arguments are stored?
(4 answers)
Closed 6 years ago.
I know that the command line arguments are character arrays and that they are stored on the stack. But, I want to know actual memory allocation for of each argument. e.g. suppose I passed the directory name "/tmp" as a command line argument. This will be stored in argv[1]. But as I tested, it is allowed to change argv[1] to "/tmp/log/" (size increased) in the program. How is this possible ?
To answer your question, the total maximum size available to argument strings and the passed environment can be obtained with:
getconf ARG_MAX
from the command line or the syconf equivalent from C (see http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html for more information).
(On my Linux box, the limit is 2097152).
Your example happens to work because the arguments and the environment are realistically stored contiguously, so appending to a string will overwrite what comes after it (following arguments, or the environment).
And that's why it's a bad idea to try and expand the argv strings like that. If you want to modify them, either edit them or shrink them, but trying to expand them is a call for trouble.
On Linux, parameters are populated by create_elf_tables. For this specific platform at least, you are correct that the values are stored on the stack.
Linux only uses exactly as much memory as is necessary to store arguments and (initial) environment variables on the stack; if you try to use more than what is already there, you're overwriting something else (or crashing).
The standard states that the argv can be modified since it is a special internal.
177 — The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination, so it is allocated only what you need at the assignment or replacement.
Standard text:
http://c0x.coding-guidelines.com/5.1.2.2.1.html

Fortran and gnuplot: parameter passing and returning a value

I would like to call a gnuplot script from a program in Fortran. The program is supposed to perform a linear fit, to obtain the linear parameters and to send them back to the main program. I know that gnuplot can be called from Fortran using the command
call system ('gnuplot script.gnu')
what I don't know is how to send parameters to gnuplot in this call (let's say a real variable called t) and to return back to the main program the values of the fitted parameters (two real values a and b).
Note: I would like to avoid the use of files to communicate between the programs: I don't want gnuplot to write a file that it is then read by the Fortran program.
My script for the linear fitting:
f(x)=a*x+b
fit [t:*] f(x) "data.txt" u 1:2 via a,b;
You can use the -e command line argument of gnuplot
call system (`gnuplot -e "t=1" script.gnu')
to pass a parameter to gnuplot. I am not aware of any way to return a value though.
(To make it really useful you will have to get the numbers into the string, see
Convert integers to strings to create output filenames at run time and many related question in the "Linked" tab about how you can do that.)
It should be very easy to do your linear fit in Fortran, the formula is very simple and there are also libraries available, and avoid all these complications.

What does the dash mean in windows command line syntax?

I know basic c++ coding and command line syntax. Often, the main() function looks like this:
int main(int argc, char *argc[])
When I execute my program via command line, I just do this:
cd c:\path\to\foo 1
Where 1 is the argument. And of course, arc would be equal to '2' and the '1' would be at element '1' of the array argc (as opposed to 0).
I've seen the dash used in a lot of places. Specifically:
gcc -v
And if I type just 'gcc', it says there are no arguments. And if I type 'gcc v' I get "error: no such file or directory". But when I take a look at the minGW bin folder where gcc is, there is no folder 'v'.
This is just a style of setting options in programs. It comes from the getopt library provided in Unix/Linux etc. The -- form that kc7zax mentions in their answer is the long-form of these options (allowing a long identifier instead of a single character).
There's nothing magic about these. They are simply parsed out of the argv array. You can implement similar or identical functionality yourself if you want. But it's a pain. That's why libraries exist.
It is simply a standard for identifying the name of a command line parameter from the parameter value that may exist. e.g. gcc -o myfile.o
The windows world usually sees a - or a / as the marker. I've often encountered a -- in the unix/bsd world as well.

Program to call other programs

I am writing a program that will solve a type of min. spanning tree problem. i have 2 different algorithms that I've gotten working in two separate .cpp files i've named kruskels.cpp and prims.cpp.
my question is this:
each file takes the following command line to run it . time ./FILENAME INPUTFILE FACTOR
i would like to make a program that, depending on what inputfile is entered, will run either kruskels.cpp or prims.cpp. how can i do this?
this program must pass those command line arguments to kruskels or prims. each file (kruskels.cpp and prims.cpp) are designed to be run using those command line arugments (so they take in INPUTFILE and FACTOR as variables to do file io).
this should be for c++.
You can call external programs using the system function.
However, it would be much better to build your Kruskal and Prim solvers in a modular way as classes, and instantiate the appropriate class from your main, according to the input. For this you'll link kruskels.cpp, prims.cpp and your main.cpp into a single executable.
The standard way is to use system(). You might also want to look up popen() (or, on Windows, _popen()).
Edit: My assumption was that you have two executables and (critical point) want to keep them as separate executables. In that case, using system is pretty straightforward. For example, you could do something like:
std::stringstream buffer;
if (use_Kruskals)
buffer << "Kruskals " << argv[1] << argv[2];
else
buffer << "Prims " << argv[1] << argv[2];
system(buffer.str().c_str());
Depending on what you're doing (and as Eli pointed out) you might want to create a single executable, with your implementations of Prim's and Kruskal's methods in that one executable instead. Without seeing your code for them, it's impossible to guess how much work this would be though.
If you need your top program to regain control after executing one of your two child programs, use system() or popen(), if you don't need it then you can use execve()