home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/wish -f
- #
- # Process Lister -- list processes, signal them
- #
- #Hacked by GuestToo and BK, for Puppy Linux, www.puppylinux.org
-
-
- # initial values for menu options
- set user $env(LOGNAME)
- set signal -9
- # ...have changed this from -2
-
- option add *borderWidth 1
-
- #
- # Get the selected line(s) from the list-box,
- # extract the pid, signal the process
- #
- proc kill_proc {} {
- global signal
-
- #
- # Get the list of selected line numbers.
- # If the list is empty, nothing is selected, so return
- #
- set sellist [.ps.list curselection]
- if {[llength $sellist] == 0} {
- return
- }
-
- #
- # For each entry in the selected-lines-list,
- # get the line, extract the pid, append to a list of PID's
- # (optional: filter out critical processes that shouldn't be touched)
- #
- foreach index $sellist {
- set line [.ps.list get $index]
- set pid ""
- scan $line "%s %d" uid pid
- if {$pid == ""} {
- scan $line "%d" pid
- if {$pid == ""} {
- continue
- }
- }
-
- # Use this to skip over protected processes:
- # if {[string match "*precious*" $line]} {
- # err "$line\n\nMust not kill this process!"
- # continue
- # }
-
- lappend pid_list $pid
- }
-
- #
- # Construct a "kill" command line,
- # execute it and get the error return
- #
- set cmd [list exec kill $signal $pid_list]
- set ret [catch $cmd err]
-
- #
- # If there was a problem signalling a process,
- # let the user know
- #
- if {$ret == 1} {
- msg "Could not kill a process;\nit's already gone?"
- return
- }
-
- #
- # Refresh the process list
- #
- scan_proc
- }
-
- #
- # Do a "ps", collect the output, put into a list-box
- #
- proc scan_proc {} {
- set cmd "|ps"
- #
- # Sort the output (by names or PIDs)
- #
- append cmd " | sort -n "
-
- #
- # Evaluate the command line
- # Get the resulting list of lines
- # Fill the list-box with the lines
- # Be careful to retain our position in the listbox!
- #
- set fid [open $cmd r]
- if {$fid != 0} {
- # save original position
- set sel [lindex [.ps.list curselection] 0]
- set top [.ps.list nearest 1]
-
- # clear contents, refill it
- .ps.list delete 0 end
- while {[gets $fid line] > 0} {
- .ps.list insert end $line
- }
- catch {close $fid}
-
- # restore listbox position
- if {$sel != ""} {
- .ps.list selection set $sel
- .ps.list activate $sel
- }
- .ps.list yview $top
- } {
- err "Cannot run command\n$cmd"
- return
- }
- }
-
- #
-
- #
-
- proc err { msg } {
- tk_dialog .err "Error!" $msg error 0 OK
- }
-
- proc msg { msg } {
- tk_dialog .msg "Message:" $msg info 0 OK
- }
-
- proc ask_yn { msg } {
- return [tk_dialog .ask "Question:" "$msg" question 0 Yes No]
- }
-
- #
- # Make a listbox and scrollbar, glue them together,
- # add some keyboard controls
- #
- proc list_box {w {action ""}} {
- if {[winfo exists $w] == 0} {
- frame $w
- }
- scrollbar $w.sb -command "$w.list yview"
- listbox $w.list -yscroll "$w.sb set" \
- -font fixed -setgrid 1 -width 81 -height 10
- pack $w.sb -side right -fill y
- pack $w.list -side left -fill both -expand yes
- if {$action != ""} {
- bind $w.list <Double-1> $action
- bind $w.list <Return> $action
- }
- bind $w.list <Control-p> {tkListboxUpDown %W -1}
- bind $w.list <Control-n> {tkListboxUpDown %W 1}
- bind $w.list <k> {tkListboxUpDown %W -1}
- bind $w.list <j> {tkListboxUpDown %W 1}
- bind $w <Any-Enter> "focus $w.list"
- }
-
- #
- # Make a menubar with menus
- #
- proc menu_bar {w args} {
- if {[winfo exists $w] == 0} {
- frame $w -relief raised
- }
- set mnum 0 ;# menu counter
- set inum 0 ;# item counter
-
- foreach arg $args {
- foreach {type name var val v2} $arg { }
-
- if {$inum == 0 && [string match "menu*" $type] == 0} {
- err "menu_bar: need menu to hold $type/$name menu-item"
- return
- }
-
- switch $type {
- menu {
- set mbase $w.m[incr mnum]
- set new $mbase.menu
- menubutton $mbase -text $name -menu $new
- menu $new -disabledforeground DarkBlue
- set inum 1
- }
-
- sep {
- $new add sep
- }
-
- label {
- $new add command -label $name -state disabled
- incr inum
- }
-
- cmd {
- $new add command -label $name -command $var
- incr inum
- }
-
- radio {
- global $var
- $new add radiobutton -label $name \
- -variable $var -value $val
- incr inum
- }
-
- check {
- global $var
- $new add checkbutton -label $name \
- -variable $var -offvalue $val -onvalue $v2
- incr inum
- }
-
- end {
- # pack this menu on the given side
- pack $mbase -side $name -padx 1m
- set inum 0
- }
-
- default {
- err "menu_bar: unknown type '$type' for '$name'"
- return
- }
-
- }
- }
- }
-
-
- #
- # Make a button row from some button names and commands
- #
- proc buttons {w args} {
- if {[winfo exists $w] == 0} {
- frame $w
- }
- set i 0
- set btns ""
- foreach arg $args {
- foreach {name cmd} $arg { }
- set btn $w.b[incr i]
- append btns " $btn"
- button $btn -text $name -command $cmd
-
- }
- eval pack $btns -side left -fill x -expand yes
- }
-
-
- #
- # Make the main control panel -- fill it with some controls
- #
- proc make_control_panel { } {
- global user
- wm title . "Process Lister"
- wm iconname . "PL"
- wm command . "PL"
-
- menu_bar .mbar \
- {menu File} \
- {cmd Quit exit} \
- {end left} \
- \
- {menu Signals} \
- {radio " 1 Hangup" signal -1} \
- {radio " 2 Interrupt" signal -2} \
- {radio " 3 Quit" signal -3} \
- {radio " 9 Kill" signal -9} \
- {radio "14 Alarm" signal -14} \
- {radio "15 Terminate" signal -15} \
- {radio "23 Stop" signal -23} \
- {radio "24 Term. Stop" signal -24} \
- {radio "25 Continue" signal -25} \
- {end left}
-
- list_box .ps kill_proc
-
- buttons .cmd \
- {Scan scan_proc} \
- {Kill kill_proc} \
- {Quit exit}
-
- # pack menu -> top
- # pack btns -> on the bottom
- # pack scroll-box -> in the middle
-
- pack .mbar -side top -fill x
- pack .cmd -side bottom -fill x
- pack .ps -side top -fill both -expand yes
- }
-
-
- #
- # Read user's settings, make the interface
- #
- make_control_panel
- update
- scan_proc
-
- #
- # Stub routine to get a new process listing
- # (called from Tcl 'trace', setup below)
- #
- proc do_new_scan {n1 n2 op} {
- scan_proc
- }
-