#!/bin/sh
#
# ------------------------------------------------------------------
#  show_signal.sh
# 
#  October 2010, Michael C. Scott
# 
#  Copyright (c) 2010-2011, 2013 by Cisco Systems, Inc.
#  All rights reserved.
# ------------------------------------------------------------------


# Prints a header before iterating over the specified nodes (printing a node
# header if it iterates over more than one node). Within each node it iterates
# over the processes on the node. For each process the process name and
# pending, ignored and queued signals are retrieved and printed. Within each 
# process it then iterates over the threads of the process. For each thread the
# blocked and pending signals are retrieved and printed.

# SH_PROC_SIGNAL*FORMAT_STRING
#
# The format string used when printing information.
SH_PROC_SIGNAL_FORMAT_STRING="%5.5s %-22.22s %16.16s %16.16s %16.16s\n"
SH_PROC_SIGNAL_SUBFORMAT_STRING="%-5.5s %-16.16s"


# Load the show_proc / pidin library.
source `dirname $0`/sh_proc_lib


function main
{
    local node_list=""
    local process_list=""
    local thread_list=""

    printf "$SH_PROC_SIGNAL_FORMAT_STRING" \
           "jid" "name" "signals pending" "signals ignored" "signals queued"
    printf "$SH_PROC_SIGNAL_FORMAT_STRING" \
           "" "`printf "$SH_PROC_SIGNAL_SUBFORMAT_STRING" "tid" "signals blocked"`" "signals pending" "" ""

    # Generate a list of nodes.
    sh_proc_node_iterator
    node_list=("${sh_proc_node_iterator_out[@]}")

    # Iterate over each node.
    for node in ${node_list[@]}; do
        # If there are multiple nodes we print a header for each node.
        if [ ${#node_list[@]} -gt 1 ]; then
            sh_proc_print_node_header $node
        fi
        # Set the path for the /proc filesystem of the current node.
        sh_proc_set_proc_path $node

        # Genereate a list of processes.
        sh_proc_process_iterator $node
        process_list=($sh_proc_process_iterator_out)

        # Generate a list of JIDs from the process list.
        sh_proc_pid_list_to_jid_list_in=("${process_list[@]}")
        sh_proc_pid_list_to_jid_list
        jid_list=($sh_proc_pid_list_to_jid_list_out)

        # Iterate over each process.
        local index=0
        while [ $index -lt ${#process_list[@]} ]; do
            local process=${process_list[$index]}

            # Retrieve the required information for the process.
            sh_proc_get_item $process "name15"
            name_out=$sh_proc_get_item_out

            sh_proc_get_item $process "sig_pend"
            sig_pend_out=$sh_proc_get_item_out    

            sh_proc_get_item $process "sig_ign"
            sig_ign_out=$sh_proc_get_item_out

            sh_proc_get_item $process "sig_queue"
            sig_queue_out=$sh_proc_get_item_out

            # If the information was succesfully retrieved print it. If the
            # PID could not be converted to a JID print an apporpriate
            # error message.
            if [ $sh_proc_get_item_error -eq 0 ]; then
                if [ ${jid_list[$index]} == "-1" ]; then
                    printf "Failed to get jobid from pid\n"
                else
                    printf "$SH_PROC_SIGNAL_FORMAT_STRING" \
                           "${jid_list[$index]}" "$name_out" "$sig_pend_out" \
                           "$sig_ign_out" "$sig_queue_out"

                    # Generate a list of threads.
                    sh_proc_thread_iterator $process
                    thread_list=$sh_proc_thread_iterator_out
               
                    # Iterate over each thread.    
                    for thread in $thread_list; do
            
                        # Retrieve the required information for the thread.
                        sh_proc_get_item $thread "sig_blk"
                        sig_blk_out=$sh_proc_get_item_out

                        sh_proc_get_item $thread "sig_pend"
                        sig_pend_out=$sh_proc_get_item_out

                        # If the information was succesfully retrieved print it.
                        if [ $sh_proc_get_item_error -eq 0 ]; then
                            printf "$SH_PROC_SIGNAL_FORMAT_STRING" \
                                   "" "`printf "$SH_PROC_SIGNAL_SUBFORMAT_STRING" \
                                   "$thread" "$sig_blk_out"`" $sig_pend_out "" ""
                        else
                            sh_proc_get_item_error=0
                        fi
                    done 
                fi
            else
                sh_proc_get_item_error=0      
            fi
            let index+=1
        done
        printf "\n"
    done
}


sh_proc_command_parser "$@"
main
