Re: [dev] pids for surf, webkit instances (+ lsw.c bug)

From: Greg Minshall <minshall_AT_acm.org>
Date: Thu, 07 Sep 2017 15:14:57 +0300

just for completeness, below is a bash script that uses lsw recursively
to walk the tree. it's a bit overkill (feeling guilty for having missed
the hackathon?). "once a Fortran programmer..."
----
#!/usr/bin/env bash
# this script walks the tree of known X windows on the system and
# prints out those that have PIDs (process ids; see ps(1)) associated
# with them.
# usage: "$0", or "$0 windowid ..."; in the former, the windows are
# traversed from the root window; in the latter, from the designated
# window id(s).
# the output is: pid windowid name [secondary]\n...
# program we use to list windowids
LSW=lsw
# recursive part of getwinids
function rgetwinids() {
    local windowid=$1 a i
    echo ${windowid}
    a=$(${LSW} $windowid | awk '{print $1}')
    for i in $a; do
        rgetwinids $i
    done
}
# output the windowids that seem to be on the system.
function getwinids() {
    local arg
    if [[ $# -eq 0 ]] ; then
        echo $(rgetwinids);
    else
        for arg in $*; do echo $(rgetwinids ${arg}); done
    fi
}
# do some processing on grep output
function gnhelper() {
    grep -w "$1" |
        head -1 |
        tr -d '\n' |
        awk '{$1=""; $2=""; print; exit}' |
        sed 's/^[[:blank:]]*"//' |
        sed 's/"$//';
 }
# now, get the name (and maybe surf(1) uri) of the window
function getname() {
    local winid=$1 wim su
    wim=$(xprop -id ${winid} | gnhelper ${pname});
    if [[ ${args} == 0 ]]; then
       echo ${wim}
    else
        su=$(xprop -id ${winid} | gnhelper ${sname});
        if [[ -z $su ]]; then
            echo ${wim};
        else
            echo "${wim} [$su]"
        fi
    fi
}
# how many digits might be in a PID?  will give one greater (newline
# counted by wc(1))
function pidndigits() {
    local i
    echo $(
        (for i in $(ps haxo pid); do
             echo $i |
                 wc |
                 awk '{print $3}';
         done) |
            sort -nu |
            tail -1
        )
}
# get the process id of the process that "owns" a window
function getpid() {
    xprop -id $1 | grep PID | awk '{print $3}';
}
# make sure ${LSW} is installed
function prereq() {
    a=$(${LSW} $windowid);
    if [[ $? -ge 126 ]] ; then
        printf "required program ${LSW} not found; see https://suckless.org\n(or install package suckless-tools)\n" > /dev/stderr
        exit 1;
    fi
}
function help() {
    echo "\
$(basename $0) lists all the windows open on the system, along with
their process IDs (pids), optionally ([--winid|-w]) the window ids, as
well as the name property of each window (\"WM_ICON_NAME\" is the
default property here), optionally ([-s]) a secondary property of the
window (\"_SURF_URI\" is the default) is listed after the primary
(enclosed in square brackets).
the width of the (combined) primary and secondary properties can be
set with [--cmdn|-c]; the width of the PID field set with [--pidn|-p].
"
    echo
    usage
}
function usage() {
    if [[ ! -z $1 ]] ; then echo "invalid argument \"$1\"" > /dev/stderr; fi
    echo "usage: $(basename $0) 
    [-s]
    [--winid|-w]
    [--help|-h]
    [[--cmdn|-c] NUM (${DEF_argnc})]
    [[--pidn|-p] NUM (${DEF_argnp})]
    [--pname STRING (\"${DEF_pname}\")]
    [--sname STRING (\"${DEF_sname}\")]" > /dev/stderr
    exit 1;
}
function parseargs() {
    local optlist="-l cmdn:,help,pidn:,pname:,sname:,winid -o c:hp:sw" optresult
    # http://bahmanm.com/blogs/command-line-options-how-to-parse-in-bash-using-getopt
    # of help here
    DEF_pname=WM_ICON_NAME
    DEF_sname=_SURF_URI
    DEF_argnc=200           # digits reserved for name field
    DEF_argnp=$(pidndigits) # how many digits should we reserve for pid?
    DEF_args=0
    DEF_argwinid=0
    cn=${DEF_argnc}
    pn=${DEF_argnp}
    argwinid=${DEF_pwinid}
    pname=${DEF_pname}
    sname=${DEF_sname}
    args=${DEF_args}
    optresult=$(getopt ${optlist} -- "$_AT_")
    if [[ $? != 0 ]]; then usage; fi
    eval set -- ${optresult}
    while true ; do
        case "$1" in
            -c|--cmdn) cn=$2; shift 2 ;;
            -h|--help) help; shift ;;
            -p|--pidn) pn=$2; shift 2 ;;
            -s) args=1; shift ;;
            -w|--winid) argwinid=true ; shift ;;
            --pname) pname=$2; shift 2 ;;
            --sname) sname=$2; shift 2 ;;
            --) shift; desired=$*; break ;;
            *) usage $1; ;; # NOTREACHED
        esac
    done
}
function main() {
    local winid a b winidpart
    parseargs $*
    prereq
    for winid in $(getwinids ${desired} | tr '[[:blank:]]' '\n' | sort -u | tr '\n' " "); do
        a=$(getpid ${winid})
        if [[ ! -z $a ]]; then
            b=$(getname ${winid})      # get name string for this window
            if [[ ${argwinid} ]]; then
                winidpart=" ${winid} ";
            else
                winidpart=" ";
            fi
            printf "%${pn}d%s%-.${cn}s\n" $a "${winidpart}" "$b"
        fi
    done | sort -n -k1
}
main $*
Received on Thu Sep 07 2017 - 14:14:57 CEST

This archive was generated by hypermail 2.3.0 : Thu Sep 07 2017 - 14:24:18 CEST