Retrieving command line arguments of a particular PID

hi

The "ps" command shows the command line arguments of running processes:

$ /bin/ps -o pid,args -e
....
26031 pico /tmp/crontab2KaG1Y
596 /usr/lib/sendmail -bd -q15m
9955 xterm -n 1 -sb -sl 800 -g 80+70+70
2627 /usr/sbin/snmpd -Lsd -Lf /dev/null -p /var/run/snmpd -a 1691
....

I need to write a C program to get the command line arguments of a particular process id, but do not want to rely on:

system("/bin/ps -o pid,args -e");
--or--
popen("/bin/ps -o pid,args -e", "r");

On Solaris, the command line arguments of a running process are stored at: /proc/<pid>/psinfo
On Linux, the command line arguments of a running process are stored at: /proc/<pid>/cmdline

These two files are not text files, so I'm not sure how to read the contents.

Where can I find example C code to read the contents of the "psinfo" and "cmdline" files?

Thanks
--Andrew

In Linux, cmdline is to be used as a regular file which splits arguments by nil chars. So, if you have three arguments named 1.foo 2.bar 3.example, then cmdline will have "foo\0bar\0example\0".

Just read cmdline's content and print the arguments by indexing all \0 locations and using pointer arithmetics.

PS: remember that most C string functions stop at '\0' and if you where to have a string like:

char * foobar = "foo\0bar\0example\0";
printf ("%s\n", foobar); /* this would print foo */
printf ("%s\n", foobar+4); /* this would print bar */
/* pointer arithmetics... */

hi,

Thank you for the tip.

I am able to read in the contents of the "cmdline" file into a variable,
but when I try to print out the string, the output shows only characters before
the first null character.

How do I get the other characters after the first null character.
You suggested that i use pointer arithmetic, but how do i'm not sure
how to get the index of the '\0'.

I used strtok(), but it stops processing after the first null.

my code is below.
-------------------------------------------------

% cd /proc/14007
% cat cmdline
emacs--background-colorblack/tmp/abc

---------------------------

% ps -e -o pid,args | grep 14007
14007 emacs --background-color black /tmp/abc

---------------------------------------

% a.out /proc/14007/cmdline
file length is: 0
content is [emacs] <<<<<----- everything after first null character is not shown
strlen: 5
1: emacs
Tokenizing complete

==============================================================

#include <stdio.h>


main (int argc, char *argv[])
{
  FILE *fp;
  char *tok;
  int x = 1;
                  
  long  lFileLen;               /* Length of file */
  char *contents;                  /* Dynamically allocated buffer (entire file) */

  if (argc < 2) {
     printf("need a filename\n");
     exit(1);
  }

  fp = fopen(argv[1], "r"); /* Open in BINARY mode */
  if (fp == NULL) {
      printf("could not open file\n");
      exit(2);
  }

  fseek(fp, 0L, SEEK_END);  /* Position to end of file */
  lFileLen = ftell(fp);     /* Get file length */
  rewind(fp);               /* Back to start of file */

  printf("file length is: %ld\n", lFileLen);
 
  lFileLen = 200; /* assume there are 200 bytes at most */
  
  contents = (char*)calloc(lFileLen + 1, sizeof(char));

  if(contents == NULL )
  {
    printf("\nInsufficient memory to read file.\n");
    return 0;
  }

  /* Read the entire file into contents */
  fread(contents, lFileLen, 1, fp); 
  
  fclose(fp);

  printf("content is [%s]\n", contents);  /* nothing after first null character !!! */
  printf("strlen: %d\n", strlen(contents)); 
  
   /* extract first string from string sequence */
  tok = (char*)strtok(contents, "\0");

  /* print first string after tokenized */
  printf("%i: %s\n", x, tok);

  /* loop until finishied */
  while (1) 
  { 
          /* extract string from string sequence */
          tok = (char*)strtok(NULL, "\0");

          /* check if there is nothing else to extract */
          if (tok == NULL)
          {
                  printf("Tokenizing complete\n");
               /*   exit(0); */
                  break;
          } 

          /* print string after tokenized */
          printf("/%i: %s\n", x, tok);
          x++;
  } 


  free(contents);

}