Why pass the program name as a parameter to main? - c

If I call:
./program hello world
then:
argc would be 3.
argv[0] would be "./program".
argv[1] would be "hello".
argv[2] would be "world".
What's the purpose of passing "./program" as an argument? In fact, it's not an argument at all!

You can make symbolic links to the same binary. Depending on what link you use, you will get different behaviour. Busybox is an example of this.

One use is so that the application can know how it was invoked (essentially, what its own name is).
Note that what appears in argv[] is implementation-defined. If you use one of the UNIX exec() functions, for instance, the contents can be whatever you like.

...and you can make make a nice help-function that display a help-text when invoked that doesn't need to be updated when the name of the executable changes.

Related

Parsing command line arguments in c without spaces

I have a program that parses command line arguments using a while loop. Simply, while iterating through the length of argc, if an argument matches a flag than the next argument is taken as a variable. Now in my assignment we are asked to do this in a way that spaces between flags and integer arguments are optional.
For example if i input -k1 it is the same as -k 1 and 1 is the value stored.
I can't find anything that allows this. The only thing I can think is that if argc is an even number it means that there are no pals between a set of argument and i could use scanf("-k%d",key).
Any helpful pointers for me?
At a POSIX-compatible OS you can use a standart API for that: man getopt. It will do all the dirty job to parse the parameters and will provide you a convenient interface to deal with.
Here is a good example for it: http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt

How to get the name of the executed file after compilation with gcc?

I'm coding a program in C, and I'd like it to detect its own name. I'll explain :
I want it to do a specific action, depending of its name. Let's say :
if (!strcmp(myName, "Program1"))
printf("I am program 1!");
else
printf("I am someone else !");
This code is contained in Program1.c, and is compiled with :
gcc Program1.c -o Program1
And I'd execute it with :
./Program1
But I'm not able to find the code that would allow me to get the value "Program1" (the name of the executable file), which would be the variable myName in the code I gave.
Can someone help me please?
The name of the output from gcc is not stored anywhere in the file by default, and I don't know of a way to inject it into the binary. But is this what you really want?
The name that the program is invoked as is available as argv[0]. That may be different if the executable has been renamed after compilation.
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("My name is %s\n", argv[0]);
return 0;
}
Argument 0 is chosen by the calling program. It can be a full path with directory information (it typically depends whether the caller performed PATH lookup or invoked the executable from an explicit location), so if you want to act based on that, you should probably strip the path information (e.g. with basename on Unix/POSIX platforms).
Argument 0 is chosen by the caller, so it's a matter of convention. But it's a pretty much universally followed convention, except when the caller has a good reason not to respect it. Most platforms have a way to locate the executable. For example, on Linux, /proc/self/exe is a symbolic link to the executable. But in most cases, if the caller passes a different name, that means that the caller wants your program to behave as that different name, so argv[0] is what you should use.
argv[0] can be NULL if the program is invoked without arguments (i.e. if argc is 0). That's rare, but for robustness your program should do something sensible in that case.

making getopt() process argv[0]

I trying to emulate main() function like behavior for normal functions using string tokenizing and storing tokens in a NULL terminated char* array.
Every thing is fine except getopt(). It won't rearrange argv[0] coz it expects the first argument to be program name. But for my function the argv[0] isn't the program name. I want to make getopt() to also rearrange argv[0](non-option). How do I do that?
getopt(3) uses a global variable optind (option index) to track its progress through argv and initializes it to 1. Try setting optind = 0 before reading the options.
Try using
c = getopt(argc + 1, argv - 1, "xyz")
Edit: Which, as pointed out below, is a hack But I'd be interested to see a machine on which it didn't work.
Though the hack #Tom Tanner suggested worked for certain systems, it didn't compile for the target which I'm supposed to make it work. Another work around I found is to replace the first argument in my argv[] array with a dummy string and use getopt() with it.

calling exec with a variable number of arguments?

I have a program which forks off other processes. The arguments to my program include the process name of the process to be forked, along with any arguments.
This means, when I make the call to exec(), I need to be able to handle however many arguments were supplied.
Any ideas?
Thanks.
The execv function takes a pointer to an array of arguments.
Just like in main, the last element in the array needs to be a null pointer.
Alternately, execl() takes a variable number of arguments, with a NULL pointer at the end of the list. You should probably use execv(), however, as it's much cleaner; varargs in C can only be considered an ugly hack (take a look at (the files pointed to by) /usr/include/varargs.h sometime, if you dare!).

Best practice when referring to a program's name in C

What is considered best practice when referring to a program's name? I've seen:
#define PROGRAM_NAME "myprog"
printf("this is %s\n", PROGRAM_NAME);
as well as:
printf("this is %s\n", argv[0]);
I know, that the second approach will give me ./myprog rather than myprog when the program is not called from $PATH and that the first approach will guarantee consistence regarding the program's name.
But is there anything else, that makes one approach superior to the other?
The second approach is superior when you have multiple links. In *nix systems, sometimes behavior depends on how you call a program. So hard coding the program name would clearly be a problem -- it could never check that.
I tried to take the best of both worlds:
char const * program_name;
int main(int argc, char **argv) {
program_name = argv[0];
//...
}
If you need program_name to be available in some other file you can declare it like this:
extern char const * program_name;
I declare "char const *" because I want it to be a pointer which points to const data. I'm not sure if I did right this part.
I usually use argv[0], or basename(argv[0]) if possible. From the user's POV, I think if they rename or hardlink an executable (or somebody else does that for them), then they want messages from it to appear under the name they're using, not under some other name it was compiled as, that they may or may not know about.
Similarly if you discover in future that you want to compile your program under different names with different options, to give different versions, do you want to wrap an #ifndef around that #define and make sure that it's defined via the compiler command line: -DPROGRAM_NAME=myprog_demo, or do you just want to do it and it works?
The exception might be that if your usage instructions are an extract from a manpage or other documentation, then possibly you do want to hardwire the program name into that. But then you probably wouldn't use the #define either.
Implementations needn't provide argv[0], though, so for best portable practices handle that case too. Then again, if your system doesn't provide it then probably the user isn't actually going to see messages on any kind of terminal, either.
By the way:
#define PROGRAM_NAME "myprog"
puts("this is " PROGRAM_NAME);
The second approach could give you also strings like /usr/bin/myprog if you executed it that way; basename should give the name of the executable (that you could think of as the name of your program)... unless it is symlinked... (in that case, you have the name of the link... that could be used to do choices of some kind in the program behaviour).
The first approach "fixes" the program name to what the programmer wanted, no matter how the user renamed the executable file or symlinked (or even hardlinked)
It doesn't exactly answer your question for programming best practices, but I think you should also keep in mind what's best for the user.
I personally prefer programs refering to themselves using argv[0], i.e. the command I was calling, and not some random name that the coder hardcoded in the program. A few examples where a hardcoded name is annoying or at least not helpful:
I've created a link to a program
I've renamed the binary for some reason
I have multiple executables with the same basenames in different directories in my $PATH
A program gives me hints about other ways to call it, e.g. in "usage" messages
The only situation where I'd prefer a hardcoded program name is when I'm using GUI applications. I wouldn't want to see "~/foo/bar.pl" as a window title.
The former is superior to the later when your don't have argv at hand.
#define PROGRAM_NAME "myprog"
void salute()
{
// no argv available
printf("Hello from %s\n", PROGRAM_NAME );
}
void main( int argc, char** argv )
{
salute();
}
Depends whether argv is in scope or not...

Resources