humani nil a me alienum puto

Aller au contenu | Aller au menu | Aller à la recherche

Tag - programmation

Fil des billets - Fil des commentaires

dimanche 15 juin 2014

nerds en noir et blanc

En passant près de mon cinéma de quartier dans lequel je n'ai remis les pieds fort longtemps (plus précisément depuis que j'ai une carte UGC illimitée et que mon appartement s'est transformé en simple dortoir, quoiqu'à présent j'y suis beaucoup plus présent, comme du temps où j'étais étudiant), j'ai aperçu une affiche qui m'a intrigué. "Computer Chess" avait de quoi me séduire : étrange film d'art et d'essai, sur un tournoi de programmation de jeu d'échecs au début des années 80, quand l'informatique a commencé à être ce qu'elle est aujourd'hui, c'est-à-dire à ce tournant où de nouveaux pionniers ont programmé avec des langages de haut niveau, laissant tomber la carte perforée pour l'abstraction de langages algorithmiques.

Andrew Bujalski est un électron libre du cinéma indépendant. À sa manière, c'est un nerd. D'ailleurs, il est victime d'un terme (inventé par son ingénieur du son) qu'il a lancé il y a dix ans : il donne dans le mumblecore -- le hardcore des films intellectuels et bavards tournés avec trois francs six sous où l'on marmonne beaucoup. Computer Chess est un film aussi original et inédit qu'il est d'une intelligence remarquable. Filmé avec une vieille caméra des années 1970 (un modèle approchant celui que l'on voit à l'écran, qui ne fonctionnait pas en réalité), en noir et blanc (excepté pour une séquence, parce que c'est trop tentant), le cachet du film est volontairement vieillot, et l'apparition des personnages (habits, lunettes, pilosité) comme les machines antédiluviennes employées (emprunté à un musée si on en croit le générique) donne une véritable impression de documentaire filmé à l'époque, parti pris délibéré dont on se détache progressivement (mais au début, on croirait presque à un pur reportage !).

Un grand maitre d'échecs organise chaque année un tournoi où sont conviés les meilleurs programmeurs réunis en équipe. On attend le TSAR3 qui succède au programme vainqueur de l'année précédente -- mais qui va se comporter "humainement", mystère. Michael Papageorge est provocateur, il dénonce la force brute employée par ses opposants, tandis que son algorithme est d'une remarquable finesse -- avant de devoir errer dans l'hôtel faute de chambre. On suspecte que le Pentagone manipule tout cela pour son compte... Et au milieu de ces intrigues s'entremêlent d'autres encore, dans une atmosphère semi-scientifique, avec du vrai nerd acteur amateur dans son jus qui parle son jargon pur (et je confirme qu'on se sent comme à la maison...), et semi-burlesque, entre les chats et le groupe de développement personnel. Contrepied total à l'abstraction de la machine, la métaphysique humaine ressort derrière les froids calculs des terminaux. Le nouvel âge (le nouvel homme ?) cybernétique voit-il le jour à cet instant ?

Il y a des moments de vides interloqués (assez typiques dans les réunions geeks, d'ailleurs), d'autres de planage à trois mille (surtout avec un joint), des quêtes de dépassement de l'homme par la machine, et d'autres par l'introspection : tout cela mélangé, au cours d'un montage d'un an pour un tournage d'à peine deux semaines, les 92 minutes intelligentes et what-the-fuck de Computer Chess, s'adressant à un public de préférence cinéphile et geek (ça fait assez peu de monde...), sont absolument remarquables et pourraient potentiellement devenir cultes dans les écoles d'informatiques hardcore (je me souviens qu'on diffusait Tron la nuit où l'on devait le coder, il serait logique d'en faire de même lors du projet C++ du dérouleur de jeux d'échecs).

La dimensions quelque peu spirituelle transparait essentiellement à la fin du film, notamment avec la séquence finale. Les références sont en tout cas remarquablement maitrisées et documentées, depuis la vie sexuelle (inexistante) des nerds jusqu'au générique sous forme de terminal (qu'il faut lire pour trouver de belles pépites). On peut trouver des (sur)interprétations cachées à l'infini, la chasse est ouverte (film en noir et blanc comme les échecs, comme le binaire des machines et le monde manichéen qui s'annonce avec leur avènement, etc.). La souris a aussi beaucoup apprécié, et nous sommes donc restés tout le long de l'interview en direct sur Skype (depuis Austin), quasiment une heure, du scénariste-réalisateur ébouriffé et brillant.

