MetaCard Corporation

Listings for MetaCard "top" application


------------------------------------------------------------------
Listing 1.  card script
------------------------------------------------------------------

local lasttimes, timerid

on updatelist
  local procstat, newtotaltime, totaltime, procs, procid, procpath
  local newtime, percenttime, toplist

# let the user know we're working
  set the cursor to watch
  put readfile("/proc/stat") into procstat
# compute total user, system, and idle time
  put word 2 of procstat + word 3 of procstat + word 4 \
      of procstat + word 5 of procstat into newtotaltime
# the first time through, totaltime is 0, so prevent divide by 0
  put max(1, newtotaltime - lasttimes["total"]) into totaltime
  put newtotaltime into lasttimes["total"]
# get a list of directories along with the owner of each
  put shell("ls -l /proc") into procs
  delete line 1 of procs # delete "total" line
  repeat for each line l in procs
    put the last word of l into procid
    if procid is not a number then next repeat
# build up path by concatenating id and a trailing "/"
    put "/proc/" & procid & "/" into procpath
    put readfile(procpath & "stat") into procstat
    if procstat is empty then next repeat # no file
    put word 14 of procstat + word 15 of procstat into newtime
    put (newtime - lasttimes[procid]) / totaltime * 100\
         into percenttime
# store time into associative array by proc id
    put newtime into lasttimes[procid]
# format one line of output using format (like C printf)
    put format("%5s %-10s %5d %5d %4d %s\n", word 1 of procstat,
               word 3 of l, word 23 of procstat div 1024,
               word 24 of procstat * 4, percenttime,\
               readfile(procpath & "cmdline")) after toplist
  end repeat
  delete last char of toplist # get rid of trailing newline
# double sort sorts by process size and then by CPU usage
  sort lines of toplist numeric by word 4 of each
  sort lines of toplist descending numeric by word 5 of each
  put toplist into field "toplist"
# set up a call back in a few seconds
  send "updatelist" to me in (the updateinterval of me) seconds
  put the result into timerid
  disable button "Kill Process"
  set the cursor to hand
end updatelist

------------------------------------------------------------------
Listing 2.  readfile function
------------------------------------------------------------------

function readfile which
  local zeroLoc
  open file which for read
  if the result is not empty
  then return empty      # file wasn't there!
  read from file which until empty
  close file which
# find any 0 bytes and convert them to spaces
# the offset function returns 0 if not found
  put offset(numToChar(0), it) into zeroLoc
  repeat until zeroLoc is 0
    put space into char zeroLoc of it
    put offset(numToChar(0), it) into zeroLoc
  end repeat
  return it
end readfile

------------------------------------------------------------------
Listing 3. mouseUp handler
------------------------------------------------------------------

on mouseUp
  switch the short name of the target
  case "Kill Process"
    kill process word 1 of the selectedText\
         of field "toplist"
    updatelist
    break
  case "Set Update Interval..."
    ask "Set update interval to:"\
         with the updateinterval of me
    if it is not a number then
      answer "Interval must be a number."
    else
      set the updateinterval of me to it
      cancel timerId
      updatelist
    end if
    break
  case "Close"
    close this stack
    break
  case "toplist"
    enable button "Kill Process"
    cancel timerId
    send "updatelist" to me in 5 seconds
    put the result into timerid
    break
  end switch
end mouseUp

------------------------------------------------------------------
Listing 4. stack message handlers
------------------------------------------------------------------

on openStack
  updatelist
end openStack

on closeStack
  cancel timerid
end closeStack

on iconifyStack
  cancel timerid
end iconifyStack

on unIconifyStack
  updatelist
end unIconifyStack

on resizeStack
  set the height of field "toplist"\
       to the height of this card - 80
  repeat with i = 1 to the number of buttons
    set the bottom of button i \
       to the height of this card - 8
  end repeat
end resizeStack

--------------------------------------------------------------------
[Footnote 1] 
--------------------------------------------------------------------

Note to Java programmers: many of the event names in Java were
borrowed from HyperTalk, and not the other way around.
Back to "top" article