From 7ca4171652dff239b35b1959bb7a32a2d066dca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Dejean?= Date: Mon, 10 Jan 2005 08:43:04 +0000 Subject: =?UTF-8?q?New=20feature=20by=20nick@reloco.com.ar=20(Nicol=C3=A1s?= =?UTF-8?q?=20Lichtmaier).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * configure.in: * examples/.cvsignore: * examples/Makefile.am: * examples/openfiles.c: (show_open_files), (main): * features.def: * include/glibtop/Makefile.am: * include/glibtop/command.h: * include/glibtop/procopenfiles.h: * include/glibtop/sysdeps.h: * include/glibtop/union.h: * structures.def: * sysdeps/linux/Makefile.am: * sysdeps/linux/procopenfiles.c: (glibtop_init_proc_open_files_s), (get_socket_endpoint), (glibtop_get_proc_open_files_s): * sysdeps/stub/Makefile.am: * sysdeps/stub/procopenfiles.c: (glibtop_init_proc_open_files_s), (glibtop_get_proc_open_files_s): New feature by nick@reloco.com.ar (Nicolás Lichtmaier). glibtop_get_open_files(pid) -> list of files by process. TODO: Add documentation. --- ChangeLog | 25 +++++++ configure.in | 2 +- examples/.cvsignore | 3 +- examples/Makefile.am | 11 ++- examples/openfiles.c | 64 +++++++++++++++++ features.def | 1 + include/glibtop/Makefile.am | 3 +- include/glibtop/command.h | 3 +- include/glibtop/procopenfiles.h | 116 +++++++++++++++++++++++++++++++ include/glibtop/sysdeps.h | 4 +- include/glibtop/union.h | 2 + structures.def | 1 + sysdeps/linux/Makefile.am | 2 +- sysdeps/linux/procopenfiles.c | 150 ++++++++++++++++++++++++++++++++++++++++ sysdeps/stub/Makefile.am | 2 +- sysdeps/stub/procopenfiles.c | 48 +++++++++++++ 16 files changed, 429 insertions(+), 8 deletions(-) create mode 100644 examples/openfiles.c create mode 100644 include/glibtop/procopenfiles.h create mode 100644 sysdeps/linux/procopenfiles.c create mode 100644 sysdeps/stub/procopenfiles.c diff --git a/ChangeLog b/ChangeLog index b5186838..3bfcd829 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2005-01-10 Benoît Dejean + + * configure.in: + * examples/.cvsignore: + * examples/Makefile.am: + * examples/openfiles.c: (show_open_files), (main): + * features.def: + * include/glibtop/Makefile.am: + * include/glibtop/command.h: + * include/glibtop/procopenfiles.h: + * include/glibtop/sysdeps.h: + * include/glibtop/union.h: + * structures.def: + * sysdeps/linux/Makefile.am: + * sysdeps/linux/procopenfiles.c: (glibtop_init_proc_open_files_s), + (get_socket_endpoint), (glibtop_get_proc_open_files_s): + * sysdeps/stub/Makefile.am: + * sysdeps/stub/procopenfiles.c: (glibtop_init_proc_open_files_s), + (glibtop_get_proc_open_files_s): + + New feature by nick@reloco.com.ar (Nicolás Lichtmaier). + + glibtop_get_open_files(pid) -> list of files by process. + TODO: Add documentation. + 2005-01-03 Benoît Dejean * examples/pprint.c: (pprint_get_cpu): diff --git a/configure.in b/configure.in index cf027731..67c91b53 100644 --- a/configure.in +++ b/configure.in @@ -122,7 +122,7 @@ else fi if test "x$enable_static" != xno; then - static_targets="first_static second_static mountlist_static procmap_static netload_static sysdeps_static timings_static $smp_static_examples pprint_static procargs_static df_static netlist netlist_static" + static_targets="first_static second_static mountlist_static procmap_static netload_static sysdeps_static timings_static $smp_static_examples pprint_static procargs_static df_static netlist netlist_static openfiles_static" else static_targets="" fi diff --git a/examples/.cvsignore b/examples/.cvsignore index f7ec2055..236bbd67 100644 --- a/examples/.cvsignore +++ b/examples/.cvsignore @@ -22,4 +22,5 @@ df df_static netlist netlist_static - +openfiles +openfiles_static diff --git a/examples/Makefile.am b/examples/Makefile.am index ab41a46c..a748f224 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -8,11 +8,12 @@ DEFS = @DEFS@ noinst_PROGRAMS = first second pprint procargs df netlist \ mountlist procmap netload sysdeps timings \ + openfiles \ @static_targets@ @smp_examples@ EXTRA_PROGRAMS = first_static second_static \ mountlist_static procmap_static \ - smp smp_static \ + smp smp_static openfiles_static \ netload_static sysdeps_static \ timings_static pprint_static procargs_static \ df_static netlist_static @@ -108,3 +109,11 @@ netlist_static_LDADD = $(netlist_LDADD) netlist_static_LDFLAGS = -static +openfiles_SOURCES = openfiles.c +openfiles_LDADD = $(top_builddir)/lib/libgtop-2.0.la + +openfiles_static_SOURCES = $(openfiles_SOURCES) +openfiles_static_LDADD = $(openfiles_LDADD) +openfiles_static_LDFLAGS = -static + + diff --git a/examples/openfiles.c b/examples/openfiles.c new file mode 100644 index 00000000..028c60dc --- /dev/null +++ b/examples/openfiles.c @@ -0,0 +1,64 @@ +#include +#include + +#include + +#include + +static void show_open_files(pid_t pid) +{ + glibtop_proc_open_files buf; + glibtop_open_files_entry *files; + unsigned i; + + files = glibtop_get_proc_open_files(&buf, pid); + + printf("<%ld>\n", (long)pid); + + for(i = 0; i < buf.number; ++i) + { + printf("\tfd = %d\t", files[i].fd); + + switch(files[i].type) + { + case GLIBTOP_FILE_TYPE_FILE: + printf("file \"%s\"\n", files[i].info.file.name); + break; + + case GLIBTOP_FILE_TYPE_PIPE: + printf("pipe\n"); + break; + + case GLIBTOP_FILE_TYPE_INETSOCKET: + printf("socket %s:%d\n", files[i].info.sock.dest_host, files[i].info.sock.dest_port); + break; + + case GLIBTOP_FILE_TYPE_LOCALSOCKET: + printf("localsocket\n"); + break; + } + } + + putchar('\n'); + + g_free(files); +} + + +int main(int argc, char **argv) +{ + glibtop_init(); + + show_open_files(getpid()); + + while(*++argv) + { + pid_t pid = strtol(*argv, NULL, 10); + show_open_files(pid); + } + + glibtop_close(); + + return 0; +} + diff --git a/features.def b/features.def index ea4d30e0..bb46c8d6 100644 --- a/features.def +++ b/features.def @@ -16,6 +16,7 @@ void|proc_kernel|ulong(k_flags,min_flt,maj_flt,cmin_flt,cmaj_flt,kstk_esp,kstk_e void|proc_segment|ulong(text_rss,shlib_rss,data_rss,stack_rss,dirty_size,start_code,end_code,start_stack)|pid_t(pid) char *|proc_args|ulong(size)|pid_t(pid):unsigned(max_len) glibtop_map_entry *|proc_map|ulong(number,size,total)|pid_t(pid) +glibtop_open_files_entry *|proc_open_files|ulong(number)|pid_t(pid) glibtop_mountentry *|@mountlist|ulong(number,size,total)|int(all_fs) void|@fsusage|ulong(blocks,bfree,bavail,files,ffree)|string|mount_dir void|netload|ulong(if_flags,mtu,subnet,address,packets_in,packets_out,packets_total,bytes_in,bytes_out,bytes_total,errors_in,errors_out,errors_total,collisions)|string|interface diff --git a/include/glibtop/Makefile.am b/include/glibtop/Makefile.am index ba0b59c6..8e4d36b2 100644 --- a/include/glibtop/Makefile.am +++ b/include/glibtop/Makefile.am @@ -7,4 +7,5 @@ glibtop_HEADERS = close.h loadavg.h prockernel.h procstate.h \ procsegment.h read.h sysdeps.h global.h \ procsignal.h read_data.h union.h types.h gnuserv.h \ parameter.h mountlist.h fsusage.h procmap.h signal.h \ - inodedb.h sysinfo.h ppp.h procargs.h netload.h netlist.h + inodedb.h sysinfo.h ppp.h procargs.h netload.h \ + netlist.h procopenfiles.h diff --git a/include/glibtop/command.h b/include/glibtop/command.h index aa940ddc..9ffef35f 100644 --- a/include/glibtop/command.h +++ b/include/glibtop/command.h @@ -58,8 +58,9 @@ G_BEGIN_DECLS #define GLIBTOP_CMND_NETLOAD 22 #define GLIBTOP_CMND_PPP 23 #define GLIBTOP_CMND_NETLIST 24 +#define GLIBTOP_CMND_PROC_OPEN_FILES 25 -#define GLIBTOP_MAX_CMND 25 +#define GLIBTOP_MAX_CMND 26 #define _GLIBTOP_PARAM_SIZE 16 diff --git a/include/glibtop/procopenfiles.h b/include/glibtop/procopenfiles.h new file mode 100644 index 00000000..29b2390c --- /dev/null +++ b/include/glibtop/procopenfiles.h @@ -0,0 +1,116 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + Copyright (C) 2004 Nicolás Lichtmaier + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + Modified by Nicolás Lichtmaier to give open process files. + + LibGTop is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + LibGTop is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_PROC_OPEN_FILES_H__ +#define __GLIBTOP_PROC_OPEN_FILES_H__ + +#include +#include + + +G_BEGIN_DECLS + +#define GLIBTOP_PROC_OPEN_FILES_NUMBER 0 +#define GLIBTOP_PROC_OPEN_FILES_TOTAL 1 +#define GLIBTOP_PROC_OPEN_FILES_SIZE 2 + +#define GLIBTOP_MAX_PROC_OPEN_FILES 3 + +#define GLIBTOP_FILE_ENTRY_FD 0 +#define GLIBTOP_FILE_ENTRY_NAME 1 +#define GLIBTOP_FILE_ENTRY_TYPE 2 +#define GLIBTOP_FILE_ENTRY_INETSOCKET_DST_HOST 3 +#define GLIBTOP_FILE_ENTRY_INETSOCKET_DST_PORT 4 + +#define GLIBTOP_MAX_OPEN_FILE_ENTRY 5 + +#define GLIBTOP_OPEN_FILENAME_LEN 215 + /* ready for IPv6 */ +#define GLIBTOP_OPEN_DEST_HOST_LEN 46 + +enum glibtop_file_type { + GLIBTOP_FILE_TYPE_FILE = 1, + GLIBTOP_FILE_TYPE_PIPE = 2, + GLIBTOP_FILE_TYPE_INETSOCKET = 4, + GLIBTOP_FILE_TYPE_LOCALSOCKET = 8 +}; + +typedef struct _glibtop_open_files_entry glibtop_open_files_entry; + +typedef struct _glibtop_proc_open_files glibtop_proc_open_files; + +struct _glibtop_open_files_entry +{ + int fd; + guint16 type; /* An "enum glibtop_file_type" value. */ + union { + /* When type == GLIBTOP_FILE_TYPE_INETSOCKET */ + struct { + char dest_host[GLIBTOP_OPEN_DEST_HOST_LEN+1]; + int dest_port; + } sock; + + /* When type == GLIBTOP_FILE_TYPE_FILE */ + struct { + char name[GLIBTOP_OPEN_FILENAME_LEN+1]; + } file; + } info; +}; + +struct _glibtop_proc_open_files +{ + guint64 flags, + number, /* GLIBTOP_PROC_OPEN_FILES_NUMBER */ + total, /* GLIBTOP_PROC_OPEN_FILES_TOTAL */ + size; /* GLIBTOP_PROC_OPEN_FILES_SIZE */ +}; + +#define glibtop_get_proc_open_files(proc_open_files,pid) glibtop_get_proc_open_files_l(glibtop_global_server, proc_open_files, pid) + +#if GLIBTOP_SUID_PROC_FILE +#define glibtop_get_proc_open_files_r glibtop_get_proc_open_files_p +#else +#define glibtop_get_proc_open_files_r glibtop_get_proc_open_files_s +#endif + +glibtop_open_files_entry * +glibtop_get_proc_open_files_l (glibtop *server, glibtop_proc_open_files *buf, pid_t pid); + +#if GLIBTOP_SUID_PROC_FILE +void glibtop_init_proc_open_files_p (glibtop *server); + +glibtop_open_files_entry * +glibtop_get_proc_open_files_p (glibtop *server, glibtop_proc_open_files *buf, pid_t pid); +#else +void glibtop_init_proc_open_files_s (glibtop *server); + +glibtop_open_files_entry * +glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf, pid_t pid); +#endif + +G_END_DECLS + +#endif diff --git a/include/glibtop/sysdeps.h b/include/glibtop/sysdeps.h index af490fd3..5547ccfd 100644 --- a/include/glibtop/sysdeps.h +++ b/include/glibtop/sysdeps.h @@ -52,8 +52,9 @@ G_BEGIN_DECLS #define GLIBTOP_SYSDEPS_NETLOAD 21 #define GLIBTOP_SYSDEPS_PPP 22 #define GLIBTOP_SYSDEPS_NETLIST 23 +#define GLIBTOP_SYSDEPS_PROC_OPEN_FILES 24 -#define GLIBTOP_MAX_SYSDEPS 24 +#define GLIBTOP_MAX_SYSDEPS 25 #define GLIBTOP_SYSDEPS_ALL ((1 << GLIBTOP_MAX_SYSDEPS) - 1) @@ -85,6 +86,7 @@ struct _glibtop_sysdeps proc_segment, /* glibtop_proc_segment */ proc_args, /* glibtop_proc_args */ proc_map, /* glibtop_proc_map */ + proc_open_files, /* glibtop_proc_open_files */ mountlist, /* glibtop_mountlist */ fsusage, /* glibtop_fsusage */ netlist, /* glibtop_netlist */ diff --git a/include/glibtop/union.h b/include/glibtop/union.h index ed462468..1fc628dc 100644 --- a/include/glibtop/union.h +++ b/include/glibtop/union.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -80,6 +81,7 @@ union _glibtop_union glibtop_netlist netlist; glibtop_netload netload; glibtop_ppp ppp; + glibtop_proc_open_files proc_open_files; }; G_END_DECLS diff --git a/structures.def b/structures.def index ca8cecf1..0f2440f9 100644 --- a/structures.def +++ b/structures.def @@ -1,4 +1,5 @@ glibtop_map_entry|ulong(flags,start,end,offset,perm,inode,device):string(filename) +glibtop_open_file_entry|ulong(flags,fd,type,dest_port):string(filename,dest_host) glibtop_mountentry|ulong(dev):string(devname,mountdir,type) glibtop_sysdeps|ulong(features,pointer_size,cpu,mem,swap,uptime,loadavg,shm_limits,msg_limits,sem_limits,proclist,proc_state,proc_uid,proc_mem,proc_time,proc_signal,proc_kernel,proc_segment,proc_args,proc_map,mountlist,fsusage,interface_names,netlist,netload,ppp) diff --git a/sysdeps/linux/Makefile.am b/sysdeps/linux/Makefile.am index e5bf626a..65ac37e6 100644 --- a/sysdeps/linux/Makefile.am +++ b/sysdeps/linux/Makefile.am @@ -8,7 +8,7 @@ libgtop_sysdeps_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \ proctime.c procmem.c procsignal.c prockernel.c \ procsegment.c procargs.c procmap.c siglist.c \ sysinfo.c netload.c ppp.c glibtop_private.c \ - fsusage.c netlist.c + fsusage.c netlist.c procopenfiles.c libgtop_sysdeps_2_0_la_LIBADD = @GLIB_LIBS@ diff --git a/sysdeps/linux/procopenfiles.c b/sysdeps/linux/procopenfiles.c new file mode 100644 index 00000000..5286afdc --- /dev/null +++ b/sysdeps/linux/procopenfiles.c @@ -0,0 +1,150 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + Copyright (C) 2004 Nicolás Lichtmaier + This file is part of LibGTop 1.0. + + Modified by Nicolás Lichtmaier to give a process open files. + + Contributed by Martin Baulig , April 1998. + + LibGTop is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + LibGTop is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + + +static const unsigned long _glibtop_sysdeps_proc_open_files = +(1L << GLIBTOP_PROC_OPEN_FILES_NUMBER)| +(1L << GLIBTOP_PROC_OPEN_FILES_TOTAL)| +(1L << GLIBTOP_PROC_OPEN_FILES_SIZE); + +/* Init function. */ + +void +glibtop_init_proc_open_files_s (glibtop *server) +{ + server->sysdeps.proc_open_files = _glibtop_sysdeps_proc_open_files; +} + + +static void +get_socket_endpoint(char *buf, int *prmtport, int s) +{ + FILE *f; + char l[1024]; + + buf[0] = '\0'; + prmtport = 0; + + f = fopen("/proc/net/tcp", "r"); + + if(!f) + return; + + while(fgets(l, sizeof l, f)) + { + unsigned int loc, locport, rmt; + int sock = -1; + sscanf(l, " %*d: %8x:%4x %8x:%4x %*d %*x:%*x %*x:%*x %*d %*d %*d %d", + &loc, &locport, &rmt, prmtport, &sock); + if(sock == s) + { + inet_ntop(AF_INET, &rmt, buf, INET_ADDRSTRLEN); + break; + } + } + + fclose(f); +} + +/* Provides detailed information about a process' open files */ + +glibtop_open_files_entry * +glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf, pid_t pid) +{ + char fn [BUFSIZ]; + GArray *entries; + struct dirent *direntry; + int rv; + DIR *dir; + + glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_OPEN_FILES, 0); + + memset (buf, 0, sizeof (glibtop_proc_open_files)); + + sprintf (fn, "/proc/%d/fd", pid); + + dir = opendir (fn); + if (!dir) return NULL; + + entries = g_array_new(FALSE, FALSE, sizeof(glibtop_open_files_entry)); + + while((direntry = readdir(dir))) { + char tgt [BUFSIZ]; + glibtop_open_files_entry entry = {0}; + + if(direntry->d_name[0] == '.') + continue; + + sprintf(fn, "/proc/%d/fd/%s", pid, direntry->d_name); + rv = readlink(fn, tgt, sizeof(tgt) - 1); + + if(rv < 0) + continue; + + tgt[rv] = '\0'; + + entry.fd = atoi(direntry->d_name); + + if(g_str_has_prefix(tgt, "socket:[")) + { + int sockfd; + entry.type = GLIBTOP_FILE_TYPE_INETSOCKET; + sockfd = atoi(tgt + 8); + get_socket_endpoint(entry.info.sock.dest_host, + &(entry.info.sock.dest_port), + sockfd); + } + else if(g_str_has_prefix(tgt, "pipe:[")) + { + entry.type = GLIBTOP_FILE_TYPE_PIPE; + } + else + { + entry.type = GLIBTOP_FILE_TYPE_FILE; + g_strlcpy(entry.info.file.name, tgt, sizeof entry.info.file.name); + } + + g_array_append_val(entries, entry); + } + + closedir (dir); + + buf->flags = _glibtop_sysdeps_proc_open_files; + buf->number = entries->len; + buf->size = sizeof(glibtop_open_files_entry); + buf->total = buf->number * buf->size; + + return (glibtop_open_files_entry*)g_array_free(entries, FALSE); +} diff --git a/sysdeps/stub/Makefile.am b/sysdeps/stub/Makefile.am index 8f053e45..24fa7412 100644 --- a/sysdeps/stub/Makefile.am +++ b/sysdeps/stub/Makefile.am @@ -8,7 +8,7 @@ libgtop_sysdeps_2_0_la_SOURCES = open.c close.c siglist.c cpu.c mem.c swap.c \ sem_limits.c proclist.c procstate.c procuid.c \ proctime.c procmem.c procsignal.c prockernel.c \ procsegment.c procargs.c procmap.c netload.c \ - ppp.c netlist.c + ppp.c netlist.c procopenfiles.c libgtop_sysdeps_2_0_la_LDFLAGS = $(LT_VERSION_INFO) diff --git a/sysdeps/stub/procopenfiles.c b/sysdeps/stub/procopenfiles.c new file mode 100644 index 00000000..be968c52 --- /dev/null +++ b/sysdeps/stub/procopenfiles.c @@ -0,0 +1,48 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + Copyright (C) 2004 Nicolás Lichtmaier + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + LibGTop is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + + +#include +#include +#include + +/* Init function. */ + +void +glibtop_init_proc_open_files_s (glibtop *server) +{ + server->sysdeps.proc_open_files = 0; +} + +/* Provides detailed information about a process. */ + +glibtop_open_file_entry * +glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf, pid_t pid) +{ + glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_MAP, 0); + + memset (buf, 0, sizeof (glibtop_proc_open_files)); + + return NULL; +} -- cgit v1.2.1