mercredi 9 septembre 2009

doteuh nette, ça pète !

Ça fait longtemps que je n'ai pas craché sur la techno de m$ .Net. En allant sur une page de vogue, voici ce qui est arrivé :



Erreur du serveur dans l'application '/'.

Une exception de type 'System.OutOfMemoryException' a été levée.

Description : Une exception non gérée s'est produite au moment de l'exécution de la demande Web actuelle. Contrôlez la trace de la pile pour plus d'informations sur l'erreur et son origine dans le code.

Détails de l'exception: System.OutOfMemoryException: Une exception de type 'System.OutOfMemoryException' a été levée.

Erreur source:

Ligne 31 :         else
Ligne 32 : {
Ligne 33 : dom.Load(xmlFilePath);
Ligne 34 : CacheDependency xmlFileCacheDependency = new CacheDependency(xmlFilePath);
Ligne 35 : Cache.Add(cacheKey, dom, xmlFileCacheDependency, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration, CacheItemPriority.AboveNormal, null);

Fichier source : f:\Sites\Vogue\wwwroot\_marketResources\UserControls\F6\BannerGenerator.ascx.cs    Ligne : 33

Trace de la pile:

[OutOfMemoryException: Une exception de type 'System.OutOfMemoryException' a été levée.]
System.Xml.XmlNamedNodeMap.get_Nodes() +26
System.Xml.XmlNamedNodeMap.AddNodeForLoad(XmlNode node, XmlDocument doc) +41
System.Xml.XmlAttributeCollection.Append(XmlAttribute node) +41
System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace) +190
System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc) +20
System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace) +129
System.Xml.XmlDocument.Load(XmlReader reader) +108
System.Xml.XmlDocument.Load(String filename) +87
_marketResources_UserControls_Adv_BannerGenerator.Page_Load(Object sender, EventArgs e) in f:\Sites\Vogue\wwwroot\_marketResources\UserControls\F6\BannerGenerator.ascx.cs:33
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Control.LoadRecursive() +141
System.Web.UI.Control.LoadRecursive() +141
System.Web.UI.Control.LoadRecursive() +141
System.Web.UI.Control.LoadRecursive() +141
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627


Informations sur la version : Version Microsoft .NET Framework :2.0.50727.4016; Version ASP.NET :2.0.50727.4016

C'est tout de même assez fabuleux. Jolie présentation, en tout cas...

mercredi 26 novembre 2008

oh, ce qu'ils n'ont pas osé faire !

RealBasic : via une google ad, je découvre cet IDE+compilateur crossplatform win/linux/mac (toutes versions de mac), qui... réinvente VB6  >_<". Et là normalement, il faut troller à mort, mais voilà, après un coup d'oeil, c'est simplement épatant (j'aime particulièrement le debug pas à pas où l'on peut visualiser le contenu d'une image !). Et je suis bien embêté pour me moquer, maintenant, parce que chiotte, c'est quand même du basic avec des Dim et autres saloperies. N'empêche, c'est manifestement carrément meilleur que le Visual Basic de m$ (même à l'exécution : pas besoin d'une dll de réinterprétation, la plaie absolue de VB pour filer ses programmes à quelqu'un d'autre), et c'est par des texans (ouch !) qui vous traduisent le site ouèbe dans votre langue sans qu'on ait rien à lui dire.

Purée, y'a des gens qui en 2008 codent un compilateur propriétaire complet from scratch, avec une IDE complète (qui n'est pas un plugin eclipse), avec des features puissamment clickodromesques (pareil que sous VB, on construit sa fenêtre en WYSIWYG), pour... du Basic. Va me falloir un certain temps pour m'en remettre...

samedi 13 septembre 2008

électronicien raté ?

