REPORT ZCPUTREE LINE-SIZE 255 NO STANDARD PAGE HEADING.
************************************************************************
* This program displays the UNIX process table as a tree. A click
* on a node (process) will expand the tree and display it's children
* processes. Along with the processes names the process id, owner
* and consumed CPU time is displayed as well. The heart of the program
* is the FIND_CHILD recursive function module, that creates the
* parent/child tree based upon the pid and ppid
************************************************************************
DATA: L(255), F15 TYPE C, LIN TYPE I, LEVEL TYPE I VALUE 2,
BEGIN OF A,
   1(6), 2(6), 3(50), 4(6), 5(6),
END OF A,
BEGIN OF B OCCURS 100,
   1 TYPE I, 2 TYPE I, 3(50), 4(6), 5(6),
END OF B,
BEGIN OF C OCCURS 100,
   1 TYPE I, 2 TYPE I, 3(50), 4(6), 5(6), LEVEL TYPE I,
END OF C,
BEGIN OF TREE OCCURS 100.
        INCLUDE STRUCTURE SNODETEXT.
DATA: END OF TREE.
*
START-OF-SELECTION.
  SET PF-STATUS 'LIST'.
*
* Get the process table from UNIX
  OPEN DATASET '/tmp/AAAA' FOR INPUT IN TEXT MODE.
  TRANSFER 'a' TO '/tmp/AAAA'.
  CLOSE DATASET '/tmp/AAAA'.
* The filter option and the result of pf might be UNIX specific
* This version is for HP-UX
  OPEN DATASET '/tmp/AAAA' FOR INPUT IN TEXT MODE FILTER
  'ps -ef|awk ''{if ($5!~/.[:]./){$5=" "}}{print $0}''|awk ''{print $2,
  $3,$8,$1,$7}'''.
  DO.
    READ DATASET '/tmp/AAAA' INTO L.
    IF SY-INDEX = 1.
      CONTINUE.
    ENDIF.
    IF SY-SUBRC <> 0. EXIT. ENDIF.
* I am not interested about the vx_inactive_threads (HP specific!)
    IF L NS 'vx_inactive_thread'.
      SPLIT L AT ' ' INTO A-1 A-2 A-3 A-4 A-5.
      MOVE-CORRESPONDING A TO B.
      APPEND B.
    ENDIF.
  ENDDO.
*
* Move the processes to C based upon their parent/child relationship
  READ TABLE B INDEX 1.
  MOVE-CORRESPONDING B TO C.
  C-LEVEL = LEVEL.
  APPEND C.
  DELETE B INDEX 1.
* Call a recursive function module
  PERFORM FIND_CHILD USING C-1.
*
* Fill up the tree-display table
  LOOP AT C.
    AT FIRST.
      TREE-TEXT1 = 'UNIX processes name'.
      TREE-TEXT2 = 'Process id and owner'.
      TREE-TEXT3 = 'CPU time'.
      TREE-TLENGTH1 = 30. TREE-TLENGTH2 = 30. TREE-TLENGTH3 = 30.
      TREE-TCOLOR1 = 1. TREE-TCOLOR2 = 2. TREE-TCOLOR3 = 3.
      TREE-TLEVEL = 1.
      APPEND TREE.
    ENDAT.
    MOVE-CORRESPONDING C TO A.
    TREE-TEXT1 = A-3.
    TREE-TEXT2 = A-1. TREE-TEXT2+10 = A-4.
    TREE-TEXT3 = A-5.
    TREE-TLENGTH1 = 40. TREE-TLENGTH2 = 20. TREE-TLENGTH3 = 10.
    TREE-TCOLOR1 = 1. TREE-TCOLOR2 = 2. TREE-TCOLOR3 = 3.
    TREE-TLEVEL = C-LEVEL.
    APPEND TREE.
  ENDLOOP.
*
* Construct and display the tree
  CALL FUNCTION 'RS_TREE_CONSTRUCT'
       TABLES
            NODETAB      = TREE
       EXCEPTIONS
            TREE_FAILURE = 1.
  SY-LSIND = 0.
  CALL FUNCTION 'RS_TREE_LIST_DISPLAY'
       EXPORTING
            CALLBACK_PROGRAM      = 'ZCPUTREE'
            CALLBACK_USER_COMMAND = 'NODE_SELECT'
       IMPORTING
            F15                   = F15.
*
*---------------------------------------------------------------------*
*       FORM FIND_CHILD                                               *
*       Recursive f.m. to establish the parent/child relationships    *
*---------------------------------------------------------------------*
FORM FIND_CHILD USING VALUE(PARENT_NUMBER) TYPE I.
  LOOP AT B.
    IF B-2 = PARENT_NUMBER.
* I have found a child - move the parent to the result table and
* try to find the child's children
      LEVEL = LEVEL + 1.
      MOVE-CORRESPONDING B TO C.
      C-LEVEL = LEVEL.
      APPEND C.
      DELETE B.
      PERFORM FIND_CHILD USING B-1.
    ENDIF.
  ENDLOOP.
* No more children - move one level up
  LEVEL = LEVEL - 1.
ENDFORM.
*
*---------------------------------------------------------------------*
*       FORM NODE_SELECT                                              *
*       This is called, when a node is selected with a double-click   *
*---------------------------------------------------------------------*
FORM NODE_SELECT TABLES KNOTEN STRUCTURE SEUCOMM
  USING COMMAND
  CHANGING EXIT
           LIST_REFRESH.
  EXIT = ' '.
  LIST_REFRESH = 'X'.
ENDFORM.