Perles de Mongueurs (45)

Article publié dans Linux Magazine 120, octobre 2009.

[+ del.icio.us] [+ Developers Zone] [+ Bookmarks.fr] [Digg this] [+ My Yahoo!]

La perle de ce mois-ci a été rédigée par Sébastien Aperghis-Tramoni (sebastien@aperghis.net), de Sophia.pm.

Comment trouver tous les parents d'un processus ?

Suite à cette question que m'a posée David Morel, j'ai écrit en réponse cette fonction :

    use strict;
    use Proc::ProcessTable;

    sub getsession {
        my ($pid) = @_;
        my @session;

        # on récupère la liste des processus dans un hash
        my $table = Proc::ProcessTable->new->table;
        my %proc  = map { $_->pid => $_ } @$table;

        # on sauve le PID du processus courant pour commencer
        push @session, delete $proc{$pid};

        # .. et on boucle pour trouver chaque parent
        while (my $ppid = $session[-1]->ppid) {
            push @session, delete $proc{$ppid}
        }

        return \@session
    }

Elle utilise le module Proc::ProcessTable qui permet d'obtenir toutes les informations sur les processus en cours d'exécution. Trouver tous les parent d'un processus est fondamentalement un algorithme récursif, mais Perl permet de tricher facilement grâce aux hashs.

On récupère donc la liste des processus en cours d'exécution, et on en fait un hash indexé par les PIDs. La boucle devient alors quasiment triviale à écrire, en récupérant le PPID (Parent PID) du dernier processus stocké dans @session.

Ce tableau, qui est renvoyé par la fonction, est construit de sorte à ressembler un peu à caller() : l'élément zéro est le processus d'origine, l'élément 1 son père, l'élément 2 son grand-père, etc.

Petit exemple d'appel et d'affichage :

    my $session = getsession($$);
    my $level = 0;

    for my $proc (reverse @$session) {
        printf "%s[%d] %s\n", "  " x $level, $proc->pid, $proc->cmndline;
        $level++;
    }

Sur ma machine, cela donne :

    $ perl Perl/pidparents 
    [1] (launchd)
      [61] (WindowServer)
        [1062] /Applications/iTerm.app/Contents/MacOS/iTerm -psn_0_13893633
          [1090] (login)
            [1091] -bash
              [6649] perl Perl/pidparents

Oui, je suis sur Mac OS X. ;-)

À vous !

Envoyez vos perles à perles@mongueurs.net, elles seront peut-être publiées dans un prochain numéro de Linux Magazine.

[IE7, par Dean Edwards] [Validation du HTML] [Validation du CSS]