Les informaticiens embarqués sont souvent épatant pour les informaticiens-tout-court : ils font des choses toutes bizarres qui paraissent bien merveilleuses, pour activer des choses très bas niveau, très sytème. Pour preuve cet extrait de Makefile que l'on trouve sur le Hors Série de Linux Mag' spécial électronique, à la page 16, dans un article écrit par Denis Bodor, le rédac en chef du magazine lu (et compris, c'est surtout ça le problème) par les ingénieurs-geeks les plus confirmés :

avr-objcopy -j .text -j .data -O ihex main.elf main.hex

Il est vrai d'objcopy n'est jamais employé dans le génie logiciel, la manipulation des sections et des symboles étant laissés au bon vouloir d'un lieur dont on ignore souvent même l'existence. L'article en question qui traite de communication avec les périphériques série RS232 via un AVR est épatant : mais que l'on ne s'y trompe pas, cela vient clairement d'un électronicien.

Il y a un tas d'électronicien ayant parfois reçu une légère formation informatique qui sont impressionnant en terme de programmation système. Cependant, ils ont toujours cette dimension propre à la physique (la bidouille), mais manquent de celle caractéristique des mathématiques : l'algorithme. Aussi manier des masques de bits et gérer les interruptions n'a aucun secret pour eux. Mais j'ai déjà vu un collègue peiner deux jours sur un code parce qu'il ne connaissait pas malloc. Sans arriver à cet extrême, nous pouvons voir ceci sur la même page, qui ne manquera pas d'étonner :

while (1) {
  rxbuff=ReceiveByte();

  if (rxbuff) {
    TransmitByte(rxbuff);
    switch (rxbuff) {
      case '0':             set_pwm(0);        break;
      case '1':             set_pwm(111);      break;
      case '2':             set_pwm(222);      break;
      case '3':             set_pwm(333);      break;
      case '4':             set_pwm(444);      break;
      case '5':             set_pwm(555);      break;
      case '6':             set_pwm(666);      break;
      case '7':             set_pwm(777);      break;
      case '8':             set_pwm(888);      break;
      case '9':             set_pwm(999);      break;
    }
  }
}

On reste un peu pantois. Et pas seulement parce qu'il n'y a pas de default  :). On pourrait penser à mettre directement une multiplication par 111 :

if (rxbuff < 10)   // il est évidemment non signé
  set_pwm(rxbuff * 111);

Ca coûterait au maximum sept additions, et éviterait d'avoir jusqu'à neuf branch dans le code. Cette solution serait à comparer avec celle basée sur un tableau :

int16_t pwmcorr[10] = { 0, 111, 222, 333, 444, 555, 666, 777, 888, 999 };
// ...
if (rxbuff < 10)
  set_pwm(pwmcorr[rxbuff]);

Solution évitant la multiplication, mais faisant appel à un déplacement mémoire (et forcément à une addition) ; cependant, même avec une MMU, ça ne devrait pas être trop dramatique. Dans tous les cas, on est en droit de douter qu'un switch-case sur neuf niveau aussi stupide, même avec l'aide d'un compilateur intelligent (mieux vaut un switch-case qu'un tableau de pointeurs sur fonctions : dans le premier cas, le compilateur peut comprendre et optimiser, dans le second il ne peut rien voir venir ; et c'est sans compter le debug...).

Quelque part, pour l'informaticien embarqué qui a comme moi une formation première d'informaticien, c'est rassurant : alors qu'il entre dans un monde industriel où il a déjà la réputation d'électronicien raté, car c'est uniquement l'individu transfuge qui jusque là s'occupait de ce travail, il se sent souvent impuissant face à la couche à peine supérieure à l'électronique, celle de la tambouille très bas niveau, lui qui est à peine bien content d'avoir échappé aux weberies et autres presse-boutons. Il sait alors que sa valeur ajoutée sera l'informatique pure, le beau code qui fait plaisir à lire. Et que par exemple, Linux embarqué correspond parfaitement à ce genre de secteur et d'applicatifs où sa valeur ajoutée sera la plus appréciée.

jeudi 11 septembre 2008

tuons les wébeux et les résoteux

Oui, c'est de l'eugénisme, mais vous savez...

Pour les wébeux, le dernier exemple se trouve par-là. Regardez l'immonde user agent de Chrome :

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13

Et pour les résoteux, voici un extrait de Makefile de SNMP :

INSTALL = $(LIBTOOL) --mode=install /usr/bin/install -c
UNINSTALL = $(LIBTOOL) --mode=uninstall rm -f
INSTALL_DATA = $(LIBTOOL) --mode=install ${INSTALL} -m 64

Non, vraiment, l'informatique se portera vraiment mieux sans tous ces gens...

lundi 1 septembre 2008

le itoa du bourrin

Cherchant tout à l'heure une implémentation rapide d'un "itoa", c'est-à-dire d'une fonction C transformant un entier en chaîne de caractère, entier en l'occurrence toujours positif (la précision est d'importance). Et là, je tombe sur celle que j'ai codée dans KonQueR, un grand moment (je réadapte un peu au passage) :

