#!/usr/bin/perl -w # # 2001-12-13 Jean Delvare # Released under the GNU General Public License. # # Uses lsof to answer questions such as "What libraries are used by this # process?" or "What processes are currently using this library?". # # You must edit the definition of LIBEXT below if your system's dynamic # libs aren't named .so. # # Usage: # > libuse # Shows a sorted list of processes using each library. # > libuse /somewhere/lib/libsome-1.2.so.0 # Shows a sorted list of processes using this given library. # > libuse xmms # Shows a sorted list of libraries used by xmms (an impressive number indeed.) # # 2002-01-22 Jean Delvare # Improved flexibility. You don't have to give the full path to libraries # anymore. Thanks Yannick for the suggestion. # Also added a fix for truncated binary names (lsof will cut them to 9 # characters.) # For regular ELF systems: use constant LIBEXT => qr(\.so); # For HP-UX and friends: #use constant LIBEXT => qr(\.sl); # Width of the binary name column in lsof. use constant BINWIDTH => 9; ## ## Don't change anything below this line. ## use strict; use vars qw (%uses); # Get all the uses (that is, links between a program and a lib). They go in a # hashtable.Each value is a column-separated and -beginning list. open(LSOF,'lsof|') || die 'First install lsof'; while() { my @item=split; if($item[-1] =~ LIBEXT) { $uses{$item[-1]}.=":$item[0]"; } } close(LSOF); if(defined($ARGV[0])) { # Look for all libraries used by a process. my %l=(); foreach my $b (keys %uses) { my @x=split(/:/,$uses{$b}); shift(@x); foreach my $c (@x) { if($c eq substr($ARGV[0],0,BINWIDTH)) { $l{$b}++ }; } } if(scalar(keys %l)) { printf("$ARGV[0] is using \%u different librar\%s:\n",scalar(keys %l),(scalar(keys %l)>1?'ies':'y')); foreach my $c (sort keys %l) { print(" ($l{$c}) $c\n"); } } } # Look for all processes using one or all libraries foreach my $b (sort keys %uses) { my @bx=split(/\//,$b); if(!defined($ARGV[0])||($b eq $ARGV[0])||index($bx[-1],$ARGV[0])!=-1) { my @x=split(/:/,$uses{$b}); shift(@x); my %dv=(); my @ux=grep { ! $dv{$_} ++ } @x; printf("$b is used by \%u different process\%s:\n",scalar(@ux),(scalar(@ux)>1?'es':'')); foreach my $c (sort @ux) { print(" ($dv{$c}) $c\n"); } } }