Re: oaf-slay improvements



Brian Cameron <Brian Cameron sun com> writes:

> I have made a number of updates to oaf-slay to make it run more
> efficiently.
> 
> 1. It checks the user's processes and only kills the processes that
>    need killing.  This makes oaf-slay run very quickly rather than
>    using pkill which is very slow...especially on multi-user
>    server machines.
> 2. Added the "-l" option to display the processes without killing
>    them and the "-s" to turn on a "silent" mode.
> 3. Made the script a little more robust, and added more documentation
>    in the comments.
>    
> Enjoy, and let me know if it is useful.  Please cc: any response to
> me personally since I am not on this mailing list.

Hi Brian,

This looks like a good improvement. It would be great if you could
address the two portability issues Dan mentioned and then check this
in. (One better way to call whoami might be 

$username = `PATH=/usr/ucb:${PATH} whoami`;

Then you can skip all the uname checking. I'm not sure how to handle
the ps stuff portably. Dan, didn't OCL at MIT have some script with
code to do that?

 - Maciej

> 
> Brian
> #!/usr/bin/perl
> # 
> # oaf-slay
> # 
> # Kills OAF processes
> #
> # Return code of -1 (255) returned if usage error.
> # Return code of 1 indicates oaf processes were running
> #   when script was run.  
> # Return code of 0 indicates no oaf processes were
> #   running when script was run.
> #
> use             Getopt::Std;
> 
> $usage_error = 0;
> 
> # Handle input arguments
> #
> $rc = getopts('lsh');
> 
> # Usage errors
> #
> if ($rc != 1) {
>    $usage_error = 1;
> }
> 
> if ($opt_l && $opt_s) {
>    $usage_error = 1;
> }
> 
> # Print usage if necessary.
> #
> if ($usage_error == 1 || $opt_h) {
> 	print "\n";
> 	print "Usage : oaf-slay [-hls]\n";
> 	print "\tKill OAF processes still running.\n";
> 	print "\t -h Print this help message.\n";
> 	print "\t -l List processes running, but do not kill them.  Not valid with -s\n";
> 	print "\t -s Silent.  Kill processes quietly\n";
> 	print "\n";
> 	exit(-1);
> }
> 
> # Build ps command.
> #
> $uname = (`/bin/uname`)[0];
> chomp($uname);
> if ($uname eq "SunOS") {
> 	$username = `/usr/ucb/whoami`;
> } else {
> 	$username = `/usr/bin/whoami`;
> }
> 
> chomp($username);
> $ps_cmd = "/bin/ps -e -opid,user,args | /bin/grep ".$username;
> 
> # get OAF files
> #
> @path = split(':', $ENV{'PATH'});
> 
> foreach $dir (@path) {
> 	if (-f "$dir/oafd") {
> 		$ins_dir  = `/usr/bin/dirname $dir`;
> 		chomp $ins_dir;
> 		$oaf_dir  = $ins_dir . "/share/oaf";
> 		last;
> 	}
> }
> 
> chdir($oaf_dir);
> opendir(DIR, $oaf_dir) || die "\nCan not open directory $oaf_dir\n\t$!\n\n";
> @oaf_files = readdir(DIR);
> closedir DIR;
> 
> # Initialize variables
> #
> $process_exists = 0;
> $first_time     = 1;
> 
> # Loop until no more processes are found.  This typically loops only once,
> # but if an OAF process is launched while this script is running an OAF
> # process can be left behind and be caught on the second loop, etc.
> #
> do {
> 	# Initialize variables.
> 	#
> 	@files        = @oaf_files;
> 	@list_array   = ();
> 	@process_pids = ();
> 	@file_process = ();
> 	$index        = 0;
> 
> 	# Get process list.
> 	#
> 	@ps_result    = `$ps_cmd`;
> 
> 	# Loop through files, and see if any OAF processes are running.  If
> 	# so, then build the @list_array and @process_pids arrays.
> 	# @list_array contains the process names
> 	# @process_pids contains the process IDs
> 	#
> 	while ($fname = shift(@files)) {
> 
> 		if ("$fname" =~ /\.oaf$/) {
> 		
> 			open(FILE, $fname);
> 			while (<FILE>) {
> 
> 				$line = $_;
> 				if  ($line =~m/location[ \t]*\=/ && 
> 				   !($line =~m/type=\"shlib\"/)) {
> 	
> 					$line =~s/.*location[ \t]*\="//;
> 					$line =~s/".*//;
> 					chomp($line);
> 					$line =~s/\.\///;
> 
> 					# oafd needs to be last.
> 					#
> 					if ($line ne "oafd") {
> 						push @file_process, $line;
> 					}
> 				} #end while(<FILE>)
> 			}
> 			close(FILE);
> 		}
> 	}
> 
> 	# Add oafd so that it is last.
> 	#
>  	push @file_process, "oafd"; 
> 
> 	foreach $filep (@file_process) {
> 
> 		if (not($filep =~m/^OAFIID:/)) {
> 
> 			# Search through @ps_result and look for matches
> 			#
> 			foreach $el (@ps_result) {
> 				chomp $el;
> 				if ($el =~m/$filep/ ) {
> 					@ps_array = split(' ', $el);
> 					$list_array[$index]=$ps_array[0]."\t".$ps_array[2]."\n";
> 					$process_pids[$index]=$ps_array[0]."\n";
> 					$index++;
> 					}
> 				}
> 			}
> 		}
> 
> 	# Do the killing.
> 	#
> 	if ($#list_array != -1) {
> 
> 		# Print output if -s (silent) argument is not specified.
> 		#
> 		if(!$opt_s) {
> 			if ($first_time == 1) {
> 				print "\n";
> 				print "The following processes are still running on the system.\n";
> 
> 				if (!$opt_l) {
> 					print "These processes will be terminated.\n";
> 
> 					print "\n";
> 					print "NOTE:  Killing these processes may affect other applications\n";
> 					print "on the system that use OAF and bonobo.\n"; 
> 				}
> 				print "\n";
> 				$first_time = 0;
> 			} else {
> 				# Just some feedback to indicate it had to loop...
> 				#
> 				print "...and...\n";
> 			}
> 
> 			# Print list of processes...
> 			#
> 			print @list_array;
> 			print "\n";
> 		}
> 
> 		# Kill if the -l argument is specified.
> 		#
> 		if(!$opt_l) {
> 			$killall = "/bin/kill";
> 			$kill_params = ' -9 ';
> 			foreach $proc (@process_pids) {
> 				chomp $proc;
> 				if($proc =~m/\d+/) {
> 					$cmd = $killall.$kill_params.$proc." 2>/dev/null";
> 					system($cmd);
> 				}
> 			}	
> 		}
> 		$process_exists = 1;
> 	}
> 
> # Only loop once if opt_l is used, otherwise loop until
> # no more processes are killed
> #
> } while ($#list_array != -1 && !opt_l);
>  
> # Exit
> #
> if ($process_exists == 0) {
> 
> 	# Show feedback if -l argument is used
> 	#
> 	if ($opt_l) {
> 		print "\n";
> 		print "No processes.\n";
> 		print "\n";
> 	}
> 	exit 1;
> } else {
> 	exit 0;
> }
> 

-- 
Maciej Stachowiak
Eazel, Inc.




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]