Read proc stat information
Asked Answered
S

1

6

Hello I require following information about process with some PID:

name, ppid, state, #ofOpenFiles, #ofThreads

I know the example of /proc/pid/stat file is like :

15 (watchdog/1) S 2 0 0 0 -1 69239104 0 0 0 0 0 69 0 0 -100 0 1 0 6 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 99 1 0 0 0 0 0 0 0 0 0 0 0

My current attempt of parsing such file:

FILE *fp;
           char buff[255];
           fp= fopen("/proc/123/stat", "r");
           if(fp == NULL){

           }else{

             fscanf(fp, "%d %s %c %d %d %d %d %d %u %lu ....", &pid, &name, &ppid......)
             fclose(fp);
           }

I don't find this very good method. How to do this?

Shanklin answered 3/1, 2016 at 10:2 Comment(12)
What specifically do you not like about your current method of reading /proc?Mccreary
looks like I pick up lots of information I don't need. So there is so better way :s?Shanklin
1. You don't need to read the entire stat file. Just stop at the last field that you are interested in. 2. For any fields that you need to read but don't care about, use the * format specifier to ignore it so that you don't need to provide a variable to store its value.Mccreary
Is C a requirement? Otherwise a simple awk script would be a lot easier.Annalist
@Annalist yes, unfortunatelyShanklin
@Shanklin sorry to hear that ;) knowing that /proc/stat is Linux-only and Linux generally comes with awk...Annalist
Note that there's a problem since filename (the second entry) can contain spaces, and it doesn't have to contain (, so the parsing is a little bit more complicated.Liddell
Sorry, I misread the man page - parenthesis are always there.Liddell
@Shanklin - Do you know how often /proc/stat/ is updated with new times?Salamanca
@ChetanArvindPatil pretty sure it's live at anypointShanklin
@Shanklin - No specific update interval in msec()?Salamanca
@ChetanArvindPatil Quick google search would give you all information you need..Shanklin
A
4

The solution you describe looks good (especially using @kaylum's idea of * format specifier). Note that you can use the same variable several times to ignore parameters:

fscanf(fp, "%d %s %c %d %d %d %d %d %u %lu ...", &pid, &name, &ppid, &dummy, &dummy, &dummy, ...);

You can also look into strtok to read each line "token" by token. You can use it to create a function returning an array of char* like in this other question and get the i-th element (with all proper NULL and size checks).

Edit: If the file name contains spaces then you'll have to either use a regex or parse the string manually with e.g. strtok() to detect the proper format.

Annalist answered 3/1, 2016 at 11:47 Comment(4)
What happens if the stat file looks like this: 49102 (Name with space) S 3249 3506 3506 0 -1 1077936192 573 0 0 0 671 575 0 0 20 0 11 0 10835724 808615936 13699 18446744073709551615 4194304 8101684 140732335739408 140538183277872 140538250385161 0 4 4096 1260 1 0 0 -1 7 0 0 0 0 0 10201672 10213228 40337408 140732335748225 140732335748579 140732335748579 140732335751059 0 Here the name would be "(Name" and the following reading of fscanf would be incorrect.Fascia
@Fascia then it won't work. You'll have to resort to regex or manual parsing. I edited to make it clearer. Will that be enough to remove the downvote?Annalist
@txs, in that case you have to do something like this: "%*s (%*16[^)]) %s". I don't need the first value and the 2nd value in this case, I only need the third value as string. If you need those, just remove the * and assign proper variables...Ferromagnesian
Also note, the string itself can be more that 16 characters if that's a kernel process. The process can also be wrapped inside () without any `, like (sd-pam)` for example. So you need to match all the recursive ). This works: fscanf(f, "%*llu (%*[^)]%*[)] %c", _s) ; Again, this ignores the first 2 values for example. You can't reliably say the length of the 2nd field, because it's not limited to TASK_COMM_LEN for kernel space programs.Ferromagnesian

© 2022 - 2024 — McMap. All rights reserved.