0

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 ?

shunjie
  • 3
  • 1
  • 4

2 Answers2

0

assuming Linux, I think you've got to go into /proc/*/fd and poke around

Jasen
  • 11,837
  • 2
  • 30
  • 48
  • Hi , thanks for the advice. There are indeed information regarding this. Is it possible to do it in c code via the libraries without accessing any files on the system. I am hoping to achieved the a reasonable good performance. Thanks again ! – shunjie Jun 16 '13 at 15:44
  • You are asking for information that belongs to the OS Kernel, and that there isn't really a properly standardized method of introspecting. There's no syscall, as far as I know, to request the PID of a socket, port, or listener. However, on Linux (and some other operating systems) the kernel makes various pieces of internal information (such as the process table) available by representing the data as a virtual file system under the `/proc` directory. If you want this information, you need to access it the way the kernel presents it. (Alternatively, you could look into the `lsof` tool.) – This isn't my real name Jun 17 '13 at 04:12
0

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:*.

alk
  • 69,737
  • 10
  • 105
  • 255
  • I guess I shall try out netstat's method as indicated in its sources using PROCPS tools or just code it up myself. Since /proc reside in ram, I think it should be alright. Thanks again ! – shunjie Jun 17 '13 at 15:37