<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.mymind.fr/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Mind...</title>
  <link>http://blog.mymind.fr/</link>
  <atom:link href="http://blog.mymind.fr/feed/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Wed, 05 May 2010 15:52:31 +0200</pubDate>
  <copyright>© 2007-2008 Florent Bruneau</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Yet another policy daemon for postfix</title>
    <link>http://blog.mymind.fr/post/2009/04/06/Yet-another-policy-daemon-for-postfix2</link>
    <guid isPermaLink="false">urn:md5:4b28b577e017c0d4387574e76226efec</guid>
    <pubDate>Mon, 06 Apr 2009 22:04:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
            
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.madism.org/index.php/2007/08/29/136-postfix-and-srs&quot;&gt;MadCoder announced it months ago&lt;/a&gt;, he has been working on the pfixtools. The second tool of the &lt;a href=&quot;http://www.postfix.com&quot;&gt;postfix&lt;/a&gt;-related toolsuite is named &lt;strong&gt;postlicyd&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;postlicyd is a versatile &lt;a href=&quot;http://www.postfix.org/SMTPD_POLICY_README.html&quot;&gt;policy daemon&lt;/a&gt; written in C. It does greylisting (far faster than postgrey), it performs R(H)BL access (both locally directly from rbldns zone files and remotely by using DNS), ... So, it can be used as a replacement for &lt;a href=&quot;http://packages.qa.debian.org/w/whitelister.html&quot;&gt;whitelister&lt;/a&gt; and &lt;a href=&quot;http://postgrey.schweikert.ch/&quot;&gt;postgrey&lt;/a&gt; with a significant improvement of the performances.&lt;/p&gt;


&lt;p&gt;On the same server (with the same email trafic), postlicyd is more than 20 times faster than postgrey:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Process load: postgrey ~20% CPU, postlicyd less than 1% CPU&lt;/li&gt;
&lt;li&gt;Data base cleanup for 1M entries: postgrey 20 minutes, postlicyd 40 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Moreover, it is aware of the 'session' feature of the POLICY protocol. Thus, you can write complex configurations and define policies that do not depend on a single SMTP command (like RCPT) but on the whole SMTP transaction...&lt;/p&gt;


&lt;p&gt;More informations: &lt;a href=&quot;http://pfixtools.mymind.fr&quot; title=&quot;http://pfixtools.mymind.fr&quot;&gt;http://pfixtools.mymind.fr&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2009/04/06/Yet-another-policy-daemon-for-postfix2#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2009/04/06/Yet-another-policy-daemon-for-postfix2#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/42</wfw:commentRss>
      </item>
    
  <item>
    <title>Polytechnique.org lance son blog</title>
    <link>http://blog.mymind.fr/post/2008/06/03/Polytechniqueorg-lance-son-blog</link>
    <guid isPermaLink="false">urn:md5:5dc1b67cdab0c38509fe06fac4fd19e4</guid>
    <pubDate>Tue, 03 Jun 2008 23:33:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Polytechnique.org</category>
            
    <description>    &lt;p&gt;Voilà... cela fait assez longtemps que nous recevons des demandes d'utilisateurs pour la mise en place de blog via Polytechnique.org. Afin de préparer la mise en place de ce service, Polytechnique.org lance son blog. Cela permettra à la fois&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;de tester l'outil d'intégration de l'authentification de Polytechnique.org dans Dotclear.&lt;/li&gt;
