Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FreeBSD: How to get the process name of a PID?

Tags:

c++

c

c++11

freebsd

I am trying to write a function which returns the parent process name,
if it is bash, then it should return bash.

const std::string &getParentProcessName() {
  static std::string name;
  auto ppid = getppid();
#ifdef __FreeBSD__
  // ?????
#else
 ...
#endif
  name = "unknown";
  return name;
}
like image 369
Thomas Avatar asked Apr 02 '14 18:04

Thomas


People also ask

How do I find the running process name?

You can list running processes using the ps command (ps means process status). The ps command displays your currently running processes in real-time. This will display the process for the current shell with four columns: PID returns the unique process ID.

What is the name of the process with PID 1?

Process ID 1 is usually the init process primarily responsible for starting and shutting down the system. Originally, process ID 1 was not specifically reserved for init by any technical measures: it simply had this ID as a natural consequence of being the first process invoked by the kernel.

How can we find the process name from its process ID in Linux?

With Linux, the info is in the /proc filesystem. To get the command line for process id 9999, read the file /proc/9999/cmdline . And to get the process name for process id 9999, read the file /proc/9999/comm .


2 Answers

Use the kinfo_getproc function

   pid_t pid = ...;
   struct kinfo_proc *proc = kinfo_getproc(pid);
   if (proc) {
     printf("Name %s\n", proc->ki_comm); 
     //ki_comm should be the program name
     //see the sys/user.h header file for other relevant fields.

     free(proc);
   }

See also the libprocstat functions for aquiring process information.

like image 148
nos Avatar answered Oct 02 '22 02:10

nos


To help future visitors who may find this question,

here is a solution which works on Linux, FreeBSD, OS X, NetBSD and Windows:

__attribute__((unused)) std::string *getFileContent(const std::string &file,
                                                    std::string &content) {
  std::ifstream f(file.c_str());

  if (!f.is_open())
    return nullptr;

  f.seekg(0, std::ios::end);
  auto len = f.tellg();
  f.seekg(0, std::ios::beg);

  if (len != static_cast<decltype(len)>(-1))
    content.reserve(static_cast<size_t>(f.tellg()));

  content.assign(std::istreambuf_iterator<char>(f),
                 std::istreambuf_iterator<char>());

  return &content;
}

const std::string &getParentProcessName() {
  static std::string name;
#ifdef _WIN32
  HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  PROCESSENTRY32 pe;

  auto zerope = [&]() {
    memset(&pe, 0, sizeof(pe));
    pe.dwSize = sizeof(PROCESSENTRY32);
  };

  zerope();

  auto pid = GetCurrentProcessId();
  decltype(pid) ppid = -1;

  if (Process32First(h, &pe)) {
    do {
      if (pe.th32ProcessID == pid) {
        ppid = pe.th32ParentProcessID;
        break;
      }
    } while (Process32Next(h, &pe));
  }

  if (ppid != static_cast<decltype(ppid)>(-1)) {
    PROCESSENTRY32 *ppe = nullptr;
    zerope();

    if (Process32First(h, &pe)) {
      do {
        if (pe.th32ProcessID == ppid) {
          ppe = &pe;
          break;
        }
      } while (Process32Next(h, &pe));
    }

    if (ppe) {
      char *p = strrchr(ppe->szExeFile, '\\');
      if (p) {
        name = p + 1;
      } else {
        name = ppe->szExeFile;
      }
    }
  }

  CloseHandle(h);

  if (!name.empty()) {
    return name;
  }
#else
  auto getName = [](const char * path)->const char * {
    if (const char *p = strrchr(path, '/')) {
      return p + 1;
    }
    return path;
  };
  (void)getName;
  auto ppid = getppid();
#ifdef __APPLE__
  char path[PROC_PIDPATHINFO_MAXSIZE];
  if (proc_pidpath(ppid, path, sizeof(path))) {
    name = getName(path);
    return name;
  }
#elif defined(__FreeBSD__)
  struct kinfo_proc *proc = kinfo_getproc(ppid);
  if (proc) {
    name = getName(proc->ki_comm);
    free(proc);
    return name;
  }
#else
  std::stringstream file;
  file << "/proc/" << ppid << "/comm";
  if (getFileContent(file.str(), name)) {
    if (!name.empty() && name.rbegin()[0] == '\n') {
      name.resize(name.size() - 1);
    }
    return name;
  } else {
    file.str(std::string());
    file << "/proc/" << ppid << "/exe";
    char buf[PATH_MAX + 1];
    if (readlink(file.str().c_str(), buf, sizeof(buf)) > 0) {
      buf[PATH_MAX] = '\0';
      name = getName(buf);
      return name;
    }
  }
#endif
#endif
  name = "unknown";
  return name;
}
like image 34
Thomas Avatar answered Oct 02 '22 04:10

Thomas