char *itoa(uint n)
{
  char  s[11] = {0,}; int i = sizeof(s) - 1;

  do {
    s[--i] = '0' + n % 10;
  } while ((n /= 10) > 0 && i != 0);
  return strdup(s + i);
}

En fait, le "11" était un "5", tout simplement parce que le chiffre en entrée ne dépasse pas 9999 (oui, c'est sioux, c'est pour ça aussi le "i != 0" dans le while, on ne sait jamais) ; avec 11 on peut arriver à 4294967295, soit MAX_INT, à réadapter si long long en entrée par exemple (il suffit donc de compter les chiffres de 2^64 - 1 en base 10, et d'ajouter 1 pour le \0). On peut réadapter pas trop difficilement à une autre base (il y a la vieille astuce du "0123456789abcdef" pour la base 16, etc), ou pour les nombres négatifs (tester et stocker "-1" ou "0", rendre positif, et à la fin le rajouter à s[i + sign] = '-' et strdup(s + i + sign) ).

Je me rappelle de mon premier itoa, ou plutôt du fait qu'il était long comme mon bras (long, pas large). Cinq lignes de code, c'est pas mal en revanche  :)  (je suis déjà tombé sur du code de crassouillé qui mettait l'équivalent du "s" en static et le retournait : mieux vaut faire des free que de se retrouver avec des bouts de chaînes qui se réécrasent de temps à autre !).

lundi 19 mai 2008

les merveilles de la libc

Trois extraits de man pour la route :

1. strfmon

L'appel
              strfmon(buf, sizeof(buf), "[%^=*#6n] [%=*#6i]",
                      1234.567, 1234.567);
       affiche
              [ fl **1234,57] [ NLG  **1 234,57]
       Dans la localisation hollandaise (fl étant "florijnen" et NLG "Netherlands Guilders").  Le caractère de groupement  est  horrible  car  il  prend
       autant  de place qu'un chiffre, alors qu'il ne devrait occuper qu'un demi-espace, ce qui peut induire en erreur.  Etonnament, le "fl" est précédé
       et suivi par un espace, et "NLG" est précédé par un espace et suivi par deux.  Il s'agit peut-être d'un bogue dans le  fichier  de  localisation.
       Les localisations italienne, australienne, suisse, et portugaise donnent
              [ L. **1235] [ ITL  **1.235]
              [ $**1234.57] [ AUD **1,234.57]
              [Fr. **1234,57] [CHF  **1.234,57]
              [ **1234$57Esc] [ **1.234$57PTE ]

2. strfry :

NOM
       strfry - Créer une anagramme d'une chaîne.

SYNOPSIS
       #include <string.h>

       char *strfry (char *string);

DESCRIPTION
       La  fonction   strfry()  crée  une anagramme du contenu de la chaîne string en utilisant la fonction rand(3) pour échanger aléatoirement des car-
       actères.

3. memfrob :

NOM
       memfrob - Crypter une zone de mémoire.

SYNOPSIS
       #include <string.h>

       void *memfrob (void *s, size_t n);

DESCRIPTION
       La  fonction  memfrob()  crypte  les  n  premiers octets de la zone de mémoire s en effectuant un OU-exclusif entre chaque octet et le nombre 42.
       L'effet inverse est obtenu en rappelant à nouveau memfrob() sur la zone cryptée.

       Notez que cette fonction n'est pas vraiment un cryptage, car la constante du OU exclusif est fixée. Elle est simplement  utile  pour  cacher  des
       chaînes de texte clair.

C'qu'on se marre. A noter qu'à chaque pauvre utilisation de dynamique de la libc, ces fonctions à la con sont aussi chargées en mémoire. edit: une fois suffit, qu'on en ait besoin ou pas, mais qu'une seule fois (cf commentaires) Tout à coup ça fait moins rire.

Puisque j'y suis, avez-vous vu ces illustrations hyper drôles à propos de la dernière faille abominable (ah, les mêmes dessins, ça a eu du succès :) ) sur openSSL sous Debian (&co, dont ubuntu) de ces derniers jours ?

jeudi 27 mars 2008

le single user sur openBSD (et ses facéties)

Pour un truc hyper sécurisé, des fois, ça me laisse songeur... Regardez le code par ici de init. BSD n'est pas SystemV, donc ça ne marche pas comme un Linux de base : il ne fait que lancer le script /etc/rc (codé en dur) ; il n'y a pas d'inittab. De fait, la présence de login via getty est déduite en fonction du fichier /etc/ttys, qui par défaut en met un sur tty00, la première console (on remarquera que getty est dans /usr/libexec, encore une des plaisanteries pas drôle de cet OS mal fichu ; à remarquer que c'est pareil sur MacOS, d'après ce que j'ai vu).