&lt;li&gt;d'offrir une nouvelle plateforme souple et conviviale pour informer nos utilisateurs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Je ne vais pas m'étendre davantage vu que ce ne serait que recopier &lt;a href=&quot;http://blog.polytechnique.org/post/2008/06/01/Creation-du-blog-de-lequipe-Polytechniqueorg&quot;&gt;le post d'Aymeric&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2008/06/03/Polytechniqueorg-lance-son-blog#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2008/06/03/Polytechniqueorg-lance-son-blog#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/40</wfw:commentRss>
      </item>
    
  <item>
    <title>Vieux trucs</title>
    <link>http://blog.mymind.fr/post/2008/05/18/Vieux-trucs</link>
    <guid isPermaLink="false">urn:md5:6da13e9b18c1a4d0154e2a0c5dcc7139</guid>
    <pubDate>Sun, 18 May 2008 22:50:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Général</category>
        <category>Lycée</category><category>Maths</category><category>TI-92</category>    
    <description>&lt;p&gt;Un peu de nostalgie. Je suis retombé sur de vieux programmes que j'avais fait pour ma calculatrice (TI-92) quand j'étais en 1&lt;sup&gt;ère&lt;/sup&gt;/Terminale. A mon époque (pas si lointaine... j'ai passé mon bac en 2001), ces outils couvraient le programme de Terminal S (spécialité maths) avec&amp;nbsp;:&lt;/p&gt;    &lt;ul&gt;
&lt;li&gt;En analyse et algèbre&amp;nbsp;:
&lt;ul&gt;
&lt;li&gt;tableaux de signe et de variation (avec détection de la périodicité des fonctions en cas de besoin)&lt;/li&gt;
&lt;li&gt;équation différentielles (de Terminal, donc &lt;code&gt;y' = a.y + w&lt;/code&gt; ou &lt;code&gt;y&quot; + w&lt;sup&gt;2&lt;/sup&gt;.y = 0&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;division polynomiale&lt;/li&gt;
&lt;li&gt;linéarisation trigonométrique&lt;/li&gt;
&lt;li&gt;équations du 1&lt;sup&gt;er&lt;/sup&gt; et 2&lt;sup&gt;nd&lt;/sup&gt; degré&lt;/li&gt;
&lt;li&gt;résolution de systèmes d'équations&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.wikipedia.org/wiki/Triangle_de_Pascal&quot; hreflang=&quot;fr&quot;&gt;triangle de Pascal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;En géométrie&amp;nbsp;:
&lt;ul&gt;
&lt;li&gt;barycentres&lt;/li&gt;
&lt;li&gt;produits scalaires&lt;/li&gt;
&lt;li&gt;produits vectoriels&lt;/li&gt;
&lt;li&gt;calcul d'équations de droites, plans ou sphères...&lt;/li&gt;
&lt;li&gt;mesure principale&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;En arithmétique&amp;nbsp;:
&lt;ul&gt;
&lt;li&gt;division euclidienne&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.wikipedia.org/wiki/Équation_diophantienne&quot; hreflang=&quot;fr&quot;&gt;équation diophantienne&lt;/a&gt;, algorithme d'Euclide et coefficient de Bezout...&lt;/li&gt;
&lt;li&gt;factorisation et diviseurs des entiers&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le tout avec une interface permettant de passer d'un programme à l'autre simplement. Histoire que tout ceci ne se perde pas, je les met à disposition (ils sont également trouvables sur diverses banques de programmes pour TI)&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.mymind.fr/public/misc/maths3.zip&quot; hreflang=&quot;fr&quot;&gt;Télécharger le programme de maths niveau Terminal pour TI-92&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Evidemment, ces programmes ne dispensent pas d'apprendre le cours pour passer le Bac.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2008/05/18/Vieux-trucs#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2008/05/18/Vieux-trucs#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/39</wfw:commentRss>
      </item>
    
  <item>
    <title>Encodage et terminal</title>
    <link>http://blog.mymind.fr/post/2008/03/02/Encodage-et-terminal</link>
    <guid isPermaLink="false">urn:md5:c2d036586a265e02fe63ee0dfeeeb17a</guid>
    <pubDate>Sun, 02 Mar 2008 11:57:00 +0100</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Général</category>
        <category>encodage</category><category>shell</category><category>terminal</category><category>zsh</category>    
    <description>&lt;p&gt;Beaucoup de personnes avec qui je discute sur IRC ont des problèmes avec l'encodage de leur terminal, de leur shell, de leur irssi, ou de tout autre logiciel en &quot;ligne de commande&quot;. Comme j'en ai un peu marre d'expliquer la même chose toutes les semaines, voici une petite mise au point sur les réglages à faire pour travailler efficacement en ligne de commande.&lt;/p&gt;    &lt;h3&gt;Introduction&lt;/h3&gt;


&lt;p&gt;Le point le plus important à mémoriser est que pour avoir une console avec un encodage spécifique il faut que plusieurs couches de logiciels utilisent le même encodage. Prenons le cas simple où nous avons un shell dans un terminal.&lt;/p&gt;


&lt;p&gt;Le terminal est un logiciel qui ne fait que convertir les entrées de l'utilisateur vers des entrées compréhensibles par le logiciel qu'il fait tourner, et qui interprète la sortie de ce logiciel pour qu'elle soit lisible par l'utilisateur. Donc pour que le terminal affiche correctement ce qu'indique le shell, il faut qu'il utilise le même encodage que celui-ci. Si par exemple mon shell écrit de l'UTF-8 alors que mon terminal attend du latin1, les caractères multi-octets de l'UTF-8 seront mal interprétés et afficheront un caractère par octet. Ainsi un &quot;é&quot; en utf8 s'affiche comme un &quot;Ã©&quot; en latin1.&lt;/p&gt;


&lt;p&gt;Pour l'entrée de l'utilisateur, c'est la même chose. Si mon terminal est en latin1 et mon shell en utf8, si j'entre un &quot;é&quot; dans mon terminal, celui-ci sera passé à mon terminal comme un seul octet (de valeur 0xE9). Or mon shell attend de l'utf8 et lorsqu'il reçoit un 0xE9, il considère que je viens d'entrer un octet d'un caractère multi-octets... les prochains caractères que j'entrerais seront donc ajoutés à mon 0xE9 jusqu'à ce que mon shell considère que j'ai entré un caractère... assez embêtant.&lt;/p&gt;


&lt;p&gt;Il faut donc faire extrêmement attention à choisir un encodage unique compatible avec son shell et son terminal (et les logiciels qu'on compte utiliser).&lt;/p&gt;



&lt;h3&gt;Terminal&lt;/h3&gt;


&lt;p&gt;Le réglage du terminal dépend exclusivement du logiciel en question. Certains terminaux permettent de choisir son encodage, d'autres non. Cela peut donc être un bon critère pour choisir son logiciel. Pour utiliser l'UTF-8, vous pouvez prendre Konsole, urxvt, le Terminal de Mac OS X...&lt;/p&gt;



&lt;h3&gt;Shell&lt;/h3&gt;


&lt;p&gt;Le réglage du shell se fait par des variables d'environnement qu'on appelle couramment les &quot;locales&quot;. Le réglage courant est accessible en tapant &quot;locale&quot; dans le shell. Un certain nombre de variables sont concernées&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gestion de la langue du shell (et des programmes liés)&lt;/li&gt;
&lt;li&gt;gestion des formats (dates, monnaies, virgules...)&lt;/li&gt;
&lt;li&gt;LC_ALL est un &quot;fallback&quot; (l'encodage par défaut si aucun autre n'a été défini pour une variable donnée).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chaque variable est de la forme xx_YY.ZZ. xx_YY défini la zone géographique et la langue (fr_FR pour le français, en_US pour l'anglais-US). ZZ défini l'encodage. Il est important que toutes les variables utilisent le même encodage (mais elles peuvent avoir des langues différentes). Pour faire de l'UTF-8 pur, un bon choix est d'exporter LC_ALL=&quot;en_US.UTF-8&quot; dans la configuration du shell (ou fr_FR.UTF-8 pour ceux qui veulent un shell en français).&lt;/p&gt;


&lt;p&gt;Il faut par contre faire attention, l'UTF-8 n'est pas supporté par tous les shells (à partir de 4.3 pour zsh par exemple).&lt;/p&gt;



&lt;h3&gt;Irssi&lt;/h3&gt;


&lt;p&gt;Pour irssi, il y a un point supplémentaire à prendre en compte&amp;nbsp;: l'encodage du réseau. Ainsi si j'ai un channel en latin1 à afficher en utf8 (et sur lequel je veux poster). Il faut donc que irssi fasse de transcodage à la volée... et bien sûr il faut lui dire ce qu'il faut faire.&lt;/p&gt;


&lt;p&gt;Tout d'abord il faut lui indiquer l'encodage du terminal. Pour ceci il y a la variable term_charset&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
settings = {
  &amp;quot;fe-common/core&amp;quot; = {
    term_charset = &amp;quot;UTF-8&amp;quot;;
  };
};
&lt;/pre&gt;


&lt;p&gt;Ensuite, il faut indiquer pour chaque réseau (ou channel) l'encodage du réseau. Ce n'est en fait nécessaire que si l'encodage est différent de celui du terminal, mais ça ne coûte rien de le spécifier pour chaque réseau. Ainsi je suis sur RezoSup (qui est en latin1) et sur FreeNode (qui est en utf8), il me suffit d'ajouter&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
settings = {
  core = {
    recode = &amp;quot;yes&amp;quot;;
  };
};
conversions = { 
  FreeNode = &amp;quot;UTF-8&amp;quot;;
  Rezosup = &amp;quot;ISO-8859-1&amp;quot;;
};
&lt;/pre&gt;


&lt;p&gt;Les entrées &quot;FreeNode&quot; et &quot;Rezosup&quot; doivent reprendre le nom du chatnet donné dans la section &quot;servers&quot; de la configuration. Pour spécifier l'encodage spécifique à un channel, il suffit de mettre &lt;code&gt;&quot;Chatnet/#channel&quot; = &quot;encoding&quot;;&lt;/code&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2008/03/02/Encodage-et-terminal#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2008/03/02/Encodage-et-terminal#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/38</wfw:commentRss>
      </item>
    
  <item>
    <title>Afficher des discussions</title>
    <link>http://blog.mymind.fr/post/2007/11/01/Afficher-des-discussions</link>
    <guid isPermaLink="false">urn:md5:1bc6a0f2c9ce16187b5ff9f62df8c2a4</guid>
    <pubDate>Thu, 01 Nov 2007 17:24:00 +0100</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Polytechnique.org</category>
        <category>Banana</category><category>Devel</category><category>PHP</category>    
    <description>&lt;p&gt;Lorsqu'un logiciel a pour vocation d'afficher des discussions, on attend de sa part qu'il nous permette de voir simplement qui répond à qui, dans quel contexte... Ce n'est pas toujours ce qui est le mieux fait. Par exemple, les programmes de fora en ligne à la mode (phpBB par exemple) affiche les discussion comme une succession de rectangles juxtaposés et seul le contenu du message permet de voir qu'il en cite un autre. D'autres logiciels comme Mail.app ont ce défaut et parfois la fâcheuse manie de ne pas vouloir corriger ce problème.&lt;/p&gt;


&lt;p&gt;L'affichage de l'arborescence dans &lt;a href=&quot;http://opensource.polytechnique.org/banana&quot;&gt;Banana&lt;/a&gt; est une des fonctionnalités clés... et elle va beaucoup changer dans la prochaine version.&lt;/p&gt;    &lt;h2&gt;Une ligne par entrée&lt;/h2&gt;


&lt;p&gt;La solution habituelle pour afficher l'arborescence est d'utiliser un message par ligne de telle, des + ou - pour ouvrir ou fermer les noeuds. C'est la solution actuelle de banana.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/old-thread.png&quot; alt=&quot;Banana Thread up to 1.7&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Avec cette solution, on perd très rapidement en lisibilité&amp;nbsp;: dès que la discussion dépasse une vingtaine de messages, l'arborescence devient très haute et plus ça va, plus le titre dérive vers la droite rendant parfois le lien inaccessible. Lorsqu'il y a un troll, il est de fait très courant que certains nouveaux messages se trouvent perdus plusieurs pages en arrière dans l'arborescence, ou que sur certains navigateurs, il soit difficile d'y accéder. De plus l'interface se trouve souvent surchargée, à la limite de la lisibilité&amp;nbsp;: c'est dur de faire tenir un maximum d'informations en un minimum de place en gardant la lisibilité de l'ensemble.&lt;/p&gt;



&lt;h2&gt;Une solution plus visuelle&lt;/h2&gt;


&lt;p&gt;Je ne sais pas combien de personnes connaissent &lt;a href=&quot;http://home.snafu.de/stk/macsoup/&quot;&gt;MacSoup&lt;/a&gt;. Il s'agit d'un petit client NNTP pour MacOS, qui en soit n'a pas beaucoup d'intérêt (il est payant et est relativement limité). Le principal atout de MacSoup est son interface de visualisation des threads (les utilisateurs diront qu'il y a bien plus que l'interface graphique, mais également l'interface clavier etc...). On trouve sur internet quelques captures d'écran en cherchant dans les &lt;a href=&quot;http://www.exalead.com/image/results?q=macsoup%20screenshot&quot;&gt;moteurs de recherche d'image&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://www.fen-net.de/~xx511/bilder/macsoup/Thread.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Cette interface est compacte, visuelle et permet d'accéder rapidement à n'importe quel message du thread. Pour la prochaine version de Banana, je me suis fortement inspiré de cette interface pour réécrire de 0 l'affichage de l'arborescence. Ceci donne&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/new-thread.png&quot; alt=&quot;Thread view in Banana&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Il s'agit de la même discussion que précédemment. On voit donc ici facilement l'arborescence. Lorsqu'un message est non lu, la branche à laquelle il est attaché est noire au lieu de grise ce qui permet de l'identifier du premier coup d'oeil. Les couleurs de fond des noeuds (une idée de &lt;a href=&quot;http://www.falco.bz&quot;&gt;Falco&lt;/a&gt;) sont obtenue à partir d'un hash quelconque sur l'émetteur et permettent donc d'identifier les messages envoyés par la même personne. Lorsqu'on laisse la souris sur un noeud, le nom de l'expéditeur et l'heure du post s'affichent (malheureusement le pointeur de la souris n'apparaît pas sur la capture d'écran)... et bien sûr quand on clique sur un noeud, on va sur le message correspondant.&lt;/p&gt;


&lt;p&gt;Lorsqu'on est sur un message, on garde également la vue du thread ce qui permet de toujours savoir où on est dans la discussion&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/new-thread-nav.png&quot; alt=&quot;Thread view with selected message&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Il y a encore un peu de travail à faire pour améliorer les performances de la génération des arbres et pour augmenter sa compacité (éviter les branches qui descendent très bas alors qu'elles auraient pu trouver leur place dans le l'espace vide disponible).&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/11/01/Afficher-des-discussions#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/11/01/Afficher-des-discussions#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/37</wfw:commentRss>
      </item>
    
  <item>
    <title>15 000</title>
    <link>http://blog.mymind.fr/post/2007/10/07/15-000</link>
    <guid isPermaLink="false">urn:md5:3203b5fe73f058361981bf16bcb0e018</guid>
    <pubDate>Sun, 07 Oct 2007 22:32:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Polytechnique.org</category>
            
    <description>    &lt;p&gt;Ca y est... 15 000 inscrits à &lt;a href=&quot;https://www.polytechnique.org&quot;&gt;Polytechnique.org&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.mymind.fr/public/screenshots/15.000.png&quot;&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/15.000.png&quot; alt=&quot;15.000 inscrits&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Si l'ascension continue, nous devrions atteindre les 16 000 l'année prochaine.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/10/07/15-000#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/10/07/15-000#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/36</wfw:commentRss>
      </item>
    
  <item>
    <title>Compter les fichiers</title>
    <link>http://blog.mymind.fr/post/2007/08/30/Compter-les-fichiers</link>
    <guid isPermaLink="false">urn:md5:a4d72e31c767c980a39751dea09efb0a</guid>
    <pubDate>Thu, 30 Aug 2007 23:12:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>Devel</category><category>pratique</category><category>zsh</category>    
    <description>&lt;p&gt;C'est un peu la suite de mon post &quot;Outils pratiques&quot; où je donnais deux scripts permettant de rendre les commandes SVN plus conviviales. Encore une fois, je réinvente sans doute la roue (des outils équivalents doivent déjà exister... sans doute en mieux), mais je pense que chercher ce genre d'outils sur internet m'aurait pris plus de temps que ce qu'il m'a fallu pour le développer.&lt;/p&gt;


&lt;p&gt;En ce moment je manipule des fichiers, beaucoup de fichiers (et même, beaucoup de gros fichiers), que j'ouvre, rouvre, et ferme et puis referme. Et à force d'ouvrir, on oublie parfois de refermer, et là, c'est comme une fuite de mémoire, sauf que le nombre limite de fichiers ouverts est beaucoup plus rapidement atteinte que la limite de mémoire... dans la configuration de base sur un linux, un programme n'a le droit qu'à 1024 descripteurs de fichiers. D'où mon problème&amp;nbsp;: comment traquer les &quot;file-handle leaks&quot;&amp;nbsp;?&lt;/p&gt;    &lt;p&gt;Pour le faire, je me suis fait rapidement un petit script qui permet d'analyser les données issues d'un &lt;code&gt;strace&lt;/code&gt;. &lt;code&gt;strace&lt;/code&gt; est, pour ceux qui ne le savent pas, un programme très pratique qui permet de lister les appels systèmes. Dans mon cas présents, surveiller les ouvertures fermetures de fichiers revient à traquer les commandes &lt;code&gt;open&lt;/code&gt; (ouverture d'un fichier), et les commandes &lt;code&gt;close&lt;/code&gt;. Donc, je récupère simplement la liste des appels à &lt;code&gt;open&lt;/code&gt; et &lt;code&gt;close&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;bash&quot;&gt;&lt;span style=&quot;color: #c20cb9; font-weight: bold;&quot;&gt;strace&lt;/span&gt; &lt;span style=&quot;color: #660033;&quot;&gt;-f&lt;/span&gt; &lt;span style=&quot;color: #660033;&quot;&gt;-e&lt;/span&gt; &lt;span style=&quot;color: #007800;&quot;&gt;trace&lt;/span&gt;=open,close mon programme &lt;span style=&quot;color: #000000;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;/&lt;/span&gt;quelque&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;/&lt;/span&gt;part&lt;/code&gt;


&lt;p&gt;Et ainsi, le fichier &lt;code&gt;/quelque/part&lt;/code&gt; contient la liste complète des appels à &lt;code&gt;open&lt;/code&gt; et &lt;code&gt;close&lt;/code&gt; effectués par mon programme (et ses processus fils). Il ne reste plus alors qu'à analyser le contenu de &lt;code&gt;/quelque/part&lt;/code&gt;. Pour ceci, il suffit de peu de lignes de code (en perl pour ma part, mais d'autres auraient fait la même chose en shell, python... ou n'importe quel langage de scripting)&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;perl&quot;&gt;&lt;span style=&quot;color: #666666; font-style: italic;&quot;&gt;#!/usr/bin/perl &lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;%files&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;%modes&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;%lines&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$lineNb&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cc66cc;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$maxOpened&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cc66cc;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$currentOpened&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cc66cc;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$totalOpened&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cc66cc;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$line&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009999;&quot;&gt;&amp;lt;STDIN&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$line&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=~&lt;/span&gt; &lt;span style=&quot;color: #009966; font-style: italic;&quot;&gt;/open\\(&amp;quot;([^&amp;quot;&amp;quot;]+)&amp;quot;, ([^\\)]+)\\)\\s*=\\s*(\\d+)/&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$files&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$3&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$modes&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$3&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$2&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$lines&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$3&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$lineNb&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$totalOpened&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;++;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$currentOpened&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;++;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$currentOpened&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$maxOpened&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$maxOpened&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$currentOpened&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$line&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=~&lt;/span&gt; &lt;span style=&quot;color: #009966; font-style: italic;&quot;&gt;/close\\((\\d+)\\)/&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$files&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;ne&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;''&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$files&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;''&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$currentOpened&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;--;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$lineNb&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;++;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&lt;a href=&quot;http://perldoc.perl.org/functions/print.html&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;print&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;$totalOpened files opened, max. $maxOpened at the same time&lt;br /&gt;
&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;a href=&quot;http://perldoc.perl.org/functions/print.html&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;print&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;$currentOpened files not closed&lt;br /&gt;
&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #b1b100;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$id&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://perldoc.perl.org/functions/keys.html&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;keys&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;%files&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;a href=&quot;http://perldoc.perl.org/functions/local.html&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;local&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$file&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$files&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;a href=&quot;http://perldoc.perl.org/functions/local.html&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;local&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$mode&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$modes&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;a href=&quot;http://perldoc.perl.org/functions/local.html&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;local&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$line&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$lines&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$file&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;ne&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;''&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;a href=&quot;http://perldoc.perl.org/functions/print.html&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;print&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;[line $line] id=$id, open $file with mode $mode&lt;br /&gt;
&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Pour simplifier le tout, on rajoute une fonction dans le &lt;code&gt;zshrc&lt;/code&gt; pour wrapper tout ça, et ça donne (attention, ceci ne fonctionne que sous linux, &lt;code&gt;mktemp&lt;/code&gt; n'a pas la même syntaxe sur MacOS, et surtout, &lt;code&gt;strace&lt;/code&gt; n'est pas disponible sur Mac&lt;/p&gt;

&lt;code class=&quot;bash&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; checkFiles&lt;span style=&quot;color: #7a0874; font-weight: bold;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #7a0874; font-weight: bold;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #7a0874; font-weight: bold;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #007800;&quot;&gt;TEMPFILE&lt;/span&gt;=&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #c20cb9; font-weight: bold;&quot;&gt;mktemp&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;`&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #c20cb9; font-weight: bold;&quot;&gt;strace&lt;/span&gt; &lt;span style=&quot;color: #660033;&quot;&gt;-f&lt;/span&gt; &lt;span style=&quot;color: #660033;&quot;&gt;-e&lt;/span&gt; &lt;span style=&quot;color: #007800;&quot;&gt;trace&lt;/span&gt;=open,close &lt;span style=&quot;color: #007800;&quot;&gt;$*&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #007800;&quot;&gt;$TEMPFILE&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #c20cb9; font-weight: bold;&quot;&gt;cat&lt;/span&gt; &lt;span style=&quot;color: #007800;&quot;&gt;$TEMPFILE&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;|&lt;/span&gt; ~&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;/&lt;/span&gt;.zsh&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;/&lt;/span&gt;trackFiles.pl &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #c20cb9; font-weight: bold;&quot;&gt;rm&lt;/span&gt; &lt;span style=&quot;color: #007800;&quot;&gt;$TEMPFILE&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #7a0874; font-weight: bold;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Avec, ça, il ne me répond&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
% checkFiles cp test test2
12 files opened, max. 2 at the same time
0 files not closed
&lt;/pre&gt;


&lt;p&gt;Si maintenant, je fais un programme minimaliste qui oublie de fermer un fichier&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;c&quot;&gt;&lt;span style=&quot;color: #339933;&quot;&gt;#include &amp;lt;stdio.h&amp;gt; &lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; main&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; FILE&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; file &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; fopen&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; file &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;?&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/code&gt;

&lt;pre&gt;
% gcc test.c -o tester
% checkFiles ./tester
3 files opened, max. 1 at the same time
1 files not closed
[line 4] id=3, open test with mode O_RDONLY
&lt;/pre&gt;


&lt;p&gt;Voilà, maintenant je sais que mon programme oublie de fermer un fichier, que ce fichier s'appelle &quot;test&quot;, et qu'il est ouvert en read-only. La ligne &quot;4&quot; est la ligne dans la sortie de &lt;code&gt;strace&lt;/code&gt;, et n'a aucun rapport avec la ligne 4 du fichier source (contrairement aux apparences).&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/08/30/Compter-les-fichiers#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/08/30/Compter-les-fichiers#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/35</wfw:commentRss>
      </item>
    
  <item>
    <title>Templates en C</title>
    <link>http://blog.mymind.fr/post/2007/08/16/Templates-en-C</link>
    <guid isPermaLink="false">urn:md5:305c30979642387ee13cea31a6b77855</guid>
    <pubDate>Thu, 16 Aug 2007 22:53:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>C</category><category>Cpp</category><category>Devel</category>    
    <description>&lt;p&gt;En C++, il existe un mécanisme extrêmement pratique pour généré du code générique&amp;nbsp;: les templates. Une fonction templatée est une fonction dont le code comporte un trou qui sera remplacé à la compilation par le nom d'un type, ou une valeur... Par exemple&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
template &amp;lt;class T&amp;gt; 
T read(const char *buffer) 
{
    T val;
    memcpy(&amp;amp;val, buffer, sizeof(T));
    return val;
} 
&lt;/pre&gt;


&lt;p&gt;Cette fonction lit un objet de type T sur un buffer. L'intérêt de cette fonction est très compréhensible&amp;nbsp;: quel que soit le type qu'on fournit à la fonction, elle va fonctionner, en adaptant la taille à lire au type. C'est donc beaucoup plus rapide que d'écrire une fonction pour chaque type... et l'utilisation est également très simple&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
read&amp;lt;int&amp;gt;(const char* buffer) // lit un entier sur le buffer
read&amp;lt;double&amp;gt;(const char* buffer) // lit un double sur le buffer
read&amp;lt;MaClass&amp;gt;(const char* buffer) // lit un objet de type &amp;quot;MaClass&amp;quot;
&lt;/pre&gt;


&lt;p&gt;Mais cette syntaxe n'est qu'un sucre syntaxique, car en fait, on peut également faire des templates en C...&lt;/p&gt;    &lt;h3&gt;Comment fonctionne les templates&amp;nbsp;?&lt;/h3&gt;


&lt;p&gt;En fait un template est, comme son nom l'indique, qu'un modèle de fonction. Lors de la compilation d'un programme qui utilise des templates, le compilateur regarde la liste des instances de cette fonction qui sont utilisées et les génère. Plus explicitement, si j'appelle read&amp;lt;double&amp;gt;(), le compilateur va générer cette fonction&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;cpp&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;double&lt;/span&gt; read&lt;span style=&quot;color: #000080;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;double&lt;/span&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #000040;&quot;&gt;*&lt;/span&gt;buffer&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;double&lt;/span&gt; val&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000dd;&quot;&gt;memcpy&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000040;&quot;&gt;&amp;amp;&lt;/span&gt;val, buffer, &lt;span style=&quot;color: #0000dd;&quot;&gt;sizeof&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;double&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; val&lt;span style=&quot;color: #008080;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Ainsi, l'appel à read&amp;lt;double&amp;gt; devient un appel de fonction classique.&lt;/p&gt;


&lt;h3&gt;Jeu de préprocesseur&lt;/h3&gt;


&lt;p&gt;Le préprocesseur en C possède des outils sympathique... Nous nous attarderons particulièrement sur le ##. Il s'agit tout simplement d'un opérateur de concaténation. Donc&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;c&quot;&gt;&lt;span style=&quot;color: #339933;&quot;&gt;#define Truc(Machin) Truc ## Machin&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Truc&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;Bidule&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* génère TrucBidule */&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;C'est donc très pratique. On peut facilement par exemple, imaginer une petite macro du genre&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;c&quot;&gt;&lt;span style=&quot;color: #339933;&quot;&gt;#define maFonction(Type) maFonction_ ## Type&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Si dans ce cas, on défini par exemple maFonction_int, maFonction_double, maFonction_MaStruct (oui, les classes n'existent pas en C), on pourra faire&lt;/p&gt;

&lt;code class=&quot;c&quot;&gt;maFonction&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* appelle maFonction_int */&lt;/span&gt;&lt;br /&gt;
maFonction&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333;&quot;&gt;double&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* appelle maFonction_double */&lt;/span&gt;&lt;br /&gt;
maFonction&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;MaStruct&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* appelle maFonction_MaStruct */&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Maintenant, il ne reste plus qu'à générer les fonctions... sans avoir à toutes les écrire une à une. Pour ceci, nous allons encore une fois profiter de la présence du préprocesseur.&lt;/p&gt;

&lt;code class=&quot;c&quot;&gt;&lt;span style=&quot;color: #339933;&quot;&gt;#define maFonctionBuild(Type) \\&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; Type maFonction_ &lt;span style=&quot;color: #339933;&quot;&gt;## Type(const char* buffer) { \\&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Type val&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; \\&lt;br /&gt;
&amp;nbsp; &amp;nbsp; memcpy&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt;val&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; buffer&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;sizeof&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;Type&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; \\&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; val&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; \\&lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
maFonctionBuild&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* génère maFonction_int */&lt;/span&gt;&lt;br /&gt;
maFonctionBuild&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333;&quot;&gt;double&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* génère maFonction_double */&lt;/span&gt;&lt;br /&gt;
maFonctionBuild&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;MaStruct&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* génère maFonction_MaStruct */&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Il ne reste donc qu'à appeler maFonctionBuild(Type) sur chacun des types pour lesquels nous avons besoin d'instancier la fonction, et d'appeler maFonction(Type) chaque fois qu'on veut appeler maFonction pour le type en question. D'une certaine manière on peut dès lors dire que les fonctions sont&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;c&quot;&gt;Type maFonction&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;Type&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; buffer&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/code&gt;


&lt;h3&gt;Et voilà&amp;nbsp;!&lt;/h3&gt;


&lt;p&gt;Nous avons donc une implémentation générique grâce au préprocesseur associé à un appel typé. Ce n'est évidemment qu'une astuce de préprocesseur, mais cela donne une souplesse syntaxique agréalble&amp;nbsp;: &quot;J'appelle maFonction appliquée sur les entiers avec les arguments args&quot;.&lt;/p&gt;


&lt;p&gt;Tout ceci est certes, moins souple que les templates C++&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;il n'y a pas d'auto-instanciation par le compilateur&amp;nbsp;: il faut &quot;manuellement&quot; instancier la fonction pour tous les types pour lesquels ont l'appelle&lt;/li&gt;
&lt;li&gt;il n'y a pas de &quot;type check&quot;&amp;nbsp;: les seules limites sont celle de la compilation&lt;/li&gt;
&lt;li&gt;le correction des erreurs de compilation est fastidieuse car toutes les erreurs apparaissent comme étant à la ligne d'appel à maFonctionBuild&lt;/li&gt;
&lt;li&gt;il est rapidement fastidieux de rajouter l'antislash à la fin de chaque ligne de la définition de la fonction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comme on le voit dans les choix de l'exemple, pour les entrées/sorties, ça permet d'avoir une seule fonction à écrire tout en gardant la flexibilité d'une fonction par type de données.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/08/16/Templates-en-C#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/08/16/Templates-en-C#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/34</wfw:commentRss>
      </item>
    
  <item>
    <title>Comprendre du code</title>
    <link>http://blog.mymind.fr/post/2007/08/15/Comprendre-du-code</link>
    <guid isPermaLink="false">urn:md5:166320b7eed5bae3b2f101cffa3b53e9</guid>
    <pubDate>Wed, 15 Aug 2007 01:28:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>Devel</category>    
    <description>&lt;p&gt;J'ai tenté cet après-midi une petite expérience sur IRC. J'ai posté 3 lignes de code en demandant &quot;que font ces trois lignes&quot;. Après quelques minutes (sans doute trop peu), j'ai donné la solution car personne n'avait vraiment trouvé. En effet, même si on réussi facilement à lire le code et à reconstituer la suite d'opération qu'il génère, il est très difficile de vraiment comprendre ce qu'il fait, d'imaginer son application dans un contexte et d'en déduire son usage.&lt;/p&gt;


&lt;p&gt;Juste pour continuer à m'amuser, et pour amuser ceux qui se perdraient ici, voici le code en question.&lt;/p&gt;    &lt;code class=&quot;c&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: #339933;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;pos&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;pos&lt;span style=&quot;color: #339933;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Vous pouvez remarquer dès à présent que ce code n'est pas volontairement rendu illisible (il serait facile de supprimer des parenthèses et de changer le test de nullité en une négation. Le but est donc de comprendre la suite d'instruction, de dire ce qu'elle fait et ensuite de comprendre dans quel contexte elle est utilisable. La question est aussi de savoir en combien de temps vous allez trouver la solution.&lt;/p&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;http://blog.mymind.fr/jquery.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;//&lt;![CDATA[
function show_answer() {
  $(&quot;#show_answer&quot;).hide();
  $(&quot;#answer&quot;).show(&quot;slow&quot;);
  return false;
}
//]]&gt;&lt;/script&gt;
&lt;p&gt;
&lt;a href=&quot;http://blog.mymind.fr/post/2007/08/15/&quot; onclick=&quot;return show_answer()&quot; id=&quot;show_answer&quot;&gt;Cliquer ici pour afficher la répondre&lt;/a&gt;
&lt;/p&gt;
&lt;div id=&quot;answer&quot; style=&quot;display: none&quot;&gt;


&lt;h3&gt;Fonctionnement&lt;/h3&gt;


&lt;p&gt;Si on lit le code, on voit qu'il fait la suite d'opération suivante&amp;nbsp;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;on incrémente la valeur pointée par pos&lt;/li&gt;
&lt;li&gt;on regarde si la valeur obtenue est nulle&lt;/li&gt;
&lt;li&gt;on incrémente le pointeur pos&lt;/li&gt;
&lt;li&gt;si le test 2 est vrai, on retourne en 1, sinon, on quitte la boucle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Il s'agit donc d'une petite boucle qui incrémente des objets successifs jusqu'à ce qu'elle en trouve un qui, une fois incrémenté, n'est pas nul.&lt;/p&gt;


&lt;p&gt;Voilà donc la solution du pauvre au problème, celle qu'on peut trouver en lisant le code, sans chercher à le comprendre.&lt;/p&gt;


&lt;h3&gt;Interprétation&lt;/h3&gt;


&lt;p&gt;Mais en fait, ce code va plus loin. Imaginons maintenant la zone mémoire sur laquelle pos pointe initialement&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
 oct1 oct2 oct3 oct4
  ^
 pos
&lt;/pre&gt;


&lt;p&gt;L'octet 1 à une certaine valeur. Je l'incrémente et je m'aperçois que sa nouvelle valeur est 0. Quand un octet incrémenté peut-il retomber à 0&amp;nbsp;? Quand il fait un overflow. On a donc fait déborder le premier octet... et quand cet octet déborde on incrémente le suivant&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
    _+1__
   |     |
 oct1 oct2 oct3 oct4
       ^
      pos
&lt;/pre&gt;


&lt;p&gt;Il s'agit donc ni plus ni moins que d'une retenue (comme quand on apprend à faire les additions ou les multiplications)&amp;nbsp;: quand je fais déborder un octet, je déplace le surplus vers le suivant. Finalement, ces 3 lignes de code ne sont que l'implémentation d'une incrémentation, mais sur plusieurs octets... et même sur un nombre non défini d'octets (puisqu'il n'y a pas de limite explicitée sur le nombre d'étapes autorisées).&lt;/p&gt;


&lt;p&gt;Pour être plus précis, il s'agit d'un incrémenteur d'entier stocké en Little Endian sur un nombre illimité d'octets.&lt;/p&gt;


&lt;h3&gt;Encore&amp;nbsp;?&lt;/h3&gt;


&lt;p&gt;Bon, pour ceux qui tiennent vraiment à s'assurer que ce n'est pas du code illisible, voici une version vraiment illisible de la même machine&amp;nbsp;:&lt;/p&gt;
&lt;code class=&quot;c&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;++*&lt;/span&gt;pos&lt;span style=&quot;color: #339933;&quot;&gt;;!*&lt;/span&gt;pos&lt;span style=&quot;color: #339933;&quot;&gt;++;++*&lt;/span&gt;pos&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;(Merci Falco)&lt;/p&gt;


&lt;p&gt;Tout ceci n'était bien sûr qu'un exemple. Il est toujours très dur de comprendre du code, alors pour éviter de passer dix minutes sur 3 lignes lors de la prochaine relecture il suffit de documenter ce qu'on écrit.&lt;/p&gt;

&lt;/div&gt;
</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/08/15/Comprendre-du-code#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/08/15/Comprendre-du-code#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/33</wfw:commentRss>
      </item>
    
  <item>
    <title>BlueScreen</title>
    <link>http://blog.mymind.fr/post/2007/07/28/BlueScreen</link>
    <guid isPermaLink="false">urn:md5:3f824372316f05e5b5d01f48810094d9</guid>
    <pubDate>Sat, 28 Jul 2007 21:15:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Général</category>
        <category>Vista</category><category>Windows</category>    
    <description>    &lt;p&gt;Juste parce que je trouve ça amusant&amp;nbsp;: lorsque Vista plante en raison d'une erreur sérieuse, il fait un écran bleu (exactement le même que sous Windows XP). Ce qui est amusant, c'est le message affiché lors du démarrage suivant de Windows.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/BlueScreen.png&quot; alt=&quot;Vista-bluescreen&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Windows récupère donc d'une erreur de type &quot;BlueScreen&quot;... cela a l'intérêt d'être précis. En temps normal, on identifie une erreur à sa cause, et non à sa conséquence.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/07/28/BlueScreen#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/07/28/BlueScreen#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/32</wfw:commentRss>
      </item>
    
  <item>
    <title>Mail.app, IMAP et signatures...</title>
    <link>http://blog.mymind.fr/post/2007/06/11/Mailapp-IMAP-et-signatures</link>
    <guid isPermaLink="false">urn:md5:657a3063b4d13d904067ae115cc2bd01</guid>
    <pubDate>Mon, 11 Jun 2007 23:24:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Général</category>
        <category>IMAP</category><category>Mac</category><category>Mail</category><category>PGP</category>    
    <description>&lt;p&gt;Les temps sont durs pour les utilisateurs de IMAP... jusqu'à présent je n'ai pas trouvé de client idéal pour travailler avec ce protocole&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kmail plante lamentablement&lt;/li&gt;
&lt;li&gt;Mail.app se synchronise mal&lt;/li&gt;
&lt;li&gt;Outlook Express (et le tout nouveau Windows Mail) n'arrive pas à lister tous mes répertoires&lt;/li&gt;
&lt;li&gt;Thunderbird rame comme un malheureux et me crée des répertoires que je ne veux pas avant de m'avoir demandé quoi que ce soit&lt;/li&gt;
&lt;li&gt;mutt est trop casse-pied à configurer à mon goût (même si pratique parfois)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;De fait, j'utilise le moins pire que j'ai trouvé, et qui en plus a le mérite de ne pas être trop lourd, bien intégré avec MacOS X, et qui, jusqu'à présent, n'a pas trop fait de bêtises sur mon IMAP. Ce client, pourtant pas réputé pour sa qualité, c'est évidemment Mail.app.&lt;/p&gt;    &lt;p&gt;Un gros défauts de Mail.app (une fois configuré pour éviter toutes les fonctions décoratives qui ne servent à rien), est qu'il ne gère pas nativement PGP. Il faut donc, pour profiter de la vérification des mails mais également pour signer ses mails, installer GPGMail, un petit plug-in qui fonctionne, on va dire, pas trop mal.&lt;/p&gt;


&lt;p&gt;En tout cas, GPGMail a toujours fonctionné correctement sur mon portable, mais depuis que celui-ci est en réparation (hum, d'ailleurs, j'aimerais bien savoir ce qu'il devient !), je suis obligé de travailler sur le fixe, et donc d'utiliser entre autre mon client mail sur le fixe. Malheureusement, sur mon fixe, GPGMail n'a &lt;strong&gt;jamais&lt;/strong&gt; réussi à vérifier une signature. Bizarre... les mêmes messages étaient pourtant correctement vérifiés par mon portable.&lt;/p&gt;


&lt;p&gt;Comme, ça fait quelques temps que j'envisage d'ajouter le support de PGP (via GPG) à &lt;a href=&quot;http://opensource.polytechnique.org/banana&quot;&gt;Banana&lt;/a&gt;, j'ai voulu regarder plus en détail comment fonctionne la signature d'un message. J'ai donc commencé à prendre des mails signés dans Mail.app, à en enregistrer les sources sur mon disque dur et à essayer de vérifier les signatures à la main, puis avec une version légèrement hackée de Banana. Malheureusement, ça n'a jamais fonctionner.&lt;/p&gt;


&lt;p&gt;J'ai demandé à NC s'il pouvait me donner les sources d'un mail signé qui a le mérite d'apparaître comme correctement signé chez lui, et mal signé chez moi. J'ai comparé les 2 versions du mail... et le &lt;code&gt;diff&lt;/code&gt; a été on ne peut plus troublant&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;diff&quot;&gt;--nextPart1631992.9B81mC3O8N&lt;br /&gt;
&lt;span style=&quot;color: #991111;&quot;&gt;-Content-Type: text/plain;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #991111;&quot;&gt;- &amp;nbsp;charset=&amp;quot;iso-&lt;span style=&quot;&quot;&gt;8859&lt;/span&gt;-&lt;span style=&quot;&quot;&gt;1&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;Content-Transfer-Encoding: quoted-printable&lt;br /&gt;
&lt;span style=&quot;color: #00b000;&quot;&gt;+Content-Type: text/plain;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #00b000;&quot;&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; charset=iso-&lt;span style=&quot;&quot;&gt;8859&lt;/span&gt;-1&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;Content-Disposition: inline&lt;/code&gt;


&lt;p&gt;Le contenu de la partie signée n'est pas identique dans les deux mails. Pour ceux qui ne connaissent pas la structure d'un mail signé, je les invite à jeter un coup d'oeil à la &lt;a href=&quot;http://www.faqs.org/rfcs/rfc1847.html&quot;&gt;RFC1847&lt;/a&gt; qui se résume au schéma suivant&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
Content-Type: multipart/signed; protocol=&amp;quot;TYPE/STYPE&amp;quot;;
         micalg=&amp;quot;MICALG&amp;quot;; boundary=&amp;quot;Signed Boundary&amp;quot;

--Signed Boundary
Stuff to sign

--Signed Boundary
Signature

--Signed Boundary--
&lt;/pre&gt;


&lt;p&gt;La partie différente entre chez NC et chez moi est la partie &lt;code&gt;stuff to sign&lt;/code&gt; (en fait ce sont les en-têtes de la partie signée du message).&lt;/p&gt;


&lt;p&gt;Donc, je me suis replongé dans les options de Mail.app&amp;nbsp;: pourquoi modifie-t-il les sources de mon mail&amp;nbsp;? quelle est l'option qui est différente entre mon portable et mon fixe&amp;nbsp;? J'ai recherché dans les paramètres d'affichage et d'édition sans succès... et puis je me suis dit que j'allais regarder la configuration de mon compte IMAP.&lt;/p&gt;


&lt;p&gt;Une différence majeure entre mon fixe et mon portable est que mon portable est susceptible de ne pas être constamment connecté au serveur IMAP, donc il est configuré pour conserver une copie de tous les mails alors que sur mon fixe, Mail.app est sur la même machine que le serveur IMAP, pourquoi irais-je faire une copie supplémentaire des mails (ce qui se concrétiserait par des accès disques concurrents et quelques centaines de méga-octets de données dupliquées)&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Pourquoi&amp;nbsp;? et bien maintenant j'ai ma réponse... en demandant à Mail.app de garder une copie des mails, GPGMail arrive à vérifier les signatures, donc, dans ces conditions, il a accès aux sources non modifiées. Il y a donc quelque part dans Mail.app un outil qui transforme les sources des mails... assez hallucinant&amp;nbsp;! Il faut donc que je considère que si je demande à Mail.app de m'afficher les sources d'un message qui se trouve sur un serveur IMAP sans faire de copie locale, il est possible (probable ?) que les sources en question ne soient pas les vraies sources du message mais une version &lt;em&gt;remasterisée&lt;/em&gt; par Apple.&lt;/p&gt;


&lt;p&gt;Même si je ne me fais pas trop d'illusion sur le sujet, j'espère que ce genre de détails (tout comme également la gestion des URLs dans le &lt;code&gt;format=flowed&lt;/code&gt;, ou encore l'affichage de l'arborescence des message...) sera corrigé dans Leopard.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/06/11/Mailapp-IMAP-et-signatures#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/06/11/Mailapp-IMAP-et-signatures#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/31</wfw:commentRss>
      </item>
    
  <item>
    <title>Khtml2png 2.6.5 est sorti</title>
    <link>http://blog.mymind.fr/post/2007/06/05/Khtml2png-265-est-sorti</link>
    <guid isPermaLink="false">urn:md5:58bbe8d3b518ea224316f6e597d9ddbb</guid>
    <pubDate>Tue, 05 Jun 2007 22:31:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>Devel</category><category>khtml2png</category>    
    <description>    &lt;p&gt;Après 3 mois d'un travail pas très intensif, une nouvelle version de &lt;a href=&quot;http://khtml2png.sf.net&quot;&gt;khtml2png&lt;/a&gt; est disponible. Cette version est partie du fait que les versions précédentes du programme ont parfois du mal à gérer les grandes captures d'écran (en fait, des bugs peuvent apparaître dès que la taille de la zone à capturer est plus grande que la taille affichable).&lt;/p&gt;


&lt;p&gt;Donc, rapidement après la sortie de la 2.6.0, j'avais envoyé un correctif (en fait une réécriture du moteur de rendu) au développeur de &lt;code&gt;khtml2png&lt;/code&gt;. Malheureusement, ce correctif ne fonctionnait pas correctement chez lui. Donc, pendant 3 mois, j'ai fait du débuggage à distance&amp;nbsp;: j'envoie une version modifiée (1 ou 2 lignes à chaque fois), j'attends 2 ou 3 semaine une réponse, etc... Du développement efficace&amp;nbsp;!&lt;/p&gt;


&lt;p&gt;Bon, toujours est-il que maintenant, la version 2.6.5 fonctionne à la fois chez moi (à la fois Debian + xvnc et sur MacOS X), et chez Hauke (sur Debian également, mais avec des réglages différents).&lt;/p&gt;


&lt;p&gt;Le Changelog annonce&amp;nbsp;:&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;fix: Now produces screenshots on my Debian Etch system under KDE 3.5.5 without glitches. &lt;br /&gt;
fix: Maybe better working on other systems too. Please test.&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;J'aimerais y rajouter quelques points&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;meilleur moteur de rendu (qui ne scroll plus, mais déplace la fenêtre pour s'affranchir de certains bugs de KDE et/ou Qt)&lt;/li&gt;
&lt;li&gt;meilleure détection de la taille de la capture à réaliser&lt;/li&gt;
&lt;li&gt;possibilité de choisir le comportement de &lt;code&gt;khtml2png&lt;/code&gt; face aux redirections, au javascript, au java, au flash... via la ligne de commande&lt;/li&gt;
&lt;li&gt;la détection automatique de la dimension par un &lt;code&gt;id&lt;/code&gt; devient compatible avec le format utilisé dans les version &amp;lt;= 2.5&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comme d'habitude, vous pouvez télécharger &lt;a href=&quot;http://blog.mymind.fr/mind/public/khtml2png/khtml2png-fru-last.tar.bz2&quot;&gt;ma dernière version du programme&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/06/05/Khtml2png-265-est-sorti#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/06/05/Khtml2png-265-est-sorti#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/30</wfw:commentRss>
      </item>
    
  <item>
    <title>Spaces</title>
    <link>http://blog.mymind.fr/post/2007/06/02/Spaces</link>
    <guid isPermaLink="false">urn:md5:be17c145e8a970e2e9cccd4d3e6c66a7</guid>
    <pubDate>Sat, 02 Jun 2007 14:44:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>Mac</category><category>VirtueDesktops</category>    
    <description>&lt;p&gt;Comme un certain nombre de personnes le sait déjà, j'ai repris le développement de &lt;a href=&quot;http://virtuedesktops.info&quot;&gt;VirtueDesktops&lt;/a&gt; depuis quelques semaines. Dans un premier temps je n'avais pas regardé le fonctionnement bas niveau du programme, mais la semaine dernière j'ai commencé à rechercher dans les sources &quot;Comment Virtue fait-il pour cacher les fenêtres, faire les transitions etc... ?&quot;.&lt;/p&gt;    &lt;p&gt;A ma grande surprise, tout ceci est en fait géré nativement par MacOS X... la bibliothèque CoreGraphics contient en effet quelques fonctions cachées qui gèrent l'attribution d'une fenêtre à un Workspace et les transitions entre ces Workspaces. On peut trouver la liste complète de ces fonctions sur la &lt;a href=&quot;http://trac.virtuedesktops.info/browser/trunk/Shared/Headers/CGSPrivate.h&quot;&gt;SVN de VirtueDesktops&lt;/a&gt;.&lt;/p&gt;

&lt;code class=&quot;c_mac&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;extern&lt;/span&gt; OSStatus CGSMoveWorkspaceWindowList&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; CGSConnection connection, CGSWindow &lt;span style=&quot;color: #000000;&quot;&gt;*&lt;/span&gt;wids, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; count, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; toWorkspace&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;extern&lt;/span&gt; OSStatus CGSGetWorkspace&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; CGSConnection cid, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;*&lt;/span&gt;workspace&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;extern&lt;/span&gt; OSStatus CGSGetWindowWorkspace&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; CGSConnection cid, &lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; CGSWindow wid, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;*&lt;/span&gt;workspace&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;extern&lt;/span&gt; OSStatus CGSSetWorkspace&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;const&lt;/span&gt; CGSConnection cid, &lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt; workspace&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/code&gt;


&lt;p&gt;VirtueDesktops (et également DesktopsManager) n'est qu'une interface graphique qui tente d'utiliser ces fonctions. Et là &lt;a href=&quot;http://www.apple.com/fr/macosx/leopard/spaces.html&quot;&gt;Spaces&lt;/a&gt; part avec une longueur d'avance car contrairement à VirtueDesktops, il sera facile pour Apple de gérer les ouvertures, fermetures et masquage d'application ce qui est à mon avis le plus gros point faible de Virtue. J'ai beaucoup travaillé là-dessus et je pense arriver actuellement aux limites de ce qu'il est possible de faire avec un gestionnaire de bureaux virtuels sur Tiger.&lt;/p&gt;


&lt;p&gt;Un autre problème de VirtueDesktops est l'accès à l'ordonnancement des fenêtres. Comment être sûr que lorsqu'on arrive sur un bureau les fenêtres sont dans le bon ordre&amp;nbsp;? Idéalement il faudrait enregistrer l'ordre en temps réel et le restaurer lors du retour sur le bureau. Ceci permettrait également de toujours savoir quelle application activer lorsqu'on arrive sur un bureau, simplement en utilisant la fenêtre qui se trouve au premier plan.&lt;/p&gt;


&lt;p&gt;Voilà, je me suis certes lancé dans une cause perdue d'avance, mais je suis tout de même content du résultat obtenu lors de ces dernières semaines. Virtue a désormais un comportement qui correspond à ce que j'attends d'un gestionnaire de bureaux virtuels&amp;nbsp;: quand je change d'application il va sur le bureau adéquat, et quand je change de bureau, il active bien la dernière application que j'ai utilisée sur ce bureau.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/06/02/Spaces#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/06/02/Spaces#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/29</wfw:commentRss>
      </item>
    
  <item>
    <title>Et si on oubliait les bases ?</title>
    <link>http://blog.mymind.fr/post/2007/05/26/Et-si-on-oubliait-les-bases</link>
    <guid isPermaLink="false">urn:md5:fe3ef04de8c5c8b32ac7e89741c86760</guid>
    <pubDate>Sat, 26 May 2007 11:40:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>Devel</category><category>Mac</category><category>POSIX</category><category>VirtueDesktops</category>    
    <description>&lt;p&gt;MacOS X est un Unix... compatible POSIX. Voilà ce qu'un certain nombre de personnes semblent oublier assez fréquemment. C'est assez dommage quand ces personnes programment pour MacOS, on se retrouve parfois avec du code complexe pour réécrire des fonctions POSIX (en moins bien ?).&lt;/p&gt;    &lt;p&gt;En fait si je parle de ça, c'est parce que je viens de rencontrer le problème dans le cadre du développement de &lt;a href=&quot;http://blog.mymind.fr/post/2007/05/18/VirtueDesktops-revient&quot;&gt;VirtueDesktops&lt;/a&gt;. Il se trouve qu'en parcourant le tracker du projet je suis tombé sur le &lt;a href=&quot;http://trac.virtuedesktops.info/ticket/115&quot;&gt;ticket 115&lt;/a&gt; qui s'intitule&amp;nbsp;:&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;Patch to check group id of 'procmod' group&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;C'est intéressant... jusqu'à maintenant Virtue suppose que le gid du groupe procmod est celui par défaut de MacOS (c'est à dire qu'il vaut 9)... et le problème est donc que si un utilisateur a un procmod différent (ou si Apple décide un jour de changer le gid du groupe), le code actuel peut avoir des résultats inattendus, il faut donc faire un code plus portable qui recherche le gid de procmod au lieu de le stocker en dur. Ce n'est clairement pas une mauvaise idée&amp;nbsp;! Seul problème, le patch soumis est le suivant (au cas où certain voudrait réutiliser ce code, je tiens à signaler que c'est une mauvaise idée !)&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;c&quot;&gt;&lt;span style=&quot;color: #339933;&quot;&gt;#define NI_DOMAIN &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;.&amp;quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #339933;&quot;&gt;#define NI_PATH &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;/name=groups/name=procmod&amp;quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #339933;&quot;&gt;#define NI_KEY&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;quot;gid&amp;quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #666666; font-style: italic;&quot;&gt;// Sucked from netinfo-369.5/tools/niutil/niutil.c&lt;/span&gt;&lt;br /&gt;
ni_status ni_read_single_prop&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;**&lt;/span&gt;property&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;NI_DOMAIN&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; NI_PATH&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; NI_KEY&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #993333;&quot;&gt;char&lt;/span&gt; myname&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;ni_read_single_prop&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; bool opt_tag &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #993333;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; timeout &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ni_namelist nl&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #993333;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;domain&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ni_id dir&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ni_status ret&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;ret &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; do_open&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;myname&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt;domain&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; opt_tag&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; timeout&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; ret&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* args[1] should be a directory specification */&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; ni2_pathsearch&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;domain&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt;dir&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;ret &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; NI_OK&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fprintf&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;stderr&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;%s: can't open directory %s: %s&lt;br /&gt;
&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; myname&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; ni_error&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;ret&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ni_free&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;domain&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; ret&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/* get the property values for args[2] */&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NI_INIT&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt;nl&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; ni_lookupprop&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;domain&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt;dir&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt;nl&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;ret &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; NI_OK&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fprintf&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;stderr&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;%s: can't get property %s in directory %s: %s&lt;br /&gt;
&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; myname&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; args&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; ni_error&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;ret&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ni_free&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;domain&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; ret&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;nl.&lt;span style=&quot;color: #202020;&quot;&gt;ni_namelist_len&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fprintf&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;stderr&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;%s: expected length = 1, found length = %d&lt;br /&gt;
&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; myname&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; nl.&lt;span style=&quot;color: #202020;&quot;&gt;ni_namelist_len&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; NI_FAILED&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;property &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;calloc&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;strlen&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;nl.&lt;span style=&quot;color: #202020;&quot;&gt;ni_namelist_val&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;sizeof&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; strcpy&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;property&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; nl.&lt;span style=&quot;color: #202020;&quot;&gt;ni_namelist_val&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ni_namelist_free&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;&amp;amp;&lt;/span&gt;nl&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ni_free&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;domain&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; NI_OK&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Donc que fait cette fonction&amp;nbsp;? C'est assez simple&amp;nbsp;: elle utilise l'utilitaire NetInfo d'Apple pour lire les informations relatives au chemin &lt;code&gt;/groups/procmod&lt;/code&gt;. Une fois là dedans elle copie la valeur stockée à la clé &lt;code&gt;gid&lt;/code&gt; et renvoie cette chaîne dans le pointeur passé en argument.&lt;/p&gt;


&lt;p&gt;Il n'y a pas à dire... c'est une solution qui devrait fonctionner (enfin j'ai même un doute, car je ne vois pas le groupe procmod apparaître quand je regarde dans NetInfo). Seulement cette solution montre clairement que la personne qui l'a écrite savait que MacOS utilise un système de groupes, mais avait oublié qu'en fait c'est avant tout un système POSIX. Et là, ce qui est intéressant c'est que sous MacOS X on a accès à l'API POSIX... en particulier à la fonction &lt;code&gt;getgrnam&lt;/code&gt; qui retourne les informations sur un groupe à partir de son nom.&lt;/p&gt;


&lt;p&gt;Donc, pas besoin de dépendance vers NetInfo, pas besoin d'une recherche dans une arborescence abstraite&amp;nbsp;: NetInfo n'est qu'une abstraction de la couche Unix pour simplifier l'accès aux données par les utilisateurs... mais ça ne doit pas être un framework d'abstraction de l'API POSIX ce qui entraîne nécessairement du code moins portable (et surtout, moins lisible dans le cas présent), moins rapide et plus lourd.&lt;/p&gt;


&lt;p&gt;Ici, le code est utilisé dans un programme en C qui est chargé de mettre un objet dans le groupe procmod pour autoriser Virtue à effectuer certaines actions qui nécessitent un accès privilégié au serveur graphique... ce programme ne fait &lt;em&gt;que&lt;/em&gt; changer les permissions. Pourquoi utiliser une API lourde et spécifique à MacOS alors que ce type de programme pourrait clairement être utilisé sur n'importe quel Unix&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Voici donc une solution qui fait la même chose que la fonction ci-dessus, en mieux et surtout en beaucoup moins de lignes&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;c&quot;&gt;&lt;span style=&quot;color: #339933;&quot;&gt;#include &amp;lt;grp.h&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #993333;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; getProcmodGid&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #993333;&quot;&gt;struct&lt;/span&gt; group&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; groupDesc&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #993333;&quot;&gt;int&lt;/span&gt; gid &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; groupDesc &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; getgrnam&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;procmod&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;groupDesc&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gid &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; groupDesc&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;gr_gid&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; free&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;groupDesc&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; gid&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Pourquoi cette solution est-elle meilleure&amp;nbsp;?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;elle retourne un entier... on a donc pas besoin de faire une conversion a posteriori&lt;/li&gt;
&lt;li&gt;elle utilise l'API POSIX et est donc utilisable sur n'importe quel OS POSIX (donc quasiment tous... à l'exception de Windows)&lt;/li&gt;
&lt;li&gt;elle évite toute manipulation inutile de chaîne de caractères&lt;/li&gt;
&lt;li&gt;elle est ne nécessite pas de charger une bibliothèque supplémentaire&amp;nbsp;: &lt;code&gt;getgrnam&lt;/code&gt; est dans la &lt;code&gt;libc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;elle est drôlement plus courte non&amp;nbsp;?&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/05/26/Et-si-on-oubliait-les-bases#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/05/26/Et-si-on-oubliait-les-bases#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/28</wfw:commentRss>
      </item>
    
  <item>
    <title>Mac c'est bien... mais pas top</title>
    <link>http://blog.mymind.fr/post/2007/05/22/Mac-cest-bien-mais-pas-top</link>
    <guid isPermaLink="false">urn:md5:0a5eff7c3162452e382fd9eb6f893e56</guid>
    <pubDate>Tue, 22 May 2007 21:44:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Général</category>
        <category>Mac</category>    
    <description>    &lt;p&gt;Bon, la suite des mes problèmes avec les machines Apple&amp;nbsp;!&lt;/p&gt;


&lt;p&gt;Alors que la carte mère de mon portable a été changée il y a un peu plus d'un mois, mon portable a décidé aujourd'hui d'arrêter de vouloir fonctionner. Symptômes&amp;nbsp;? Il s'allume (des fois), fonctionne (rarement) quelques secondes puis s'éteint brutalement... et ce qu'il démarre sur secteur, sur batterie ou les deux ensemble, que ce soit sur le disque dur, sur le DVD d'installation ou encore en mode &lt;em&gt;target&lt;/em&gt; (en tant que disque dur externe).&lt;/p&gt;


&lt;p&gt;En plus ça lui arrive de s'allumer tout seul alors que ça fait plusieurs minutes que je ne l'ai plus touché. Un autre symptôme étrange, la diode de la prise magsafe clignote bizarrement lorsque la machine n'est pas sous-tension (pas un clignotement vert/rouge, mais une lumière verte continue qui scintille un peu). Tout ça me laisse penser que c'est l'alimentation qui est en cause.&lt;/p&gt;


&lt;p&gt;Voilà... les joies des machines de qualité, d'autant plus que la garantie de la machine a expirée il y a &lt;strong&gt;2&lt;/strong&gt; jours (le 19 mai).&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/05/22/Mac-cest-bien-mais-pas-top#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/05/22/Mac-cest-bien-mais-pas-top#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/27</wfw:commentRss>
      </item>
    
  <item>
    <title>VirtueDesktops revient...</title>
    <link>http://blog.mymind.fr/post/2007/05/18/VirtueDesktops-revient</link>
    <guid isPermaLink="false">urn:md5:5c8f94c8bfb5d09c36d4dd26d5f77d45</guid>
    <pubDate>Fri, 18 May 2007 12:25:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>Devel</category><category>Mac</category><category>VirtueDesktops</category>    
    <description>&lt;p&gt;Voici plus ou moins trois mois que j'ai découvert &lt;a href=&quot;http://synergy2.sf.net&quot;&gt;synergy&lt;/a&gt;, c'est vraiment très agréable de pouvoir contrôler les deux ordinateurs sans changer de clavier/souris continuellement. Seul problème, c'est que sur la machine qui héberge le serveur &lt;code&gt;synergy&lt;/code&gt;, &lt;a href=&quot;http://virtuedesktops.info&quot;&gt;VirtueDesktops&lt;/a&gt;, un &lt;em&gt;excellent&lt;/em&gt; gestionnaire de bureaux virtuels pour MacOS, n'arrête pas de crasher. J'avais donc posté un bugreport sur le trac de Virtue... malheureusement pour diverses raisons, Tony Arnold a décidé peu après de stopper le développement de Virtue.&lt;/p&gt;    &lt;p&gt;J'ai donc pris mon courage à 2 mains, et je me suis doucement plongé dans le code de VirtueDesktops (c'est vraiment bien les applications OpenSource). Il y a maintenant deux semaines, j'ai soumis le patch permettant de corriger le crash dont je souffrais. Depuis, ce patch a été publié ce qui a conduit la &lt;a href=&quot;http://virtuedesktops.info/index.php/2007/05/14/virtuedesktops-054-beta-3/&quot;&gt;release de la bêta 3 de Virtue 0.54&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;Je me suis relancé dans le développement cette semaine en me fixant comme objectif de corriger plusieurs comportements énervants de Virtue. Par exemple, si je dis que &lt;code&gt;Mail.app&lt;/code&gt; doit être sur le bureau Mail, je veux que &lt;strong&gt;toutes&lt;/strong&gt; les fenêtres de &lt;code&gt;Mail.app&lt;/code&gt; aillent forcément sur ce bureau. Seul problème, c'est que lorsque je reçois une notification de l'arrivée d'un nouveau mail et que je clique sur cette notification, une fenêtre avec le message s'ouvre sur le bureau courant, et Virtue tourne pour atteindre le bureau de Mail.app... résultat&amp;nbsp;: j'ai changé de bureau mais je n'ai pas accès à la fenêtre que je voulais voir. J'ai corrigé ce comportement, désormais, la fenêtre est automatiquement déplacée sur le bureau de &lt;code&gt;Mail.app&lt;/code&gt; lors de son ouverture.&lt;/p&gt;


&lt;p&gt;Autres corrections diverses&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lorsqu'on ferme une application Virtue reste sur le bureau courant (sauf si il n'y a plus rien sur le bureau courant)&lt;/li&gt;
&lt;li&gt;lorsqu'on choisi de changer de bureau, Virtue active désormais la dernière application active connue pour le nouveau bureau&lt;/li&gt;
&lt;li&gt;lorsqu'on restaure une fenêtre qui était dans le Dock, soit l'application a le droit d'être sur le bureau courant et la fenêtre est affichée sur ce bureau sans chercher à changer de bureau, soit l'application est attribuée à un bureau et dans ce cas la fenêtre est restaurée sur le bureau de l'application et Virtue change de bureau&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ces changements ont abouti à la &lt;a href=&quot;http://virtuedesktops.info/index.php/2007/05/18/virtuedesktops-054-beta-4/&quot;&gt;bêta 4&lt;/a&gt; et se résument à&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Changing to desktops when you launch, activate, deactivate, minimise, restore or quit an application should be much more consistent;&lt;/li&gt;
&lt;li&gt;Window ordering when changing desktops should be much more consistent;&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/05/18/VirtueDesktops-revient#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/05/18/VirtueDesktops-revient#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/26</wfw:commentRss>
      </item>
    
  <item>
    <title>La Banane et l'escargot</title>
    <link>http://blog.mymind.fr/post/2007/05/07/La-Banane-et-lescargot</link>
    <guid isPermaLink="false">urn:md5:f4eb2372ed96701c79b70613de7c59fe</guid>
    <pubDate>Mon, 07 May 2007 17:44:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Polytechnique.org</category>
        <category>Banana</category><category>Devel</category><category>PHP</category>    
    <description>&lt;p&gt;La release de &lt;a href=&quot;http://opensource.polytechnique.org/banana/&quot;&gt;Banana&lt;/a&gt; 1.6 en même temps que celle de plat/al 0.9.14 a mis en évidence un certain nombre de faiblesses dans Banana. En particuliers la génération du spool (mise en cache de l'arborescence des messages) et des flux RSS s'est révélé extrêmement lourde pour plusieurs raisons&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;l'accès aux mbox des Mailing-Lists nécessite d'appel du &lt;code&gt;mbox-helper&lt;/code&gt;, et donc un &lt;code&gt;fork&lt;/code&gt;... opération lourde, qui répétée plusieurs fois par mbox devient rapidement très lourde lorsqu'on a plusieurs dizaines de Mailing-Lists.&lt;/li&gt;
&lt;li&gt;le traitement des données par PHP est loin d'être immédiats... et il y a clairement des goulots d'étranglement dans le code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;C'est pour ces raisons que j'ai passé Banana au &lt;code&gt;profiler&lt;/code&gt;, c'est à dire que j'ai analysé l'exécution de Banana à l'aide d'un outil qui permet de tracer l'exécution du programme et mettant un accent particuliers sur le temps d'exécution de chaque fonction. L'outil que j'ai trouvé pour faire ça est &lt;a href=&quot;http://www.xdebug.org&quot;&gt;xdebug&lt;/a&gt;, utilisé conjointement à &lt;a href=&quot;http://kcachegrind.sourceforge.net/&quot;&gt;KCacheGrind&lt;/a&gt;.&lt;/p&gt;    &lt;h2&gt;Forks&lt;/h2&gt;


&lt;p&gt;Je dois avouer que lorsque j'avais fait mes tests, je n'avais pas plusieurs centaines de Mailing-Lists à traiter... et je ne m'attendais pas à ce qu'une fois passée en production le script de mise à jour des flux RSS puisse prendre toutes les ressources de la machine pendant plusieurs minutes. Il a donc fallu sérieusement restructurer la gestion des accès aux Mailing-Lists pour restreindre au maximum le nombre d'accès au &lt;code&gt;mbox-helper&lt;/code&gt; (un petit programme écrit en C qui se charge de tous les accès aux mbox), et, en cas d'accès, limiter au maximum le temps passer sur le &lt;code&gt;mbox-helper&lt;/code&gt;.&lt;/p&gt;


&lt;p&gt;Donc désormais le &lt;code&gt;mbox-helper&lt;/code&gt; n'est plus appelé que si la mbox a changé depuis le dernier passage (le changement étant détecté par la taille du fichier). Ce qui permet donc de supprimer le lancement d'environ 500 &lt;code&gt;mbox-helper&lt;/code&gt; lors des rafraîchissements des spools (en effet, un nombre négligeable de Mailing-List aura des nouveaux messages lors du passage du script toutes les 5, 10 ou 20 minutes). Ajouté à cela la correction d'un bug qui faisait que l'appel au &lt;code&gt;mbox-helper&lt;/code&gt; oubliait de spécifier l'offset où chercher le message à traiter et qui forçait donc le &lt;code&gt;mbox-helper&lt;/code&gt; à relire la totalité de la mbox, on peut se permettre de supposer que la prochaine version de Banana sera plus efficace pour la gestion des mbox.&lt;/p&gt;



&lt;h2&gt;Array_shift&lt;/h2&gt;


&lt;h3&gt;Piles&lt;/h3&gt;


&lt;p&gt;Il est souvent extrêment pratique d'utiliser une pile de données. Cela permet de traiter les informations dans l'ordre de la pile sans excès de mémoire puisque chaque élément est dépilé avant d'être traité. C'est une technique que j'aime particulièrement lorsque j'ai une suite de lignes à traiter&amp;nbsp;: je prend un tableau contenant une ligne par entrée et je le parcours avec &lt;code&gt;array_shift&lt;/code&gt; qui permet de dépiler le premier élément du tableau. On obtient ainsi un code de la forme&lt;/p&gt;

&lt;code class=&quot;php&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;!&lt;/span&gt;&lt;a href=&quot;http://www.php.net/is_null&quot;&gt;&lt;span style=&quot;color: #990000;&quot;&gt;is_null&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$line&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;a href=&quot;http://www.php.net/array_shift&quot;&gt;&lt;span style=&quot;color: #990000;&quot;&gt;array_shift&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$lines&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; do_something&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$line&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
do_something&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$lines&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Un &lt;code&gt;foreach&lt;/code&gt; peut très bien faire la même chose, mais on perd les avantages de la piles. Avec cette structure, pour avoir le même comportement que la boucle précédente, il faut ajouter un &lt;code&gt;unset()&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;php&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;foreach&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$lines&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #000088;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;=&amp;gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$value&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; do_something&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$line&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;a href=&quot;http://www.php.net/unset&quot;&gt;&lt;span style=&quot;color: #990000;&quot;&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$lines&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
do_something&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$lines&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Certes le &lt;code&gt;foreach&lt;/code&gt; sera sensiblement plus rapide que le &lt;code&gt;while&lt;/code&gt;/&lt;code&gt;array_shift()&lt;/code&gt; car il comprend un appel de fonction à chaque itération, mais on peut s'attendre raisonnablement à ce que cet appel soit en O(1), et ait donc un coût négligeable.&lt;/p&gt;


&lt;h3&gt;Profiler&lt;/h3&gt;


&lt;p&gt;Là où il y a un problème c'est que le profiler m'indique que &lt;code&gt;array_shift&lt;/code&gt; prend 57% du temps d'exécution de Banana. Ces 57% sont partagés entre 80000 appels à la fonction, mais le plus marquant c'est que parmi ces 80000 appels, ce ne sont que 24000 d'entre eux qui prennent la quasi-totalité du temps. Pourquoi ces appels particuliers sont-ils si lourd alors que les 60000 autres ont un coût parfaitement négligeable.&lt;/p&gt;


&lt;p&gt;La seule différence entre ces deux cas d'appels c'est que les &lt;em&gt;lourds&lt;/em&gt; traitent un énorme tableau de 24000 lignes, alors que les &lt;em&gt;légers&lt;/em&gt; traitent un grand nombre de petits tableaux de quelques dizaines de lignes chacun. Il est donc extrêmement clair que &lt;code&gt;array_shift&lt;/code&gt; &lt;strong&gt;n'est pas&lt;/strong&gt; une fonction en O(1)... J'ai donc changé la structure de code qui reflétait la structure de données par une simple boucle qui perd en lisibilité dans &lt;a href=&quot;http://opensource.polytechnique.org/viewsvn/diff.php?path=/trunk/banana/mbox.inc.php&amp;amp;rev=248&amp;amp;repname=Banana&quot;&gt;ce patch&lt;/a&gt;. Après ce changement, les 60000 &lt;code&gt;array_shift&lt;/code&gt; restant ne prennent que 0.16% du temps d'exécution de Banana...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/05/07/La-Banane-et-lescargot#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/05/07/La-Banane-et-lescargot#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/25</wfw:commentRss>
      </item>
    
  <item>
    <title>Vista ?</title>
    <link>http://blog.mymind.fr/post/2007/05/03/Vista</link>
    <guid isPermaLink="false">urn:md5:62bd8f650a94f0c10c5ff0ef44878622</guid>
    <pubDate>Thu, 03 May 2007 16:07:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Général</category>
        <category>Vista</category><category>Windows</category>    
    <description>&lt;p&gt;Étant curieux, en tout cas pour ce qui est informatique, je n'ai pas pu m'empêcher de mettre un Windows Vista en double boot sur mon MacBook Pro... Grâce à BootCamp, l'installation ne pose pas de problème. Par contre une fois l'OS installé, je n'ai pas arrêtez d'enchaîner les petits problèmes qui ont été plus une perte de temps qu'autre chose...&lt;/p&gt;    &lt;h3&gt;Accueil réussi&lt;/h3&gt;


&lt;p&gt;Les problèmes commencent dès l'arrivée sous Vista. Déjà un premier coup d'oeil&amp;nbsp;: c'est loin d'être laid à regarder... même si les ombres sont moins agréables que celles de MacOS X et que les effets de flouté sous les fenêtres me fatiguent un peu. Quand on arrive sous Vista, on tombe sur la fenêtre &lt;em&gt;Accueil de Windows&lt;/em&gt; ci-dessous&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.mymind.fr/public/screenshots/Vista/Vista-accueil1.PNG&quot;&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/Vista/.Vista-accueil1_m.jpg&quot; alt=&quot;Fenêtre d&amp;#039;accueil de Windows Vista&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Cet écran est sympathique&amp;nbsp;: un navigateur pratique pour circuler entre les fonctionnalités de Windows... le problème provient lorsque justement je clique sur une de ces fonctionnalités, par exemple &quot;Transfert de fichiers&quot;... rien ne se passe. Enfin, je m'attendais à voir surgir un assistant, mais rien n'apparaît. Après quelques secondes, je me rends compte qu'en fait l'en-tête de la fenêtre à changé&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.mymind.fr/public/screenshots/Vista/Vista-accueil2.PNG&quot;&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/Vista/.Vista-accueil2_m.jpg&quot; alt=&quot;Fenêtre accueil après sélection&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Il faut cliquer sur le texte en bas de l'en-tête pour enfin avoir le logiciel de Transfert de fichier... qui se lance dans un environnement bizarre en plein écran avec une petite fenêtre au milieu.&lt;/p&gt;



&lt;h3&gt;Personnalisation&lt;/h3&gt;


&lt;p&gt;Le premier réflexe après avoir installé un nouveau système, c'est de le personnaliser. Ceci passe donc par le changement du fond d'écran, de l'écran de veille, etc... Sous Vista, ceci se fait via une page du panneau de configuration&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.mymind.fr/public/screenshots/Vista/Vista-apparence.PNG&quot;&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/Vista/.Vista-apparence_m.jpg&quot; alt=&quot;Réglages de l&amp;#039;apparence de Windows&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;C'est très bien, ça marche... sauf que lorsqu'on arrive à la catégorie &lt;em&gt;Thèmes&lt;/em&gt;, changer le thème change &lt;strong&gt;tous&lt;/strong&gt; les réglages qu'on avait faits précédemment pour les remplacer par ceux du thème sélectionné... L'art et la manière de perdre 10 minutes à faire 2 fois la même configuration, et à refaire tout ce que j'avais déjà fait alors que si &lt;em&gt;Thèmes&lt;/em&gt; se trouvait en première place de cette liste, j'aurais d'abord choisi un thème avant de le personnaliser.&lt;/p&gt;



&lt;h3&gt;Inquiétude&lt;/h3&gt;


&lt;p&gt;Un autre problème se manifeste sous Windows Vista&amp;nbsp;: les ventilateurs de mon MacBook Pro tournent quasiment à fond... alors qu'en temps normal c'est une machine silencieuse, sous Vista mon portable génère un fond sonore désagréable. Comme après avoir cherché un peu, je trouve qu'il y a un &lt;em&gt;gadget&lt;/em&gt; (ce n'est pas du tout la même chose que les &lt;em&gt;widgets&lt;/em&gt; de Dashboard) pour le panneau latéral de Windows qui permet de (plus ou moins) monitorer la charge CPU et l'occupation mémoire, je l'active. Et là, quelle bonne surprise&amp;nbsp;! Vista tourne à 15% proc comme occupation de croisière (étant donné que j'ai un dual-core, dois-je considérer que c'est 30% d'un des coeurs ?)... Quand je bouge la souris (si si, ça fait varier la charge), une fenêtre, ou que je travail sur une application, la charge proc augmente. Par exemple, les deux captures suivantes montre la charge de la machine lorsque j'utilise le logiciel de capture d'écran&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la première lorsque je capture par sélection (une fois la sélection terminée, il est monté aussi à 30% CPU pendant quelques secondes)&lt;/li&gt;
&lt;li&gt;la deuxième lorsque je capture par fenêtre (dans ce cas, il prend du processeur pour faire de joli effets graphiques pour mettre en valeur la fenêtre sélectionnée)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;http://blog.mymind.fr/public/screenshots/Vista/Vista-performances.PNG&quot; alt=&quot;Occupation du processeur à vide&quot; /&gt; &lt;img src=&quot;http://blog.mymind.fr/public/screenshots/Vista/Vista-performances2.PNG&quot; alt=&quot;Occupation du processeur changement de fenêtre&quot; /&gt;&lt;/p&gt;


&lt;p&gt;C'est donc mon processeur qui gère les effets graphiques ??? Pourtant j'ai une bonne carte graphique (ATI X1600) et d'après les benchmarks effectués par Vista, j'ai même une bonne machine, bien adaptée à Vista... je n'ose pas imaginer ce que ça donnerait sur une machine un peu moins puissante.&lt;/p&gt;



&lt;h3&gt;Mais encore...&lt;/h3&gt;


&lt;p&gt;J'ai également passé beaucoup de temps à chercher comment diminuer l'espace disque occupé par Windows&amp;nbsp;: je n'ai alloué que 20Go à la partition pour Windows, et j'aimerais bien pouvoir y installer 2 ou 3 jeux quand même... donc limité la taille de la mémoire virtuelle, la taille de la corbeille... par contre j'ai mis plus d'une demi-heure à trouver comment désactiver la restauration système. Et j'ai eu de la chance de finir par trouver en décochant au hasard une case dans une fenêtre de configuration sur laquelle j'ai abouti sans trop savoir comment&amp;nbsp;!&lt;/p&gt;


&lt;p&gt;Je ne m'étendrais pas sur tous mes déboires avec le nouveau &lt;em&gt;menu démarrer&lt;/em&gt; de windows et le nouveau navigateur de programmes grâce auquel je n'ai toujours pas réussi à lancer une application du premier coup (à chaque fois je clique sur celle juste au-dessus), ni sur la gestion des droits d'accès qui n'arrêtent pas de me demander dans une jolie fenêtre sur un écran grisé si je veux continuer sans me demander de taper le moindre mot de passe (bah oui, mon compte ayant les droits d'administrateurs, je suppose que ça ne sert à rien de me demander un mot de passe), ni sur le temps et le nombre de clics nécessaires pour supprimer un fichier, ni sur Windows Mail qui ne trouve que 48 des 140 répertoires de mon serveur IMAP, ni même sur le pseudo-Exposé de Windows qui affiche les fenêtres les unes sur les autres et qui me force donc à scroller pour trouver celle que je veux alors qu'il serait tellement plus efficace de les mettre côte à côte (comme avec Exposé :).&lt;/p&gt;


&lt;p&gt;Donc, Vista c'est beau, mais c'est tout... Je trouve l'ergonomie du nouveau système de microsoft déplorable. Je suis bien content avec mon MacOS X qui utilise la carte graphique pour les effets graphiques, qui ne fait pas trop de fioritures et qui me permet de trouver rapidement ce que je cherche sans avoir à parcourir 50 menus.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/05/03/Vista#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/05/03/Vista#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/24</wfw:commentRss>
      </item>
    
  <item>
    <title>0.9.14 en ligne !</title>
    <link>http://blog.mymind.fr/post/2007/04/29/0914-en-ligne</link>
    <guid isPermaLink="false">urn:md5:200148e068514954b2f5974a8553116d</guid>
    <pubDate>Sun, 29 Apr 2007 19:09:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>Polytechnique.org</category>
        <category>Devel</category><category>platal</category>    
    <description>&lt;p&gt;Ca y est, comme annoncé dans &lt;a href=&quot;http://blog.mymind.fr/mind/post/2007/03/30/Un-apercu-de-la-version-0914-de-plat/al&quot;&gt;mon billet de fin mars&lt;/a&gt;, la version 0.9.14 de &lt;a href=&quot;http://opensource.polytechnique.org/platal&quot;&gt;plat/al&lt;/a&gt; est en ligne depuis vendredi soir. Comme expliqué précédemment, cette version apporte un grand nombre d'innovations comme &lt;a href=&quot;http://blog.mymind.fr/mind/post/2007/02/25/Un-client-RSS-pour-lire-les-Forums-NNTP-et-les-Mailing-Lists&quot;&gt;le flux RSS pour les Mailing-Lists et les Fora&lt;/a&gt;, la &lt;a href=&quot;http://blog.mymind.fr/mind/post/2007/03/15/Soundex-Francais&quot;&gt;recherche par proximité sonore améliorée&lt;/a&gt; et généralisée, un système d'annonces retravaillé pour offrir un approche plus conviviale, et bien sûr, le passage en UTF-8.&lt;/p&gt;


&lt;p&gt;Mais de tout cela, j'en ai déjà parlé... je tiens par contre à m'étendre sur les quelques fonctionnalités qui ont été développées durant le dernier mois (en fait, durant les dernières deux semaines de développement, le reste du temps ayant été consacré aux tests).&lt;/p&gt;    &lt;h2&gt;Recherche interactive&lt;/h2&gt;


&lt;p&gt;Caribou a réalisé un énorme travail sur la mise en place d'un remplissage automatique (auto-completion pour les geeks) sur la recherche avancée. Ainsi, lorsqu'on tape quelques caractères dans un champ, une liste de propositions apparaît avec pour chaque proposition le nombre de camarades correspondant à la requête. Ce qui donne par exemple&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.mymind.fr/mind/public/screenshots/select-ville.png&quot; alt=&quot;Auto-Completion sur les villes&quot; /&gt;&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.mymind.fr/mind/public/screenshots/select-pays.png&quot; alt=&quot;Auto-Completion sur les pays&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Par contre, là où cela devient très intéressant, c'est que l'interface reste flexible&amp;nbsp;: si vous préférez choisir dans une liste des valeurs possibles plutôt que d'utiliser l'auto-completion, ce qui est envisageable, il suffit, si c'est disponible pour le champ correspondant, de cliquer sur la petite icône représentant une liste en fin de ligne... Ainsi, pour les pays, cela donne&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://blog.mymind.fr/mind/public/screenshots/select-pays-dropdown.png&quot; alt=&quot;Choix sur les pays&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Il s'agit du même champ dont le &amp;lt;input type=&quot;text&quot;&amp;gt; a été remplacé par une &amp;lt;select&amp;gt;.&lt;/p&gt;


&lt;h2&gt;Sondages&lt;/h2&gt;


&lt;p&gt;Les sondages étaient la seule fonctionnalité du site qui avait été perdue lors du passage à plat/al il y a maintenant 2 ans et demi. C'est maintenant réparé grâce au travail de pika. Cette fonctionnalité étant de fait encore jeune, on peut s'attendre à ce que l'interface soit retravaillée fortement dans les prochaines versions du site pour s'adapter aux attentes des utilisateurs. Néanmoins, il est à noter que l'édition des sondages a été travaillée de telle sorte qu'un sondage soit facilement éditable&amp;nbsp;: l'utilisateur qui crée un sondage peut aisément ajouter, supprimer ou modifier des questions, et les administrateurs ont accès exactement aux mêmes fonctionnalités pour la maintenance des sondages.&lt;/p&gt;


&lt;p&gt;Nous attendons maintenant l'utilisation de cette fonctionnalité pour avoir des retours de la part de nos utilisateurs. Si l'expérience se révèle concluante, les sondages seront intégrés à Polytechnique.net pour que les animateurs les aient à leur disposition directement depuis l'interface de gestion des groupes.&lt;/p&gt;


&lt;h2&gt;Ensemble d'utilisateurs&lt;/h2&gt;


&lt;p&gt;Il s'agit de la partie sur laquelle j'ai travaillé, et donc celle que je connais le mieux, mais c'est aussi la partie la plus abstraite. Pour l'utilisateur, ça ne change quasiment rien, par contre au niveau du moteur du site, c'est à mon sens un pas en avant important vers des interfaces plus adaptées aux besoins des utilisateurs. C'est pour cette raison que cette partie risque d'être un poil technique.&lt;/p&gt;


&lt;p&gt;Ce dont je parlais au paragraphe précédent est la gestion des ensembles d'utilisateurs... mais qu'est-ce donc&amp;nbsp;? un ensemble d'utilisateur est tout simplement une sélection d'utilisateurs dans l'annuaire, ça peut être les membres d'une Mailing-List, les contacts d'un utilisateur, les membres d'un groupe, les camarades correspondant à une recherche...&lt;/p&gt;


&lt;p&gt;Le problème est que je voudrais que dès que sélectionne un ensemble d'utilisateur, je puisse séparer totalement la représentation de ces utilisateurs de la sélection qui est faite&amp;nbsp;: ainsi si je choisi mes contacts, je veux pouvoir afficher mes contacts sur un planisphère, voir le trombinoscope de mes contacts, mais aussi voir leurs fiches... mais je voudrais avoir les mêmes outils pour toute autre sélection d'utilisateur.&lt;/p&gt;


&lt;p&gt;La résolution propre de ce problème (c'est-à-dire, sans tout recoder à chaque cas possible d'utilisation) est l'utilisation d'un outil orienté Model/View&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le modèle gère la parti sélection des utilisateurs en fonction de la page&lt;/li&gt;
&lt;li&gt;l'afficheur sélectionne les données à afficher pour les utilisateurs et génère ce que l'utilisateur verra&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dans plat/al, le Model s'appelle PlSet (duquel hérite un UserSet spécialisé dans les ensembles d'utilisateurs), et le View s'appelle PlView. De cette manière, l'affichage des contacts se fait en 5 lignes de code&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; UserSet&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;quot;INNER JOIN contacts AS c2 ON (u.user_id = c2.contact)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;quot; c2.uid = &lt;span style=&quot;color: #006699; font-weight: bold;&quot;&gt;$uid&lt;/span&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #004000;&quot;&gt;addMod&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;'minifiche'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;'Mini-Fiches'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #004000;&quot;&gt;addMod&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;'trombi'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;'Trombinoscope'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #990000;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;'with_admin'&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;'with_promo'&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #004000;&quot;&gt;addMod&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;'geoloc'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;'Planisphère'&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #004000;&quot;&gt;apply&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;'carnet/contacts'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000088;&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000088;&quot;&gt;$action&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000088;&quot;&gt;$subaction&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;On crée le UserSet en lui donnant les critères de sélection des utilisateurs à afficher, puis on ajoute les Views à utiliser, enfin on gère l'affichage (en fonction des arguments passés à l'affichage de la page). C'est le type d'abstraction qui font vraiment plaisir car finalement on se rapproche du slogan de Qt&amp;nbsp;: &lt;q&gt;Code less, Do more&lt;/q&gt;.&lt;/p&gt;


&lt;p&gt;Bien sûr, il faut développer tout le background, mais le temps de développement est négligeable comparé à celui qu'on aurait passé à dupliquer ce code, voire justement à ne pas le dupliquer en raison de la complexité de certains cas. Un autre exemple d'utilisation est sur l'annuaire des groupes sur Polytechnique.net&amp;nbsp;:&lt;/p&gt;

&lt;code class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; UserSet&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #004000;&quot;&gt;addMod&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;'trombi'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;'Trombinoscope'&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #004000;&quot;&gt;addMod&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;'geoloc'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;'Planisphère'&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;color: #000088;&quot;&gt;$view&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #004000;&quot;&gt;apply&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;'annuaire'&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000088;&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000088;&quot;&gt;$action&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #000088;&quot;&gt;$subaction&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;/code&gt;


&lt;p&gt;Dans ce cas, comme UserSet sait que s'il est appelé dans le cadre d'un groupe-X sur Polytechnique.net, il ne doit pas sélectionner d'utilisateurs hors de l'annuaire de ce groupe, il n'y a aucune restriction à lui indiquer&amp;nbsp;: tout l'annuaire du groupe est sélectionné. On ajoute les deux modules de représentation qu'on désire utiliser&amp;nbsp;: trombinoscope et Planispère, et applique à la page... en 4 lignes c'est fait.&lt;/p&gt;


&lt;p&gt;Je m'extasie devant ce travail parce que je suis content du résultat, mais il n'est pas pour autant parfait. Son problème actuel est dû au background basé sur SQL&amp;nbsp;: chaque élément (PlSet ou PlView) apporte des bribes d'une requête SQL permettant de finalement obtenir toutes les informations à afficher (PlView) pour les utilisateurs sélectionnés (PlSet), mais il peut arriver qu'une même donnée soit utilisée pour la sélection et pour l'affichage. Dans ce cas, la solution la plus simple est de dupliquer les jointures dans la requête, mais c'est une solution qui peut sérieusement alourdir et ralentir la requête.&lt;/p&gt;


&lt;p&gt;L'implémentation actuelle gère la duplication au cas par cas&amp;nbsp;: les PlView peuvent contenir tester s'il faut sélectionner un champ ou non en testant la classe du PlSet utilisé. Cette solution n'est pas particulièrement propre. La meilleure solution envisageable est d'utiliser une abstraction des champs SQL&amp;nbsp;: chaque élément ne donnerait plus une bribe de requête SQL mais des informations sur &quot;comment sélectionner la donnée&quot;... ensuite la génération de la requête consiste à comparer toutes ces informations et à les assembler. Plat/al possède déjà les outils nécessaires pour réaliser ce jeu d'assemblage... ce sera très probablement pour la prochaine release.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/04/29/0914-en-ligne#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/04/29/0914-en-ligne#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/23</wfw:commentRss>
      </item>
    
  <item>
    <title>Stats</title>
    <link>http://blog.mymind.fr/post/2007/04/21/Stats</link>
    <guid isPermaLink="false">urn:md5:8fac3526281ad76cf6ecb507a074b66e</guid>
    <pubDate>Sat, 21 Apr 2007 00:59:00 +0200</pubDate>
    <dc:creator>Florent Bruneau</dc:creator>
        <category>GeekTime</category>
        <category>awstats</category><category>Devel</category><category>root</category>    
    <description>    &lt;p&gt;Depuis le début, j'ai installé &lt;a href=&quot;http://awstats.sf.net&quot;&gt;awstats&lt;/a&gt; pour avoir des statistiques sur l'utilisation de mon serveur web.&lt;/p&gt;


&lt;p&gt;J'ai choisi awstats un peu par hasard&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on avait utilisé &lt;a href=&quot;http://www.mrunix.net/webalizer/&quot;&gt;webalizer&lt;/a&gt; au &lt;a href=&quot;http://www.frankiz.net/binets/reseau&quot;&gt;BR&lt;/a&gt; et je n'étais pas spécialement convaincu par le résultat obtenu&amp;nbsp;: beaucoup de chiffres, graphiquement peu attirant et d'ergonomie d'utilisation assez mauvaise.&lt;/li&gt;
&lt;li&gt;à &lt;a href=&quot;https://www.polytechnique.org&quot;&gt;Polytechnique.org&lt;/a&gt; par contre, on utilise awstats, même si je n'ai pas fait le bilant complet des fonctionnalités, il a au moins l'avantage d'être lisible et agréable à l'oeil.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Donc &lt;a href=&quot;http://stat.mymind.fr/blog&quot;&gt;je l'ai installé&lt;/a&gt;, personnalisé... en particuliers j'ai ajouté des browsers (principalement des syndicateurs) et robots, amélioré les spécifications de certains OS, et j'avais également ajouté à l'outil de configuration le support de &lt;a href=&quot;http://www.mamp.info/en/home/&quot;&gt;MAMP&lt;/a&gt;. J'ai envoyé le patch au mainteneur du projet. Aujourd'hui je fais un &lt;code&gt;cvs up&lt;/code&gt; sur mon installation du projet et je vois&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
P docs/awstats_faq.html
RCS file: /cvsroot/awstats/awstats/tools/awstats_configure.pl,v
retrieving revision 1.6
retrieving revision 1.7
Merging differences between 1.6 and 1.7 into awstats_configure.pl
M tools/awstats_configure.pl
M wwwroot/cgi-bin/awstats.model.conf
RCS file: /cvsroot/awstats/awstats/wwwroot/cgi-bin/lib/browsers.pm,v
retrieving revision 1.54
retrieving revision 1.55
Merging differences between 1.54 and 1.55 into browsers.pm
M wwwroot/cgi-bin/lib/browsers.pm
RCS file: /cvsroot/awstats/awstats/wwwroot/cgi-bin/lib/operating_systems.pm,v
retrieving revision 1.20
retrieving revision 1.21
Merging differences between 1.20 and 1.21 into operating_systems.pm
M wwwroot/cgi-bin/lib/operating_systems.pm
RCS file: /cvsroot/awstats/awstats/wwwroot/cgi-bin/lib/robots.pm,v
retrieving revision 1.44
retrieving revision 1.45
Merging differences between 1.44 and 1.45 into robots.pm
M wwwroot/cgi-bin/lib/robots.pm
&lt;/pre&gt;


&lt;p&gt;Bizarrement, tous les fichiers que j'ai modifié ont été modifié également sur la CVS... donc je suis allé faire un tour sur le &lt;a href=&quot;http://awstats.cvs.sourceforge.net/awstats/awstats/&quot;&gt;webvc du projet&lt;/a&gt;, et sur les fichiers correspondants, il y a le commentaire &lt;em&gt;Patch florent bruneau&lt;/em&gt;.&lt;/p&gt;


&lt;p&gt;Voilà, une bonne surprise&amp;nbsp;! Je suis juste un peu déçu de l'avoir vu uniquement sur un update de cvs.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.mymind.fr/post/2007/04/21/Stats#comment-form</comments>
      <wfw:comment>http://blog.mymind.fr/post/2007/04/21/Stats#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.mymind.fr/feed/atom/comments/22</wfw:commentRss>
      </item>
    
</channel>
</rss>