views:

236

answers:

5

Hello,

I know the program name is passed as the first argument, and next simple example will print it to the standard output :

#include <iostream>
int main ( int argc, char *argv[] )
{
  std::cout<<argv[0]<<std::endl;
}

Is there a function to get the program name?

EDIT

I am starting the program from the shell, and the above code will always print the program name (I am using fedora 9, but I am sure it works in other distros).

I have found that /proc/self/ directory might contain what I am looking for, but I couldn't find what exactly in that directory.

+4  A: 

This is not guaranteed.

Usually, argv[0] holds the executable name but one can call your executable using execve and set it to something else.

In a word: don't rely on this.

ereOn
Moreover, at least on Windows, `argv[0]` may hold the full path as well as just the executable name w\ or w\o the extension.
Matteo Italia
argv[0] is always the name of the program I think.
Chubsdad
@Chubsdad: ereOn just pointed out when this might not be true. So no, it is not always the name of the program.
unwind
@Chubsdad: If you know write your own answer. If you only think then go look it up or wait for somebody that does know to answer. Currently you are wrong (and the foolish sheep who followed you with up-voting your comment).
Martin York
It's much worse than that. On Linux with bash, this parameter is user-faced : bash -c 'exec -a"The beautiful program name that is in argv[0]" ./executable'
BatchyX
@Martin York: that could have been softer....Never mind.
Chubsdad
+1  A: 

No, it depends entirely on what the parent program puts in there.

The exec family of functions allow the executable name to be totally different to the argument passed in, and this is supported by the ISO C standard.

If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment.

So no, it's only the program name if the name is available. And the section before that states:

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.

(my italics).

So, even their values are not dictated by the standard, it's up to the implementation entirely. This means that the program name can be empty if the host environment doesn't provide it, and anything else if the host environment does provide it.

However, implementation-defined has a specific meaning in the ISO standards - the implementation must document how it works. So even UNIX, which can put anything it likes into argv[0] with the exec family of calls, has to (and does) document it.

Similarly (thanks to Chubsdad), C++03 states:

"If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (NTMBSs) (17.3.2.1.3.2) and argv[0] shall be the pointer to the initial character of a NTMBS that represents the name used to invoke the program or "".

So, even there, argv[0] may not contain anything and, even if it does, "represents the name" is a very vague requirement. It doesn't have to be the full pathname of the executable or even contain the command used to invoke it


Another way to do it under Linux is with the proc filesystem. I think /proc/self/exe is a link to the executable file.

Wikipedia has an entry for the procfs filesystem with lots of goodies.

paxdiablo
The C++ standard (03) states - "If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (NTMBSs)(17.3.2.1.3.2) and argv[0] shall be the pointer to the initial character of a NTMBS that represents the name used to invoke the program or "".
Chubsdad
So, is the behavior possibly different for C and C++?
Chubsdad
I don't think so, @Chubsdad: that seems little different to the C standard. `argv[0]` can represent the program name or be empty. Notice also the weasel words "represent the name" - this in no way has to be the full path of the executable or even a partial match. Maybe I'm cynical but the string `"A delay program"` would be perfectly representative of `/bin/sleep` :-)
paxdiablo
@Chubsdad: I believe that's 100% equivalent to what pax quoted.
Roger Pate
'represents the name' is specifying the property of the NTMBS string. I think it means that the sequence of bytes would correspond to the program name. So 'sleep' or '/bin/sleep' probably is fine but not 'A cute little delay program' :)
Chubsdad
/proc/self/exe I have seen that it links to the executable, but how can I transform that to the string?
VJo
That's one interpretation :-) You're probably right but, unfortunately, it still doesn't get around thet `or ""` bit. I know there's a way to do it in Windows as well but I think the `/proc/self/exe` is probably safest for Linux. I'm not sure if that softlink stays valid if someone deletes the executable but I would suspect so, you just wouldn't be able to follow it, but you should still be able to `readlink` it.
paxdiablo
@VJo: see http://linux.die.net/man/2/readlink
paxdiablo
a softlink is allowed to point to a deleted file. In fact it's allowed to point to anything. They are plenty of those in /proc/*/fd/ that points to "[socket:1984]" or "[pipe:6116]" which doesn't exist at all in the filesystem.
BatchyX
+2  A: 

You can determine the pid of your process using getpid() and then inspect the contents of /proc/[pid number] using standard I/O tools.

This is what I thought to do, but what holds the program name?
VJo
See my answer. You don't need `getpid`.
larsmans
You may be able to get what you need by calling readlink() on /proc/[pid]/exe or (even better) /proc/self/exe. Not 100% sure though.
`/proc/self` is a semi-magic name for the current process's /proc entry. No real need for `getpid()`. But +1 for recommending /proc.
cHao
+4  A: 

No, there is no such function. Linux stores the program name in __progname, but that's not a public interface. In case you want to use this for warnings/error messages, use the err(3) functions.

If you want the full path of the running program, call readlink on /proc/self/exe:

char *program_path()
{
    char *path = malloc(PATH_MAX);
    if (path != NULL) {
        if (readlink("/proc/self/exe", path, PATH_MAX) == -1) {
            free(path);
            path = NULL;
        }
    }
    return path;
}

(I believe __progname is set to the basename of argv[0]. Check out the glibc sources to be sure.)

larsmans
With readlink it works fine. Thank you. I also tried __progname, but it didn't compile. Not sure what I have to include to make it work.
VJo
You shouldn't use `__progname`, since it's undocumented and for internal use by the `err(3)` functions only. (If you want to cheat, declare it with `extern const char *__progname;` But really, you don't want to cheat.)
larsmans
+2  A: 

If you use GLib you can use the function g_get_prgname(). On Win32 it calls GetModuleFileNameW(), on everything else it appears to return NULL though.

Steve-o
I tried this, and it didn't work. I included glib.h
VJo
Seems to get set when you use g_option_context_parse() with argv[0] for non-Win32 platforms.
Steve-o