Patch title: Release 94 bulk changes
Abstract:
File: /pliant/fullpliant/logical.pli
Key:
    Removed line
    Added line
module "/pliant/language/compiler.pli"
module "/pliant/language/stream.pli"
module "/pliant/admin/file.pli"
module "this_computer.pli"
module "/pliant/protocol/dns/name.pli"
module "/pliant/admin/execute.pli"
module "/pliant/linux/schedule/process.pli"
module "/pliant/language/schedule/daemon.pli"
module "/pliant/linux/storage/filesystem.pli"

public

function lc_root id -> r
  arg Str id r
  r := this_computer:env:"logical":id:"root"
  if r=""
    r := "file:/logical/"+id+"/"

function lc_user id -> u
  arg Str id ; arg Int u
  if not (this_computer:env:"logical":id:"user" parse u)
    u := 1

function lc_group id -> g
  arg Str id ; arg Int g
  if not (this_computer:env:"logical":id:"group" parse g)
    g := 1

function lc_http_port id -> p
  arg Str id ; arg Int p
  p := name_database:data:host:id:http_port

function lc_remote_port id -> p
  arg Str id ; arg Int p
  p := name_database:data:host:id:remote_port

function lc_start id
  arg Str id
  var Str pre := " module /pliant/install/minimal.pli"
  if this_computer:env:"logical":id:"precompile"="true"
    pre := " 'precompile /binary/default.dump module /pliant/install/precompile.pli'"
  if this_computer:env:"logical":id:"cooped"="false"
    execute id+" root "+(file_os_name lc_root:id)+"pliant/"+pre+" module /pliant/fullpliant/run.pli" path lc_root:id+"bin/" user lc_user:id group lc_group:id detached
  else
    if lc_user:id=0
      file_tree_copy "file:/lib/modules/" lc_root:id+"lib/modules/"
      if (file_query lc_root:id+"proc/modules" standard)=undefined
        filesystem_mount "file:proc" lc_root:id+"proc" "filesystem [dq]proc[dq]"
    execute id+pre+" module /pliant/fullpliant/run.pli" root lc_root:id path lc_root:id+"bin/" user lc_user:id group lc_group:id detached

function lc_stop id
  arg Str id
  process_kill id ""

function lc_is_running id -> c
  arg Str id ; arg CBool c
  c := process_pid:id=defined

function lc_memory id -> mem
  arg Str id ; arg Intn mem
  var Int pid := process_pid id
  if pid=undefined
    mem := undefined
  else
    mem := undefined
    (var Stream s) open "file:/proc/"+string:pid+"/status" in+safe
    while not s:atend
      if (s:readline parse "VmRSS" ":" (var Int kb) "kB")
        mem := kb*2n^10

function lc_cpu id -> cpu
  arg Str id ; arg Float cpu
  if not (this_computer:env:"logical":id:"user" parse (var Int user))
    return undefined
  cpu := 0
  var Array:FileInfo files := file_list "file:/proc/" standard+directories
  for (var Int i) 0 files:size-1
    if (files:i:name parse "file:/proc/" (var Int pid) "/")
      (var Stream s) open files:i:name+"status" in+safe
      var Int uid := undefined ; var CBool running := false # var Int sleepavg := 100
      while not s:atend
        var Str l := s readline
        l parse "Uid" ":" uid any
        if (l parse "State" ":" "R" any)
          running := true
        # l parse "SleepAVG" ":" sleepavg any
      if uid=user
        if running
          cpu += 1
        # cpu += (100-sleepavg)/100

daemon "restart logical computers"
  daemon_sleep 120
  while not daemon_emergency
    each logical this_computer:env:"logical"
      if logical:"automatic"="true"
        if not (lc_is_running keyof:logical)
          lc_start keyof:logical
    daemon_sleep 15