Sauf que si l'on regarde dans le code, la lecture de ce fichier se fait via la fonction "read_ttys()", qui elle-même appelle "start_session_db()" ; si cela échoue, c'est "single_user()" qui est appelé (par pointeur de fonction), sinon plus bas, c'est "multi_user()" (idem). multi_user, c'est le truc standard, avec un login/mot de passe demandé pour se logguer. Tout ceci se passe évidemment après avoir lu et entièrement exécuté le fichier /etc/rc (fonction "runcom()" ; à remarquer que c'est le même script qui est exécuté lorsque l'on arrête ou que l'on reboote la machine, pratique non ? Heureusement, un argument "shutdown" est passé dans ce cas, fonction "nice_death()"), tout ce qui doit être démarré pour avoir un système viable (un serveur apache, par exemple) est donc démarré. Notamment, on a depuis longtemps dépassé la fonction "main()" qui avec son while sur getopt en tête, vérifie que l'on n'a pas explicitement demandé un single mode dans le sens unixien/linuxien du terme, c'est-à-dire le fameux démarrage en mode dégradé directement sur shell (remarquons d'ailleurs que de plus en plus de distribution Linux semblent désactiver cette fonction du kernel par défaut : sinon avec un accès physique à un portable, il suffit d'éditer la ligne de conf avant démarrage, sous grub, et ajouter "single" à la liste des arguments, avant de changer le mot de passe root et redémarrer, par exemple) ; sous bsd, ça s'appelle en mettant un argument "-s" au noyau (stocké usuellement dans /bsd, soit à la racine, tout est simpliste dans ce monde).

Résumons : le single user est comme sous Linux, et tout aussi dangereux ; il n'est pas désactivable, sauf à compiler le kernel sans support de la ligne de commande (la gestion de la compilation de bsd est d'ailleurs des plus folkloriques ; à noter que la notion de modules n'est pas encore au goût du jour, et que désactiver le support d'une carte pcmcia dont on n'a que faire peut avoir des conséquences fâcheuses inattendues -- j'ai fini par la remettre, j'étais prévenu -- ah, si vous trouvez la faq austère, sachez qu'elle est en réalité fort complexe, si si, et que c'est pour ça qu'elle n'est pas aux standards w3c). C'est-à-dire que s'il est déclenché, on se loggue sans mot de passe en root, et l'on peut faire la fête sur le système. Parlons donc de cette fonction "start_session_db()"...

Il semble que bien des choses reposent sur db, la base de donnée antédiluvienne, notamment la gestion des mots de passe (pas de shadow mais un pwd.db). Et apparemment pour la gestion des ttys aussi. Or, db a besoin de son répertoire /var/db. Que se passe-t-il si le disque est plein, ou si /var est read-only ou du moins non inscriptible, par exemple parce que le file system de sa partoche (enfin, slice, je passe sur les détails...), est corrompu et automatiquement monté en ro ? (ce qui peut avoir des conséquences tragi-comiques : ayant un fichier sur lequel j'ai créé par virtual node -- le loopback du pauvre sur bsd -- un système bsd complet, et notamment une partition primaire bootable, le fait de vouloir la monter alors qu'un qemu fermé un peu trop vite m'avait un peu pourri le file system -- qui n'est pas journalisé, sous bsd --, a fait détecter au système que je voulais remonter une partition système avec bootloader et certainement noyau alors que celle-ci n'était pas nettoyé : refus catégorique et affichage de warning sur toutes les consoles ! Ou comment une mesure de sécurité légèrement pensé mène à du grand n'importe quoi) Ou encore que /var ou /var/db n'existe plus ? (imaginons qu'une coupure de courant fasse rebooter violement la machine, et que certains dossiers soient perdus ou fichier de création dynamique de répertoires corrompu)

Eh bien tout simplement, la fonction échoue, et on se retrouve, alors que login et getty peuvent se lancer tout à fait correctement, avec le prompt "Enter pathname of shell or RETURN for sh: ", ce qui en appuyant sur Entrée donne directement sur un shell root, sans passer par l'étape habituelle de la demande de mot de passe.

"Ah bein bravo", comme on dit...

