30

How can I get the process name in C? The same name, which is in /proc/$pid/status. I do not want to parse that file. Is there any programmatic way of doing this?

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
Mariusz
  • 1,825
  • 5
  • 22
  • 36

8 Answers8

45

If you're on using a glibc, then:

#define _GNU_SOURCE
#include <errno.h>

extern char *program_invocation_name;
extern char *program_invocation_short_name;

See program_invocation_name(3)

Under most Unices, __progname is also defined by the libc. The sole portable way is to use argv[0]

Craig McQueen
  • 41,871
  • 30
  • 130
  • 181
Pierre Habouzit
  • 690
  • 4
  • 6
30

It's either pointed to by the argv[0] or indeed you can read /proc/self/status. Or you can use getenv("_"), not sure who sets that and how reliable it is.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
  • 3
    Note that `getenv("_")` appears to return the process originally started by the shell -- if I call it in a process started by `make`, I see "/usr/bin/make", rather than my process name. This means that it's probably set by the shell. – Roger Lipscombe Apr 29 '14 at 10:47
  • _ is set by the shell. – John Kearney Mar 22 '23 at 11:42
17

You can use __progname. However it is not better than argv[0] as it may have portability issues. But as you do not have access to argv[0] it can work as follows:-

extern char *__progname;
printf("\n%s", __progname);
ste
  • 316
  • 2
  • 7
raj_gt1
  • 4,653
  • 2
  • 20
  • 28
5

I often make use of following call,

char* currentprocname = getprogname();
RLT
  • 4,219
  • 4
  • 37
  • 91
  • 7
    That's BSD-specific. You can get it on Linux with `libbsd`, but it's not part of libc as it is on FreeBSD or OS X. – Cairnarvon Jun 05 '13 at 13:14
4

Look at the value of argv[0] which was passed to main. This should be the name under which your process was invoked.

Borealid
  • 95,191
  • 9
  • 106
  • 122
3

This is a version that works on macOS, FreeBSD and Linux.

#if defined(__APPLE__) || defined(__FreeBSD__)
const char * appname = getprogname();
#elif defined(_GNU_SOURCE)
const char * appname = program_invocation_name;
#else
const char * appname = "?";
#endif
Ales Teska
  • 1,198
  • 1
  • 17
  • 38
1

If you cannot access argv[] in main(), because you are implementing a library, you can have a look at my answer on a similar question here.

It basically boils down into giving you access to argc, argv[] and envp[] outside of main(). Then you could, as others have already correctly suggested, use argv[0] to retrieve the process name.

SIGSEGV
  • 412
  • 4
  • 5
1

for posterity, a version that's more C++-ish and works also on MSVC:

https://godbolt.org/z/sh3TnM

#define FMT_HEADER_ONLY
#include <fmt/format.h>

std::string get_current_process_name()
{
    #if defined(__APPLE__) || defined(__FreeBSD__)
        return getprogname();
    #elif defined(_GNU_SOURCE)
        return program_invocation_name;
    #elif defined(_WIN32)
        return __argv[0];
    #else
        return "?";
    #endif
}

int main()
{
    fmt::print("whatsmyname: {}\n", get_current_process_name());
    return 0;
}

// msvc output:
// whatsmyname: C:\Users\<user>\source\repos\Project6\Debug\Project6.exe
Jan Wilmans
  • 665
  • 6
  • 10