Created
October 6, 2014 20:30
-
-
Save fclairamb/a16a4237c46440bdb172 to your computer and use it in GitHub Desktop.
posix: Get parent process id and name
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef SHELL | |
gcc -Wall -Werror $0 && ./a.out | |
exit $? | |
#endif | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <stdlib.h> | |
/** | |
* Get a process name from its PID. | |
* @param pid PID of the process | |
* @param name Name of the process | |
* | |
* Source: http://stackoverflow.com/questions/15545341/process-name-from-its-pid-in-linux | |
*/ | |
static void get_process_name(const pid_t pid, char * name) { | |
char procfile[BUFSIZ]; | |
sprintf(procfile, "/proc/%d/cmdline", pid); | |
FILE* f = fopen(procfile, "r"); | |
if (f) { | |
size_t size; | |
size = fread(name, sizeof (char), sizeof (procfile), f); | |
if (size > 0) { | |
if ('\n' == name[size - 1]) | |
name[size - 1] = '\0'; | |
} | |
fclose(f); | |
} | |
} | |
/** | |
* Get the parent PID from a PID | |
* @param pid pid | |
* @param ppid parent process id | |
* | |
* Note: init is 1 and it has a parent id of 0. | |
*/ | |
static void get_process_parent_id(const pid_t pid, pid_t * ppid) { | |
char buffer[BUFSIZ]; | |
sprintf(buffer, "/proc/%d/stat", pid); | |
FILE* fp = fopen(buffer, "r"); | |
if (fp) { | |
size_t size = fread(buffer, sizeof (char), sizeof (buffer), fp); | |
if (size > 0) { | |
// See: http://man7.org/linux/man-pages/man5/proc.5.html section /proc/[pid]/stat | |
strtok(buffer, " "); // (1) pid %d | |
strtok(NULL, " "); // (2) comm %s | |
strtok(NULL, " "); // (3) state %c | |
char * s_ppid = strtok(NULL, " "); // (4) ppid %d | |
*ppid = atoi(s_ppid); | |
} | |
fclose(fp); | |
} | |
} | |
int main(int argc, char *argv[]) { | |
pid_t pid = getpid(); | |
while (pid != 0) { | |
char name[BUFSIZ]; | |
get_process_name(pid, name); | |
printf("%6d - %s\n", pid, name); | |
get_process_parent_id(pid, & pid); | |
} | |
return 0; | |
} | |
/* Your should get something like that: | |
24090 - ./a.out | |
24084 - bash | |
2425 - bash | |
1369 - /usr/bin/xfce4-terminal | |
13056 - init | |
12994 - lightdm | |
1428 - lightdm | |
1 - /sbin/initsession-child | |
*/ |
change posix to unix. not every posix system has /proc
@fclairamb Could you please state under which license you put this code?
I would like to use it in a GPL2 licensed project and want to follow the rules ;-)
Edit: Intended usage would be this -> mcdope/pam_usb#45
@mcdope License would be MIT
Thanks for clarifying!
simple and cool code! love it.
For C++ guys, here is the version you look for:
const auto parentProcessName = []() -> std::string {
const std::string cmdlinePath = "/proc/" + std::to_string(::getppid()) + "/cmdline";
std::ifstream file(cmdlinePath);
if (!file.is_open()) {
PLOGE << "Failed to open parent process name file: " << cmdlinePath;
return "";
}
std::string parentProcessName;
std::getline(file, parentProcessName);
return parentProcessName;
}();
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And if you don't have /proc filesystem? This is a rhetorical question, of course :)