title: Linux API to list running processes? - with arguments
body: <p>This post answer almost my question:
  <a href="https://stackoverflow.com/questions/939778/linux-api-to-list-running-processes">Linux API to list running processes?</a></p>
  
  <p>But what is missing in the example code (C++/C - see below) is the argument of the process. For example the program called mypaint will only be listed as "python2.7" and not the full executable and arguments "python2.7 /usr/bin/mypaint".</p>
  
  <p>From the man page of proc:
  /proc/[pid]/cmdline
  This holds the complete command line for the process, unless the process is a zombie. In the latter case, there is nothing in this file: that is, a read on this file will return 0 characters. The command-line <strong>arguments appear in this file as a set of strings separated by null bytes ('\0')</strong>, with a further null byte after the last string.</p>
  
  <p>How can I modify this code to list also the argument of the process?</p>
  
  <pre><code>#ifndef __cplusplus
      #define _GNU_SOURCE
  #endif
  
  #include &lt;unistd.h&gt;
  #include &lt;dirent.h&gt;
  #include &lt;sys/types.h&gt; // for opendir(), readdir(), closedir()
  #include &lt;sys/stat.h&gt; // for stat()
  
  #ifdef __cplusplus
      #include &lt;iostream&gt;
      #include &lt;cstdlib&gt;
      #include &lt;cstring&gt;
      #include &lt;cstdarg&gt;
  #else
      #include &lt;stdio.h&gt;
      #include &lt;stdlib.h&gt;
      #include &lt;string.h&gt;
      #include &lt;stdarg.h&gt;
  #endif
  
  
  #define PROC_DIRECTORY "/proc/"
  #define CASE_SENSITIVE    1
  #define CASE_INSENSITIVE  0
  #define EXACT_MATCH       1
  #define INEXACT_MATCH     0
  
  
  int IsNumeric(const char* ccharptr_CharacterList)
  {
      for ( ; *ccharptr_CharacterList; ccharptr_CharacterList++)
          if (*ccharptr_CharacterList &lt; '0' || *ccharptr_CharacterList &gt; '9')
              return 0; // false
      return 1; // true
  }
  
  
  int strcmp_Wrapper(const char *s1, const char *s2, int intCaseSensitive)
  {
      if (intCaseSensitive)
          return !strcmp(s1, s2);
      else
          return !strcasecmp(s1, s2);
  }
  
  int strstr_Wrapper(const char* haystack, const char* needle, int intCaseSensitive)
  {
      if (intCaseSensitive)
          return (int) strstr(haystack, needle);
      else
          return (int) strcasestr(haystack, needle);
  }
  
  
  #ifdef __cplusplus
  pid_t GetPIDbyName(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
  #else
  pid_t GetPIDbyName_implements(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
  #endif
  {
      char chrarry_CommandLinePath[100]  ;
      char chrarry_NameOfProcess[300]  ;
      char* chrptr_StringToCompare = NULL ;
      pid_t pid_ProcessIdentifier = (pid_t) -1 ;
      struct dirent* de_DirEntity = NULL ;
      DIR* dir_proc = NULL ;
  
      int (*CompareFunction) (const char*, const char*, int) ;
  
      if (intExactMatch)
          CompareFunction = &amp;strcmp_Wrapper;
      else
          CompareFunction = &amp;strstr_Wrapper;
  
  
      dir_proc = opendir(PROC_DIRECTORY) ;
      if (dir_proc == NULL)
      {
          perror("Couldn't open the " PROC_DIRECTORY " directory") ;
          return (pid_t) -2 ;
      }
  
      // Loop while not NULL
      while ( (de_DirEntity = readdir(dir_proc)) )
      {
          if (de_DirEntity-&gt;d_type == DT_DIR)
          {
              if (IsNumeric(de_DirEntity-&gt;d_name))
              {
                  strcpy(chrarry_CommandLinePath, PROC_DIRECTORY) ;
                  strcat(chrarry_CommandLinePath, de_DirEntity-&gt;d_name) ;
                  strcat(chrarry_CommandLinePath, "/cmdline") ;
                  FILE* fd_CmdLineFile = fopen (chrarry_CommandLinePath, "rt") ;  // open the file for reading text
                  if (fd_CmdLineFile)
                  {
                      fscanf(fd_CmdLineFile, "%s", chrarry_NameOfProcess) ; // read from /proc/&lt;NR&gt;/cmdline
                      fclose(fd_CmdLineFile);  // close the file prior to exiting the routine
  
                      if (strrchr(chrarry_NameOfProcess, '/'))
                          chrptr_StringToCompare = strrchr(chrarry_NameOfProcess, '/') +1 ;
                      else
                          chrptr_StringToCompare = chrarry_NameOfProcess ;
  
                      printf("Process name: %s\n", chrarry_NameOfProcess);
                      printf("Pure Process name: %s\n", chrptr_StringToCompare );
  
                      if ( CompareFunction(chrptr_StringToCompare, cchrptr_ProcessName, intCaseSensitiveness) )
                      {
                          pid_ProcessIdentifier = (pid_t) atoi(de_DirEntity-&gt;d_name) ;
                          closedir(dir_proc) ;
                          return pid_ProcessIdentifier ;
                      }
                  }
              }
          }
      }
      closedir(dir_proc) ;
      return pid_ProcessIdentifier ;
  }
  
  #ifdef __cplusplus
      pid_t GetPIDbyName(const char* cchrptr_ProcessName)
      {
          return GetPIDbyName(cchrptr_ProcessName, CASE_INSENSITIVE, EXACT_MATCH) ;
      }
  #else
      // C cannot overload functions - fixed
      pid_t GetPIDbyName_Wrapper(const char* cchrptr_ProcessName, ... )
      {
          int intTempArgument ;
          int intInputArguments[2] ;
          // intInputArguments[0] = 0 ;
          // intInputArguments[1] = 0 ;
          memset(intInputArguments, 0, sizeof(intInputArguments) ) ;
          int intInputIndex ;
          va_list argptr;
  
          va_start( argptr, cchrptr_ProcessName );
              for (intInputIndex = 0;  (intTempArgument = va_arg( argptr, int )) != 15; ++intInputIndex)
              {
                  intInputArguments[intInputIndex] = intTempArgument ;
              }
          va_end( argptr );
          return GetPIDbyName_implements(cchrptr_ProcessName, intInputArguments[0], intInputArguments[1]);
      }
  
      #define GetPIDbyName(ProcessName,...) GetPIDbyName_Wrapper(ProcessName, ##__VA_ARGS__, (int) 15)
  
  #endif
  
  int main()
  {
      pid_t pid = GetPIDbyName("bash") ; // If -1 = not found, if -2 = proc fs access error
      printf("PID %d\n", pid);
      return EXIT_SUCCESS ;
  }
  </code></pre>
  
  <p>(chrarry_NameOfProcess = only executable how to show also arguments)?</p>