I am new to C network programming. I am trying to code a patch for my conky to display something like "netstat -pan --inet". Conky's inbuilt tcp_mon to not include process name.
Initially I did this using netstat and awk but my script got a performance hit using this approach. So I am trying to code it in C directly. The output from netstat looks something like this
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:17500 0.0.0.0:* LISTEN 1042/dropbox
tcp 0 0 192.168.0.1:3333 24.244.4.104:2222 ESTABLISHED 1225/chrome
I am interested in displaying the last column "PID/Program" I look at the sockets library but I did not come across anything regarding the process name or its pid. I am on Archlinux by the way
So my questions are 1) Am I looking at the right place ? If not, where ? 2) Is there a better way of doing this ?
At least when using a recent Linux kernel it is possible to read out a process' name (as defined by a comment to the OP) using prctl()
:
#include <sys/prctl.h>
#include <stdio.h> /* for perror() */
...
char [17] = proc_name = {0}; /* the buffer provided shall at least be 16+1 bytes long */
if (-1 == prctl(PR_GET_NAME, proc_name, ...))
perror("prctl(PR_GET_NAME, ...)");
One should be aware that a maximum of 16 bytes is returned, and that in this case no trailing 0
-termination will be added. So initialising the character array to passed to prctl()
to all 0
is a good idea.
It is also possible to set this "name" by doing:
char [17] = proc_name = "new name"; /* The name will be truncated to 16 bytes */
if (-1 == prctl(PR_SET_NAME, proc_name, ...))
perror("prctl(PR_SET_NAME, ...)");
The relevant excerpts from prctl()
's man pages are:
PR_SET_NAME (since Linux 2.6.9)
Set the process name for the calling process, using the value in the location pointed to by (char *) arg2. The name can be up to 16 bytes long, and should be null-terminated if it contains fewer bytes.
PR_GET_NAME (since Linux 2.6.11)
Return the process name for the calling process, in the buffer pointed to by (char *) arg2. The buffer should allow space for up to 16 bytes; the returned string will be null-terminated if it is shorter than that.
Please note that the "process name"-value as described above is different form the command line for a process. The latter can be found in /proc/<pid>/cmdline
.
It is stored in there as 0
-terminated character array.
A convenient way to read out /proc
is to use the tool kit provided by PROCPS.
Update:
After taking a look at netstat
's sources it seem it takes the process's name from /proc/<pid>/cmdline
. The relevant pids come from scanning /proc/<pid>/fd
looking for matches to socket:*
.