In the previous post I described Windows API that can be used to get command line and full path of the EXE file of the process.
This post describes how to get the same information on Linux.
There is a pseudo-filesystem directory called “/proc/[PROCESS-ID]”, which contains a set of useful files that describe the process with PROCESS-ID. In our case we may use files “/proc/[PROCESS-ID]/cmdline” and “/proc/[PROCESS-ID]/exe”.
“/proc/[PROCESS-ID]/cmdline” is a text file which contains the command line. Note that arguments are separated by 0 character, so if you just fgets / puts you see program name only.
“/proc/[PROCESS-ID]/exe” is a symbolic link to executed command. To read the value of symbolic link you may use readlink (note that readlink may not append 0 character to the string!).
So the code may look like:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
void get_command_line() {
FILE *f;
char file[256], cmdline[256] = {0};
sprintf(file, "/proc/%d/cmdline", getpid());
f = fopen(file, "r");
if (f) {
char *p = cmdline;
fgets(cmdline, sizeof(cmdline) / sizeof(*cmdline), f);
fclose(f);
while (*p) {
p += strlen(p);
if (*(p + 1)) {
*p = ' ';
}
p++;
}
puts(cmdline);
} else {
printf("unable to open file %s\n", file);
}
}
void get_full_process_name() {
size_t linknamelen;
char file[256], cmdline[256] = {0};
sprintf(file, "/proc/%d/exe", getpid());
linknamelen = readlink(file, cmdline, sizeof(cmdline) / sizeof(*cmdline) - 1);
cmdline[linknamelen + 1] = 0;
printf("Full name is %s\n", cmdline);
}
To get more information:
man proc
man 2 getpid
man 2 readlink
And now a few notes about links. Suppose that you compile the source to “a.out” file and created a soft link called “aaa” to it:
ln -s ./a.out aaa
Now if you run
./aaa
the result is:
Command line: aaa
Full name: /home/ivbel/my_tests/a.out
And if you create a hard link like
link ./a.out hard_a
The result of running hard_a is
Command line: hard_a
Full name: /home/ivbel/my_tests/hard_a
thanks- this was helpful
ReplyDelete