How much memory is allocated for argv[]? [duplicate] - c++

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

Related

C++ sizeof(environ), the value isn't what I expected [duplicate]

In the proccess of learning C, I'm trying to write a program that accepts one of your environment variable as input, and outputs its value.
The question is, is there any way to know the length of envp? I mean, how many envp is there? I'm aware that it is a char** - an array of string. And finding the size of array in C is problematic already. What can I do to know the size of envp?
Please just provide direction, not the concrete answer (or code).
It's terminated by a NULL pointer. You have to count it if you want to know the length.
the value of argv[argc] == NULL that should give you a clue.
You should look into getenv(). It's more portable than manipulating envp, because environments like plan9 implement the environment differently, while preserving the behavior of this function.

How are the argc and argv values passed to main() set up?

I want to better understand what's going on under the hood with the command line arguments when a C or C++ program is launched. I know, of course, that argc and argv, when passed to main(), represent the argument count and argument vector, respectively.
What I'm trying to figure out is how the compiler knows to interpret int argc as the number of arguments passed from the command line. If I write a simple function that attempts to mimic main() (e.g. int testfunc(int argc, char* argv[])), and pass in a string, the compiler complains, "Expected 'int' but argument is of type char*" as I would expect. How is this interpreted differently when command line arguments are passed to main()?
In common C implementations, main is not the first routine called when your process starts. Usually, it is some special entry point like _start that is provided by the C library built into your program when you link it. The code at this special entry point examines the command line information that is passed to it (in some way outside of C, particular to the operating system) and constructs an argument list for main. After that and other work, it calls main.
You don't pass argc value on your own (from the command line, for example), it is supplied by your environment (runtime), just like the exact content for argc.[Note below]
To elaborate, C11, chapter §5.1.2.2.1, (indicators mine)
The value of argc shall be nonnegative.
argv[argc] shall be a null pointer.
If the value of argc is greater than zero, the array members argv[0] through
argv[argc-1] inclusive shall contain pointers to strings, which are given
implementation-defined values by the host environment prior to program startup. The
intent is to supply to the program information determined prior to program startup
from elsewhere in the hosted environment. [Note start]If the host environment is not capable of
supplying strings with letters in both uppercase and lowercase, the implementation
shall ensure that the strings are received in lowercase.[Note end]

How to create files given relative path [duplicate]

This question already has answers here:
Creating files in C++
(8 answers)
Closed 8 years ago.
I have a path given in command line with a filename in it like:
./something.bin infomration /some/some2/thing.txt
I know I can put the /some/some2/thing.txt into a global variable and use it. Now, I want to:
create a file named thing.txt in the path /some/some2/
For things like this you'll have to use the parameters passed to your main entry point:
int main(int argc, char **argv) {
// some other code
return 0;
}
As you can see, main() will receive two parameters:
argc: The first parameter will include the number of parameters passed through the second parameter.
argv: The second parameter points to pointers that point to strings with the actual parameters.
The usage is quite trivial, but it's important to remember that the very first "argument" is the executable file itself.
In your example, argc would be set to 3 and argv would point to the following strings:
argv[0]: ./something.bin (based on the OS, this could also be an absolute path)
argv[1]: infomration [sic]
argv[2]: /some/some2/thing.txt
As you can see, all you'll have to do is the following:
Verify the number of arguments is correct.
Verify the second argument (infomration) is correct.
Use the third argument to receive the actual file name.
Keep in mind that the user might pass invalid parameters (e.g. invalid characters for a file name) or he might try to trick you into doing something you shouldn't do (like passing reserved names).

How to read arguments from target [duplicate]

This question already has answers here:
Reading command line parameters
(4 answers)
Closed 9 years ago.
When you right click on a program in windows(such as starcraft.exe) and look at its properties there is a text field called "target" which contains the full path of the binary. I have seen programs able to parse flags added to the target such as "C:\programfiles\myprogram\myprogram.exe -x 1280 -y 360" and the program would start up in the specified resolution. My question is how to read those arguments, if it is done by argv[] please just inform me of my stupidity.
C++ is the language, VS express 2012 desktop is the environment.
you receive those parameters when calling executable main method int main(int argc, char* argv[]) as argc (count) and argv[] parameters all you have to do is just parse them
here is an example How to parse command line parameters
You'll want to avoid comparisons between char* and string literals without strncmp.
Remember that argc is the the argument count (including the program name).
argv is an array of C strings specifying the arguments (first being the program name as invoked).
In this case, you're usually best off using a library, like getopt. This will make interleaved options, long options, and arguments much more sane to manage (assuming order between options and arguments is largely unimportant).

GetCommandLine linux *true* equivalent

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.