(en l'occurrence, cette enquête a été mené parce que /var était par erreur un répertoire sur un file system / RO par mesure de sécurité, au lieu d'être un lien vers /tmp/var, lui-même monté en RAMdisk, ou "mfs" sous bsd -- d'ailleurs le "mount_mfs" reste un processus lancé, c'est-à-dire en toute rigueur une gestion en userland via allez-retour kernel/processus pour de la mémoire que l'on veut la plus rapide possible -- contrairement à un FUSE linux qui de toute façon a toujours été un gros hack, bien inférieur à ce que ferait un hurd --, et en plus non déboulonnable ensuite, du moins un kill -9 n'y fait rien... Magnifique design, pour la peine)

vendredi 4 janvier 2008

C++ bashing

Pour bien terminer la semaine, un peu de C++ bashing. Ce langage est décidément une belle merde. Souvenez-vous il y a deux ans, je découvrais que le bidule ne savait pas faire la différence au niveau de la surcharge de méthodes entre une signature avec bool et une autre avec int. C'était là. Un grand moment.

Il semble que depuis l'accent (du moins dans g++) ait été mis sur le typage qui était trop laxiste. Par exemple, les enum, sur lesquels il est impossible de faire la moindre opération (même pas d'incrémentation, de telle sorte que leur intérêt retrouvé est tout à coup grandement reréduit). Mais aussi sur les fameux appels de méthode surchargées...

Voyons ce que me dit cette quadruple buse :

erreur: call of overloaded ‘get_data(int, int&)’ is ambiguous
 note: candidats sont: void* values_pool::get_data(long unsigned int, short unsigned int)
 note:                 void* values_pool::get_data(const char*, short unsigned int)

Il n'arrive pas à faire la différence entre un const char * et un long unsigned int. Pas de la blague. Ouais ouais. Même pas peur. Mais que lui ai-je donc dit pour attirer ainsi ses foudres, et son désarrois ?

pool->get_data(0ul, i);

Ouais, 0, il sait pas ce que c'est. Avec 0u, il trouve que c'est unsigned, mais pas assez précis, il hésite toujours (il le prend pour un int, mais est-ce un long int, où un char* ? Mais qu'il est con !). Avec 0l, il trouve que c'est un long, mais il hésite encore (pas sûr que ça soit non signé... ça pourrait donc être un pointeur, logique non ?). Avec 0ul, ça passe enfin. Hosanna !

Mais vous savez pas le plus drôle ? Ce truc-là ne fait aucune erreur, et passe par le bon tuyau :

pool->get_data(42, s_1);

Bah ouais, c'est fort, seul 0 n'est pas typé ! Mais apparemment pas du tout du tout. Je suppute une hypothèse hautement probable à cette faille spacio-temporelle : comme des joyeux codeurs descendus plus du cochon que du singe n'utilisent toujours pas NULL, ils mettent 0, en dur (et grouuuuiiikk !). Faudrait pas faire de warning, nan nan ! (warning: you piggy !) Donc on fait chier les bons codeurs, avec des merdes pareilles, où l'on en est réduit à précis des "0ul" à la place de "0" tout court. Foooormidable !

(et pour info, il existe d'anciennes archis où le pointeur NULL ne vaut pas 0...)

jeudi 13 décembre 2007

Does someone understand code flow here?

        /*
         * This is subtle. Instead of calling do_follow_link() we do the
         * thing by hands. The reason is that this way we have zero link_count
         * and path_walk() (called from ->follow_link) honoring LOOKUP_PARENT.
         * After that we have the parent and last component, i.e.
         * we are in the same situation as after the first path_walk().
         * Well, almost - if the last component is normal we get its copy
         * stored in nd->last.name and we will have to putname() it when we
         * are done. Procfs-like symlinks just set LAST_BIND.
         */
        nd->flags |= LOOKUP_PARENT;
        error = security_inode_follow_link(path.dentry, nd);
        if (error)
                goto exit_dput;
        error = __do_follow_link(&path, nd);
        if (error) {
                /* Does someone understand code flow here? Or it is only
                 * me so stupid? Anathema to whoever designed this non-sense
                 * with "intent.open".
                 */
                release_open_intent(nd);
                return error;
        }

J'ai failli m'étouffer. Je crois qu'il est temps de se diriger calmement vers la salle Pleyel (c'est dans le kernel Linux, pour la 2.6.23.9, lignes 1795 à 1817 de fs/namei.c).

- page 1 de 5