Catégorie : traductions

Les aventures de l'espace… immobilier

Nb : je ne fais que la traduction de la fin de l’article, que je trouve sympa.

Cet article peut être lu en entier ici.

Ecrit par Joel Spolsky, fondateur et PDG de Fog Creek Software à New York.

Finalement le propriétaire a réalisé que nous étions sérieux. Nous avons fait un chèque de caution de 215 481,75 dollars en plus de l’autre chèque de caution, uniquement pour pouvoir s’asseoir et réfléchir concrètement à toutes les améliorations possibles avec les architectes, respectivement Russell DeRosa et Natasha Suzansky.

Comme beaucoup d’architectes qui font aussi du travail de commercial pour se vendre, ils étaient ravis d’avoir un client qui demandait enfin autre chose que « pas cher ». Ces architectes qui sortent tout juste de l’école, avec dans leurs idées plein de choses créatives, d’espaces artistiques qu’ils vont bientôt concevoir, recoivent enfin leurs premiers clients, s’asseoient avec eux autour d’une table et commencent à parler d’espace négatifs, de perméabilité et de modernisme, et les clients les coupent instantanément et disent : « En fait, on veut bon marché« .

Les architectes répondent « Ok, et si on faisait bien et bon marché ? ».

Les clients répondent systématiquement : « Non. Pas bien. Just bon marché. »

Donc, si jamais vous appelez un architecte et que vous lui dite que vous voulez faire quelque chose de cool, suffisamment original et sympa pour qu’il puisse apparaitre dans leur portfolio pour montrer à d’autres clients, et que vous les invitez à faire quelque chose à la fois beau et utile au lieu de bon marché à tout prix, cet architecte va vous aimer et ira avec vous jusqu’au bout du monde pour voir ce qu’il pourrait imaginer faire pour gagner deux centimètre de hauteur sur les plafonds. C’est pourquoi nous auront de grands espaces dans lesquels se déplacer d’ici la fin de l’été.

Il va y avoir un grand espace de réception, une grande salle pour se restaurer, où on pourra manger tous ensembles, un bar pour se faire de bons cafés, un énorme aquarium plein d’eau salée pour les poissons, une bibliothèque avec des chaise inclinables pour pouvoir faire des mini-siestes, une douche, deux salles de conférence, 20 bureaux personnels pour les développeurs, 23 stations de travail entièrement ajustables, du Wi-Fi, un écran géant pour des films et des jeux vidéos, et assez de verre pour pouvoir faire la plus grande fourmillière au monde. Il nous restera encore de l’espace pour grandir si besoin est, et dans deux ans, si tout va bien, tout ça sera à nouveau trop petit pour nous.

Comment faire une belle démonstration ?

Vous avez fait un produit super bien. Chouette ! Maintenant, il va falloir le commercialiser, le vendre. Habituellement, c’est grâce à une démonstration, un petit tour de votre produit, de 5 minutes.

Donner accès à une démo est beaucoup mieux qu’essayer d’expliquer ce que fait votre produit avec des mots. Les gens peuvent voir exactement comment les choses fonctionnent, et c’est la façon la plus rapide de les aider à comprendre rapidement ce que fait votre produit, et comment il le fait. Il y a aussi une catégorie de gens qui peuvent être particulièrement intéressés par votre démonstration : les investisseurs. Lorsque vous cherchez des fonds, une bonne démonstration à des investisseurs potentiels peut faire un processus immédiat du « ça passe ou ça casse ». Alors, comment faire une bonne démonstration ?

Lorsqu’on cherchait des fonds pour Weebly, notre démonstration a été plutôt simple. We’d spend about an hour ahead of the meeting looking up the investor’s website, downloading the pictures and text, and importing the template into Weebly. Then, we’d spend a few minutes to practice creating the site quickly. The end result: we’d recreate an investor’s site « from scratch » in front of them in 3-4 minutes. It definitely had the intended « wow » effect.

Comment réussir à faire une belle démonstration ? Voici quelques astuces :

Elle doit être courte. Elle devrait prendre, en entier, 5 minutes ou moins. Une vidéo en ligne ne devrait jamais dépasser une minute trente secondes.

Elle doit en jeter plein la vue. Elle doit être vraiment, vraiment cool. La démo est un petit tour visuel, et votre audience sera complètement concentrée sur ce qu’elle peut voir. Votre objectif est de leur faire dire « Wow ! ». Les fondus et les animations deviennent rapidement lasssantes, n’en abusez pas, mais bien placées, elles peuvent faire leur effet.

Adaptez votre démo à votre audience. Dans notre cas, il nous faut coller aux idées de l’investisseur à qui on va se présenter. La personne à qui vous faites la démonstration doit être capable de s’identifier parfaitement, lui et ses besoins, à votre produit.

Utilisez des vraies données. Ne tapez jamais « asdfasdf » dans un champ de formulaire. C’est tellement plus facile de comprendre ce qu’une application fait lorsqu’un simule un vrai utilisateur.  Les données incohérentes rendent les exemples beaucoup plus difficiles à comprendre. Assurez vous d’avoir bien pré-rempli votre votre base de données avec des données proches de la vie réelle pour mettre clairement en valeur ce que vous exposez.

N’essayez pas de montrer toutes les possibilités. Montrez uniquement celles qui font que votre logiciel se démarque des autres, les possibilités qui vont faire sortir le « wow » de la bouche des investisseurs.

Suivez une idée directrice. Si vous sautez du coq à l’âne, faites le souplement, calmement, et soyez le plus clair possible. C’est un peu comme conduire un véhicule : si vous voulez changer de direction, il ne faut surtout pas le faire brutalement sinon c’est l’accident assuré.

Toujours avoir une sauvegarde prête à l’emploi. La pire des choses qui puisse vous arriver est de vous battre pendant 10 minutes avec la connection WI-FI, ou d’essayer de comprendre pourquoi quelque chose ne fonctionne pas sur votre ordinateur. Vous n’avez peut-être qu’une seule chance. Assurez vous que vous avez une carte Ethernet, si jamais le WI-FI ne fonctionne pas, ou une version qui tourne en local.

Montrez votre produit sous son meilleur jour. Il vous faut toujours être réaliste sur les petites choses à finaliser ou qui sont en cours de finalisation, si jamais on vous le demande. Assurez vous bien de mettre le plus possible votre produit en valeur et surtout évitez de montrer quelles sont les petits problèmes éventuels et comment les soulever en pratique. De toutes les façons, si vous en êtes conscient, c’est que vous allez rapidement les résoudre, donc parlez-en le moins possible.

Finalement, soyez sûr de vous et très excité. : vous avez fait un produit vraiment cool, et il faut vraiment faire passer ce message à votre audience. Si vous ne trouvez pas votre produit enthousiasmant, pourquoi, eux, le devraient-ils ? Ayez bien en tête qu’il y a de fortes chances pour qu’ils suivent votre humeur. Ne vous déstabilisez pas et restez positif.

Jusqu'à quel point peut-on pousser la machine ? (Part. II)

Seconde partie

Par Joel Spolsky, en avril 2008.

Cet article vient d’ici. Il est en deux parties. Vous trouverez la première  partie ici.

Comme je l’ai écrit le mois dernier, je n’ai vraiment pas appris grand chose à l’armée.

Bon, ok, disons que j’exagère un peu : en fait je suis devenu super bon au démontage de M-16 à l’aveuglette : en 15 secondes il était à plat, en morceaux. Et si jamais les hotêsses du vol de l’avion JAL 747 en provenance de Tokyo, dans lequel je suis actuellement, décidaient par un manquement incroyable du respect au consommateur, de me jeter directement de l’avion avec un parachute sur le dos, je pourrais faire un superbe roulé-boulé en arrivant au sol (après, je serai mangé par un ours polaire, mais bon, l’infanterie Israélienne n’est pas entraînée pour survivre dans la toundra).

Mais avec toute l’idolâtrie que le modèle de management militaire engendre, pour pourriez penser que j’ai appris plus de choses, pendant mon service, sur les qualités qu’il faut pour diriger et gérer les gens. Aucune chance. Si je me fie à mon expérience, diriger et gérer les gens du point de vue militaire c’est simplement : réussir à faire charger des jeunes de 18 ans dans un champ de mines alors qu’il auraient une fâcheuse tendance à vouloir rester derrière un gros rocher.

Ce type de management est connu pour nécessiter instantanément, immédiatement, une obédience absolue – ce qui serait en réalité contre-productif dans ma petite compagnie de développement de programmes, dans laquelle le plus gros problème est de réussir à convaincre les développeurs de me dire quand je fais fausse route et de faire les choses selon leur point de vue, parce qu’ils sont tous plus intelligents que moi.

Malgré ce, l’armée m’a appris une importante leçon dans le domaine de la stratégie. C’est un concept très simple qu’un général nous a appris dans un discours impromptu de 5 minutes, en plein milieu d’un exercice d’entraînement exténuant. Depuis, j’ai lu Michael Porter, la revue « Harvard Business Review » et des tonnes de bouquins écrits pas des consultants en management, et je n’ai jamais appris autant de choses sur la stratégie économique que ce qu’on m’a dit à ce moment là sur le concept très simple appelé « feu puis avance », « fire and motion ».

Voici le principe : vous tirez sur l’ennemi. C’est la partie « on tire ». Et puis vous avancez en même temps. C’est la partie « on se déplace ». Compris ?

Vous tirez pour forcer l’ennemi à se mettre à couvert. Il ne peut pas se mettre en face de vous et répliquer s’il est obligé de se protéger derrière un mur. Mais tirer n’est pas suffisant. Vous devez aussi avancer, sinon vous ne progresserez jamais. Le fait d’avancer vous rapproche de votre ennemi. Et les ennemis proches sont les plus faciles à atteindre. Vous avez besoin des deux : tirer et avancer. « Fire and motion ». Pratiquement toute tactique militaire, qu’elle soit sur terre, mer ou air, est une variation de ce principe fondamental. Les stratégies de business sont basées sur ce même principe.

Si vous regardez un marché sur lequel la compétition est dure, vous verrez que les compagnies qui y arrivent sont toutes celles définissent un planning, et par là-même qui forcent les autres à essayer de les rattraper, ou de suivre ce planning. Par exemple, la version « fire and motion » de JetBlue apparaît sous la forme d’une expérience clientèle inégalable. Les prix des billets n’étaient pas forcément supérieurs, et ils ne faisaient pas de vols sur toutes les destinations imaginables. Mais leurs avions étaient vraiment super sympas. Ils avaient des sièges confortables en cuir, et il y avait une télévision individuelle pour chaque passager.

En voulant les rattraper, les autres compagnies aériennes on passé du temps, de l’argent, et des efforts à essayer de copier JetBlue. Delta a ainsi perdu une petite fortune sur Song, une start-up qui mettait en avant des coktails innovants et des hotêsses qui portaient des uniformes dessinés par Kate Spade. Cette start-up a fermé ses portes à peine trois ans après avoir commencé, trois années pendant lesquelles JetBlue a continué à s’étendre sur de nouveaux marchés, et pendant lesquelles JetBlue a récupéré de la clientèle

De la même façon, malgré qu’ils aient eu quelques problèmes à résoudre récemment, Starbucks est un bon exemple de « fire and motion ». Ils forcent les concurrents à réagir. Regardez combien de temps et d’argent McDonald a dépensé pour faire des boissons caféinées bonnes et chères. Cette année, ils prévoient d’installer des machines Expresso appelées « McCafé » dans les milliers d’agences de manière à vendre plus de cappuccinos et autres. Parce que tout le monde sait que « McDonald’s égal café sympa »…

Vous pourriez penser que McDonald devrait passer plus de temps à peaufiner ses hamburgers et à en faire de meilleurs. Eh bien non. McDonald utilise son temps et de son énergie à essayer de répondre au « fire and motion » de Starbucks. Howard Schultz, lui, est occupé à trouver d’autres manières d’étendre le coeur de métier Starbucks.

Dans l’industrie informatique « fire and motion » apparaît sous la forme de nouveautés, et/ou de mises à jour dans une application. Microsoft avait l’habitude de régner en maître incontesté dans le domainde des agendas. Cela fait des années que j’utilise les outils de développement de Microsoft, et leur « tir de couverture » du « fire and motion » n’a été que de « donner la possibilité d’avoir huit manières différentes d’extraire les données de la base de données de leur agenda ». (Pour ceux qui veulent compter les points à la maison, c’étaient : DbLib, ODBC, RDO, DAO, ADO, OLEDB, ADO.NET, et LINQ — et je suis sûr que j’en ai oublié d’autres).

Microsoft eventually overplayed its hand when it brought together developers at a conference in Los Angeles in 2003 and suggested that they might consider rewriting their applications from scratch in order to take advantage of the excellent new capabilities soon to ship as a part of Windows Vista. Beaucoup de développeurs étaient méfiant, avec raison d’ailleurs, parce que quand Vista est sorti, il avait beaucoup moins de nouvelles fonctions que celles annoncées. Entretemps, des compagnies innovantes, telles que Google et VMware, ont commencé à dicter l’agenda des nouvelles technologies dans le monde, à un niveau que Microsoft n’avait jamais vu. Et maintenant, dans un reversement de situation remarquable, on voit Microsoft sur la défensive, qui dépense énormément de temps et d’argent à répondre au « fire and motion » de ses rivaux.

Que faites vous si vous vous trouvez en situation d’essayer de coller à un agenda d’un concurrent au lieu de mettre en place le vôtre ? La réponse est de casser le cycle le plus rapidement possible. Si vous êtes une petite compagnie, vous ne pouvez pas perdre du temps à essayer de répondre au tir de quelqu’un d’autre. Les autres balèses ont 10 fois plus de munitions. Donc, au lieu de cela, il vous faut faut les amener dans une bataille de Thermopiles de votre propre crû, où la taille n’a pas d’importance.

La bonne nouvelle c’est que ce n’est pas si difficile : au lieu de prêter attention à ce que vos concurrents font, lisez plutôt les retours de vos clients sur l’utilisation de votre logiciel. Connectez vous sur le net et écoutez, lisez ce que le monde dit à propos de vos produits. Faites un suivi au jour le jour en rapport direct avec ce que vous ont demandé vos clients, et ce que vous faites, sur votre site Internet. Si vous faites réellement tout ça, vous allez déjà vous distinguer des autres, dans votre domaine. Les grosses corporations qui sont fans de la théorie de la terre plate basée sur le livre de Thomas Friedman, doivent s’auto-flageller quotidiennement pour avoir distribué, en faisant confiance à cet auteur, les emails de retour d’expérience de leurs clients à une équipe de développeurs, mauvais, mais pas chers, au moins à 10 heures de décalage horaire de leur maison mère. Ils ne vont certainement plus jamais être dérangés par ce que dont ont vraiment besoin leurs clients, ce qu’ils voulaient dire ou ce à quoi il faudrait faire attention.

Et si vos concurrents écoutent les clients ? N’essayez même pas de perdre une minute à savoir si c’est le cas. Si vos concurrents résolvent un problème d’une façon unique, vous n’allez pas le manquer, ne serait-ce qu’en écoutant vos clients. Soyez sûr qu’ils sont déjà en train de vous dire que cette possibilité existe. Si vous écoutez. Une minute utilisée à comprendre le fonctionnement des concurrents, c’est une minute qui n’est pas utilisée à écouter vos clients, vos clients potentiels, et vos presque-clients qui sont allés voir la concurrence, qui seraient contents de vous dire directement ce qu’ils voudraient ou auraient voulu qu’on leur vende. Vous pourriez même arriver à trouver une solution qui pourrait être meilleure que celle qu’a trouvé votre concurrent. C’est à ce moment là que vous créez votre propre tir-puis-avance (« Fire and motion ») : quand vous innovez. Faites quelque chose de nouveau qui forcera la compétition à tenter de vous rattraper. Si vous avez une compagnie aérienne, et que vos clients demande une télé collée sur le dos de chaque siège, ce qu’ils essaient de dire c’est que les vols longs sont ennuyeux. Peut-être pourriez vous remédier à ce problème sous-jacent ? Essayez de mettre en place un concours de chanson pendant le vol, et le perdant se fera éjecter de l’avion, avec un parachute. Ensuite asseyez vous tranquillement et regardez en souriant tous vos concurrents qui essaieront tant bien que mal de s’associer à une entreprise de parachutes. Et bien entendu ils perdront beaucoup d’argent inutilement, ce qui ne peut qu’être bon pour vous n’est-ce pas ?

Jusqu'à quel point peut-on pousser la machine ? (Part. I)

Par Joel Spolsky, mars 2008.

Cet article vient d’ici. Il est en deux parties. Vous trouverez la seconde partie ici.

Première partie

Je n’ai pas beaucoup dormi lorsque j’étais dans l’armée, en Israël, malgré le fait que j’aie servi durant une brève période de paix située entre la fin des gros combats au Liban et le début de l’intifada.

C’était en 1986. J’étais dans un camp d’entraînement de six mois pour devenir sergent d’infanterie et j’étais épuisé. Durant la période d’entraînement basique, nos officiers étaient durs avec nous, mais ils nous laissaient habituellement avoir nos six heures de sommeil par nuit. L’entraînement pour devenir sergent, lui, était plus dur : les officiers nous faisaient nous coucher à minuit, et nous lever à quatre heures du matin. Et pendant ces quatres heures, nous devions tous avoir un tour de garde d’une demi-heure. Pire : comme on ne s’était pas entraîné durant le Sabbath, on s’entrainait presque 30 d’affilée du jeudi au vendredi suivant. Nous étions en permanence épuisés ; on marchait comme des zombies pendant les exercices – exercices qui impliquaient l’utilisation de balles réelles, rien de moins que ça -et le manque de sommeil commençait à avoir un impact grave sur nos performances. Les gens étaient contrariés, et c’était bien plus que le simple fait de râler parce qu’on était soldat dans l’armée.

C’est à ce moment précis, en plein milieu d’un exercice ridiculement difficile (4 jours qui d’exercices qui comprenaient marche, course, simulation d’invasions, roulements dans la boue et autres futilités telles que monter et descendre des marches sans une minute de pause), que le brigadier-général est venu nous voir. Les officiers de ce grade, dans l’armée Israélienne, étaient les gentils policiers, et étaient là afin de nous aider à nous sentir mieux, tandis que les sergents qui nous commandaient au jour le jour étaient les méchants policiers. Il était donc là pour nous faire un discours de « bienfaisance ». Durant les premières minutes, le brigadier-général nous fit un discours brillant sur la strategié qui m’a appris plus en cinq minutes que tout ce que j’ai pu apprendre de dizaines de livres traitant du commerce. Cela concernait le « fire and motion » (« tir puis avance »), une idée qui consistait à alterner l’attaque de l’ennemi et l’avancée pour gagner un peu plus de terrain. Plus tard, lorsque j’ai travaillé à Microsoft, j’ai réalisé que c’était la metaphore parfaite sur la manière dont les compagnies technologiques devaient se comporter pour gagner des parts marché sur leurs concurrents. L’idée expliquée était si intéréssante que je vais consacrer une seconde partie (qui suit celle là) uniquement dessus.

Mais pour l’instant, je vais parler de l’effet général du discours au complet de notre homme. Tout le monde a ses forces et ses faiblesses, et il n’échappait pas à la règle. Malgré le fait que son discours était bien intentionné et intéréssant, la plupart des personnes, qui étaient épuisées, se battaient pour ne pas fermer les yeux et s’endormir. Un petit plus sympa pour le compte de l’armée : on nous avait autorisé à rester debout durant ce genre de discours, si cela pouvait nous aider à rester éveillés. Tout au long du disours, les têtes se levaient et s’abaissaient comme des sousliks.

Finalement, le discours toucha à sa fin et le général nous offrit de répondre à des questions, si nous en avions. « Quels sont les problèmes que vous avez ? », nous demanda-t-il. « Je suis là pour les résoudre pour vous ».

Très noble de votre part, monsieur.

A ce moment un soldat tout au fond de la foule a levé sa main. « Nous n’avons pas assez de temps pour dormir durant ce exercice », a-t-il dit. « Nous dormons à peu près trois heures par nuit. Nous commençons à faire des erreurs vraiment dangereuses avec de vraies munitions parce qu’on n’est pas clairs du tout. »

Les troupes d’élite Israéliennes ne sont pas des mauviettes. Elle n’exagèrent jamais.

Le général sourit et dit : « Ah ! Ce n’est pas un problème. Vous pouvez toujours trouver du temps pour dormir. Par exemple, je dors dans la voiture lorsque je me déplace ». Lui non plus ne plaisantait pas et n’exagérait rien. Ce qu’il voulait dire, c’était que vous pouviez toujours trouver du temps libre et que pendant ce temps libre il fallait en profiter pour faire une sieste, ce n’était pas plus compliqué que ça pour lui. Content de son excellente réponse, le général a de nouveau souri et puis il a fait un signe d’au-revoir.

Comme vous pouvez l’imaginer, l’effet sympatique qu’il pensait avoir fait n’a eu aucun résultat. Non, mon Général, en réalité, on ne peut pas trouver de temps pour dormir, avons-nous pensé. C’est ce qu’on essaie de vous dire, mon Général. On n’a pas de temps libre, et nous n’avons pas de chauffeur non plus : nous marchons, partout, avec au minimum vingt kilos de bagages inutiles sur le dos. Lorsque vous envoyez une petite goutte de café sur votre carte, mon Général, et que vous confondez cette tache avec une colline, cela signifie une marche-détour de 20 kilomètres supplémentaires pour nous. Quelques minutes après que le général soit parti, nous étions encore sous le coup du choc : ce type était complètement désolidarisé de l’expérience de ses propres troupes. Est-ce qu’il pensait vraiment qu’on était crevés parce que nous n’avions pas pensé à dormir à l’arrière de voitures conduites par un chauffeur ?

Lorsque j’ai crée ma société avec mes propres fonds, j’avais, et j’ai encore aujourd’hui, ce discours en tête. Cette désolidarisation complète, cette incapacité de comprendre ces troufions sur le champ de bataille, concerne aussi plein de dirigeants. C’est vraiment très facile d’oublier la vie des autres dans les tranchées, quand on n’y est pas. Après plusieurs années de travail jour et nuit, week-end compris, pour construire une compagnie qui tourne, après avoir sué sang et eau à trimer sur un bureau constitué par une porte posée sur deux tréteaux, les dirigeants d’une société en oublient que les employés qui travaillent pour eux ne sont pas les co-fondateurs : ce sont des employés. Si vous leur donnez une porte pour qu’ils la mettent à plat et s’en servent comme bureau, et que vous leur demandez de travailler le week-end, ils ne vont pas du tout voir les choses comme vous les voyez.

C’est normal. Ils n’ont pas crée la compagnie. Même si vous avez été généreux en leur donnant des stock options, vous êtes celui qui pourra finir avec un hélicoptère et une gigantesque maison en bord de mer à Cannes. Si tout fonctionne à merveille, dans le meilleur des cas, ils auront une jolie petite maisonnette dans le Sud de la France et pourront payer une bonne école à leurs enfants.

Les bons employés peuvent être dévoués, bien sûr, et c’est tout à fait raisonnable de s’attendre à ce qu’ils se décarcassent. Mais, à l’inverse des fondateurs, les employés se sentent concernés par ce qu’il se passe aujourd’hui, maintenant. Ils ne sont pas super enthousiastes pour faire des sacrifices à long terme. Alors ne dites pas à votre excellent chef des ventes de rester ici, juste après un coup de fil important de ses parents qui sont à 200 km de son travail, même si c’est ce que vous avez fait lorsque vous avez démarré la société.

Bosser comme un dingue vous faisait peut-être plaisir et vous faisiez ça gratuitement en rêvant, pendant votre boulot, à la bonne retraite que vous aurez sur un magnifique bateau à St. Tropez ou bien comment vous régalerez vos petits enfants à leur raconter vos histoires du pain dur que vous avez dû manger lorsque vous avez commencé. Mais cette femme, développeur, super intelligente, que vous avez embauché pour vous construire complètement votre site Internet ? Vous pensez qu’elle n’a jamais entendu parler des excellents repas de cantine chez Google ? (NASDAQ:GOOG)

Je dis encore et toujours ces mêmes choses aux patrons qui n’ont toujours pas réalisé cela, lorsqu’ils sont déçus et qu’ils virent tous leurs employés, mauvais et bons, en demandant toujours « pourquoi Olivier (ou Jeanne) n’a pas encore fini son travail ? Je l’aurais terminé ce week-end ! »

Ce général m’a appris une autre leçon sur les subtilités de la direction. Il était arrivé dans un énorme 4×4 flambant neuf, climatisé. Son uniforme était impeccable, et (tenez vous bien, vous allez être surpris) repassé. Je ne savais pas que le fait de dormir peut automatiquement repasser les habits que l’on porte. Ça n’a fait qu’une chose supplémentaire : le démarquer encore plus de nous et de souligner le fait qu’il vivait vraiment dans un monde complètement différent.

De la même façon, lorsqu’une compagnie commence à décoller, et que son fondateur commence à gagner un peu d’argent, il doit garder à l’esprit ce que c’est que d’être salarié. Quelque soit le montant du salaire de vos employés, l’idée qu’il se feront de l’argent sera toujours différente de la vôtre. Vous ne pouvez pas montrer que vous gagnez plein d’argent et espérer qu’ils ne s’en apercevront pas. J’ai entendu parler d’un PDG, embauché dans une start-up en tant que « professionnel expérimenté », qui avait déjà fait sa petite fortune. La compagnie n’avait pas encore commencé à décoller. Bien au contraire, elle démarrait, et tout le monde faisait des sacrifices et travaillait de longues heures pour réussir à faire avancer les choses. Mise à part le PDG. Comme mon général à l’armée, il semblait être dans un monde totalement différent. Il vivait en Californie, et le business était à New York, donc il ne se donnait la peine d’être présent à son bureau que peu de jours par semaine. Il avait pourtant bien donné l’instruction à son équipe de l’appeler si jamais il y avait un problème. « Surtout ne vous inquiétez pas », leur avait-il dit, « j’ai un téléphone portable à côté de la piscine ». Quel que soit le problème, son teint hâlé est devenu le symbole même de tout ce qui n’allait pas dans la société. Imaginez comment auraient été les personnes de l’équipe si, en plus du comportement de leur PDG, ils n’avaient dormi que quatre heures par nuit.

Librairie Apr : tutoriels 8 et 9

8. gestion des chaines de caractères

Je suppose que vous connaissez les bases de manipulation de chaine en C, notamment les fonctions strlen(3) et strcpy(3). La librairie libapr propose des fonctions extrêmement utiles de gestion des chaines. Elles sont pratiquement les mêmes que leur équivalent en ANSI C. Pourquoi libapr fournit encore une autre possibilité de gestion de chaines ? L’intérêt est directement lié avec le principe de gestion par pool mémoire. Dans une gestion habituelle de chaine en C, il faut écrire du code de gestion de mémoire : allocation, libération, etc. Le code qui suit en est l’exemple.

/* exemple de manipulation de chaine ANSI C */
/* (code simpliste) */
/* on concatène 3 chaines : s1, s2, s3 */
int len1 = strlen(s1);
int len2 = strlen(s2);
int len3 = strlen(s3);
int total_len = len1 + len2 + len3;
char *cat_str = malloc(total_len + 1);
strcpy(cat_str, s1);
strcat(cat_str, s2);
strcat(cat_str, s3);
/* plus tard, il nous faut libérer la mémoire allouée */
free(cat_str);

La même chose avec la librairie libapr s’écrira ainsi :

/* pseudo code sur la gestion des chaines de libapr */
apr_pool_t *mp;
apr_pool_create(&mp, NULL);
/* apr_pstrcat() gère à la fois l'allocation
 * mémoire et la concaténation des chaines
 * Si la chaine concaténée est en lecture seule,
 * il nous faut utiliser le type 'const char*'.
 */
const char *cat_str = apr_pstrcat(mp, s1, s2, s3, NULL);
/* plus tard, la seule chose à faire
 * est de détuire le pool mémoire
 * pour tout libérer
 */
apr_pool_destroy(mp);

De la même façon que apr_pstrcat(), apr_psprintf() vous aide à écrire un code beaucoup plus simple. Vous trouvez d’autres fonctions sur les chaines dans apr_strings.h.

9. Gestion de de l’heure

Les fonctions mises à disposition par libapr sont basées sur le schéma POSIX. Une valeur de type apr_time_t représente le temps écoulé depuis une époque UNIX c’est à dire depuis le 1/1/1970. Seulement il y a deux différences de taille :

  1. apr_time_t est géré sur 64 bits (long long)
  2. apr_time_t réprésente des microsecondes

La fonction la plus utile est apr_time_now(). Comme vous l’imaginez, elle renvoie la date et l’heure courante. Vous trouverez sa déclaration dans apr_time.h.

/* extrait de apr_time.h */
APR_DECLARE(apr_time_t) apr_time_now(void);

Très souvent nous avons à convertir une valeur apr_time_t dans d’autres formats. Il y a principalement deux formats qui vous seront utiles :

  1. Une structure temps : apr_time_exp_t (time structure)
  2. Les formats exprimant les dates sous forme de chaines (p.ex. la rfc822)

Pour convertir apr_time_t en une structure apr_time_exp_t, il faut utiliser les fonctions de la libapr suivantes :

/* extrait de apr_time.h */
APR_DECLARE(apr_status_t) apr_time_exp_gmt(
    apr_time_exp_t *result, apr_time_t input);
APR_DECLARE(apr_status_t) apr_time_exp_lt(
    apr_time_exp_t *result, apr_time_t input);

La fonction apr_time_exp_gmt() renvoie le résultat qui est dans une zone GMT, et apr_time_exp_lt() renvoie le résultat en se basant sur la zone de temps locale. Le premier argument des deux fonctions est un argument résultat.
Il est possible de faire la conversion dans l’autre sens : convertir une structure apr_time_exp_t en une valeur apr_time_t.

/* extrait de apr_time.h */
APR_DECLARE(apr_status_t) apr_time_exp_get(
    apr_time_t *result, apr_time_exp_t *input);

Il y a plusieurs fonctions pour convertir une valeur apr_time_t en différents formats de chaines représentant une date / heure :

/* extrait de apr_time.h */
APR_DECLARE(apr_status_t) apr_rfc822_date(
    char *date_str, apr_time_t t);
APR_DECLARE(apr_status_t) apr_ctime(
    char *date_str, apr_time_t t);
APR_DECLARE(apr_status_t) apr_strftime(
    char *s, apr_size_t *retsize, apr_size_t max,
    const char *format, apr_time_exp_t *tm);

A l’inverse, si on a des chaines dans ces formats, et qu’on veut les convertir en une valeur apr_time_t, il faut appeler des fonctions utilitaires de apr-util (un sous ensemble de la libapr), définis dans apr_date.h.
Regardez l’exemple de time-sample.c pour avoir un exemple concret de l’utilisation de ces fonctions.
REMARQUE : Comme expliqué juste avant, apr_time_t est un type long long (64 bits). Notez bien que le code suivant déclenchera un débordement.

/* Exemple BOGUE. Génération de débordement */
const apr_time_t UNE_HEURE = 1000 * 1000 * 60 * 60;

On le résoud en faisant une conversion de type explicite, mais je vous recommande d’utiliser simplement le type que fournit la librairie libapr. Le code suivant le montre.

/* deux exemples pour contourner
 * le débordement expliqué juste avant
 */
const apr_time_t UNE_HEURE = APR_TIME_C(1000) * 1000 * 60 * 60;

ou bien :

const apr_time_t UNE_HEURE = APR_USEC_PER_SEC * 60 * 60;

REMARQUE : Parfois, souvent en déboguant, on veut afficher des valeurs de temps en clair. Malheureusement, Unix et Windows ont des manière différentes de spécifier le type 64 bits quand on se sert de printf(3). Sur Unix c’est « %lld » est sur Windows c’est « %I64d ». Pour de tels problèmes de portabilité, la librairie libapr fournit des spécificateurs de format, p.ex. APR_INT64_T_FMT. Il y a aussi APR_TIME_T_FMT dans apr_time.h. On peut écrire du code parfaitement portable en utilisant ces spécificateurs.

/* Sur Unix, APR_INT64_T_FMT est défini dans apr.h */
#define APR_INT64_T_FMT "lld"
/* Sur Windows, APR_INT64_T_FMT est défini dans apr.h */
#define APR_INT64_T_FMT "I64d"
/* extrait de apr_time.h */
#define APR_TIME_T_FMT APR_INT64_T_FMT
/* On peut utiliser APR_TIME_T_FMT de cette façon : */
printf("L'heure courante est : %" APR_TIME_T_FMT "[us]\n",
    apr_time_now());

Librairie Apr : tutoriel : fichier time-sample.c

/**
 * Exemple du tutoriel apr
 * http://dev.ariel-networks.com/apr/
 */
#ifdef HAVE_CONFIG_H
#include 
#endif

#include 
#include 
#include 

#include 
#include 

static void format_to_struct(apr_time_t t)
{
    apr_time_exp_t tm;
    apr_time_t t2;

    apr_time_exp_gmt(&tm, t);
    printf("GMT: tm.hour = %d, tm.min = %d, tm.sec = %d\n", tm.tm_hour, tm.tm_min, tm.tm_sec);
    apr_time_exp_lt(&tm, t);
    printf("local: tm.hour = %d, tm.min = %d, tm.sec = %d\n", tm.tm_hour, tm.tm_min, tm.tm_sec);

    /* conversion inverse */
    apr_time_exp_gmt_get(&t2, &tm);/* from tm to t2 */
    assert(t == t2);
}

static void format_to_string(apr_time_t t)
{
    char rbuf[APR_RFC822_DATE_LEN + 1];
    char cbuf[APR_CTIME_LEN + 1];

    apr_rfc822_date(rbuf, t);
    printf("apr_rfc822_date: %s\n", rbuf);
    apr_ctime(cbuf, t);
    printf("apr_ctime: %s\n", cbuf);
}

/**
 * Exemple des routines de gestion de l'heure
 * @remark Vérif. des erreurs omise
 */
int main(int argc, const char *argv[])
{
    apr_pool_t *mp;
    apr_time_t t;

    apr_initialize();
    apr_pool_create(&mp, NULL);

    /* récupérer l'heure courante
     * (temps écoulé depuis le 1/1/1973, en micro-secondes)
     */
    t = apr_time_now();
    printf("Heure courante : %" APR_TIME_T_FMT "[us]\n", t);
    printf("Heure courante : %" APR_TIME_T_FMT "[ms]\n", apr_time_as_msec(t));
    printf("Heure courante : %" APR_TIME_T_FMT "[s]\n", apr_time_sec(t));

    /* formattage de l'heure */
    format_to_struct(t);
    format_to_string(t);

    apr_terminate();
    return 0;
}

Librairie Apr : tutoriel : dir-sample.c

Note

Regardez le tutoriel au complet, en Anglais, ici.
Vous trouverez tout ce tutoriel séparé en plusieurs pages ici.
Ce fichier est l’exemple le plus simple pour mettre en oeuvre les fonctions apr_xx
Il vient d’ici.

/**
 * Exemple de code tutoriel
 * http://dev.ariel-networks.com/apr/
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <apr_general.h>
#include <apr_file_info.h>
#include <apr_strings.h>

/**
 * Parcours d'un répertoire de manière récursive
 * @return TRUE si tout est Ok, sinon FALSE.
 */
static int traverse_dir(const char *dirpath, apr_pool_t *mp)
{
    apr_status_t rv;
    apr_finfo_t dirent;
    apr_dir_t *dir;

    printf("Directory: %s\n", dirpath);
    if ((rv = apr_dir_open(&dir, dirpath, mp)) != APR_SUCCESS) {
        return FALSE;
    }

    while ((apr_dir_read(&dirent,
                         APR_FINFO_DIRENT | APR_FINFO_TYPE | APR_FINFO_NAME,
                         dir)) == APR_SUCCESS) {
        if (dirent.filetype == APR_DIR) {
            char *path;
            if (strcmp(dirent.name, ".") == 0 || strcmp(dirent.name, "..") == 0) {
                continue;
            }

            if ((rv = apr_filepath_merge(&path,
                                         dirpath,
                                         dirent.name,
                                         0,
                                         mp)) != APR_SUCCESS) {
                goto error;
            }
            /* beaucoup plus simple :
             * path = apr_pstrcat(mp, dirpath, "/", dirent.name, NULL);
             */
             traverse_dir(path, mp);
        } else if (dirent.filetype == APR_REG) {
            printf("Nom de fichier normal/classique : %s\n",
                apr_pstrcat(mp, dirpath, "/", dirent.name, NULL));
        } else {
            printf("Nom de fichier anormal/pas classique : %s\n",
                apr_pstrcat(mp, dirpath, "/", dirent.name, NULL));
        }
    }

    if ((rv = apr_dir_close(dir)) != APR_SUCCESS) {
        return FALSE;
    }
    return TRUE;

 error:
    apr_dir_close(dir);
    return FALSE;
}

/**
 * Exemple de listing d'un répertoire
 * @remark Vérif. des erreurs omises
 */
int main(int argc, char **argv)
{
    apr_status_t rv;
    apr_pool_t *mp;
    const char *dirname;
    apr_finfo_t finfo;

    if (argc == 2) {
        dirname = argv[1];
    } else {
        dirname = ".";
    }

    apr_initialize();
    apr_pool_create(&mp, NULL);

    if ((rv = apr_stat(&finfo,
                       dirname,
                       APR_FINFO_TYPE, mp)) != APR_SUCCESS) {
        goto error;
    }
    if (finfo.filetype != APR_DIR) {
        printf("precisez un nom de repertoire\n");
        goto error;
    }
    traverse_dir(dirname, mp);

    apr_terminate();
    return 0;

 error:
    apr_terminate();
    return -1;
}

News fin mai début juin 2008

Splitch splatch flock

Flock a récupéré 15 millions de dollars dans un round Serie D, par Fidelity Ventures (qui comprend déjà les investisseurs précédents Bessemer Venture Partners, Catamount Ventures et Shasta Ventures).

Flock est un browser Internet orienté « social » construit sur le code de Firefox. Flock se définit comme intégrant plusieurs sites de réseaux sociaux et des services directement inclus dans le navigateur avec, par exemple, MySpace, Facebook, YouTube, Twitter.

Le nombre d’utilisateurs de Flock a augmenté de 250% depuis janvier de cette année, avec un bénéfice qui a augmenté de 400% sur la même période. Flock a été nommé comme gagnant du « Webby Award », catégorie « Réseau Social », battant Facebook et Bebo.

Flock a dit que l’argent investi allait servir à étendre le business de Flock, notamment le département recherche et développement, le marketing et l’expansion dans des marchés plus génériques.

Twitter

Twitter a terminé un tour de table qui a levé 15 millions de dollars, ce qui amène sa valeur à 80 millions de dollars, a affirmé GigaOm.

Des rumeurs circulent depuis des mois, expliquant que Twitter tente de faire d’autres levées de fonds, et certains sons de cloche laissaient entendre que de tour de table a été plusieur fois repoussé principalement parce que Twitter était plutôt radin et tentait de se faire évaluer à quelques 200 millions de dollars, donc plus personne ne voulait miser.

J’ai aussi trouvé quelque part sur un site (je ne souviens pas où) que le fait que Twitter ait eu des gros problèmes pour s’étendre (manque de souplesse) (« scaling failure ») ne voulait rien dire parce que même les personne qui se plaignaient n’auraient pas quitté ce service de toute manière, ce qui n’est pas mauvais, mais il y a un énorme espoir sur le fait que quelques 15 millions de dollars seront investis afin de pouvoir garder toujours ce service en fonctionnement, et qu’il puisse mieux grossir. Comme Twitter se veut la plateforme de prédilection pour le microblogging, la plupart des compagnies qui proposent des services autour de Twitter sont principalement des sociétés qui proposent un service en-ligne 24/7, pardonnez du peu.

Ce nouveau tour amène les investissements dans Twitter à une hauteur de 20 millions de dollars.

Napster

Napster amène ce qu’il appelle « le plus grand magasin de mp3’s au monde ».

Le vendeur de musique en ligne vient tout juste de lancer sa base de fichiers mp3’s libres de droits, ce qui veut dire que les chansons seront compatibles avec n’importe quel programme, player, ou autre, capable de jouer des mp3’s (qui ne le fait pas aujourd’hui ?).

« Les fans de musique ont parlé et c’est clair qu’ils veulent un format mp3 libre de DRM, et ce, aussi bien chez le plus gros labels de distribution que chez les artistes indépendants, le tout à un seul endroit », affirme Chris Gorog, directeur PDG de Napster.

Napster dit que son nouveau magasin fait plus d’une fois et demi la taille de n’importe quel autre vendeur de m3’s en ligne, avec plus de six millions de chansons à disposition. Celles ci sont vendues à un prix allant de 0,99 dollars l’un jusqu’à 10 dollars pour l’album entier.

Micro$oft

Microsoft lance un nouveau programme qui va vous payer si vous utilisez son site de recherche.

“Microsoft Live Search Cash Back” fonctionnera avec eBay et PayPal pour offrir aux utilisateurs du cash lorsqu’ils achèteront des produits qu’ils auront trouvé via Microsoft Live. De partout, les réductions iront de 30 pourcent jusqu’à 100 % (le prix entièrement remboursé sur votre compte eBay ou PayPal !). Barnes and Noble, Sears, et Home Depot sont déjà présents parmi les résultats de recherche.

Microsoft va vous demander de créer un acompte pour avoir ces reversements.

Le discours officiel de Microsoft ressemble à : “Nous cherchons à nous différencier via des expériences verticales, et à casser le modèle courant”.

Traduction de notre technicien spécialiste dernières technologies : “Nous sommes tellement désespérés que les internautes ne passent que par Google qu’on en arrive à leur offrir un peu d’argent pour les aider à changer leurs habitudes”.

Immobilier et business

Si Zillow est le meilleur endroit (Anglais) pour ceux qui veux acheter un bien immobilier personnel, ZoomProspector espère devenir le meilleur endroit pour ceux qui veulent faire des transactions sur des commerces, en fournissant des informations géographiques importantes et des conseils sur l’endroit où ils veulent construire/acheter leur(s) commerce(s).

ZoomProspector fait un melting-pot d’informations sur les villes, régions et alentours – par exemple le taux de chômage, le nombre de travailleurs, le niveau moyen d’éducation, l’investissement fait dans l’immobilier, et une moyenne des loyers – et toutes ces informations sont accessibles via un seul et unique outil de recherche à l’intérieur d’une carte.

La recherche avancée sur google : les pages récentes

Article original en Anglais ici.

Une des astuces les plus pratiques dans la recherche avancée de Google est le filtre « date », qui limite les résultats aux pages trouvées récemment. Les résultats peuvent être limités au dernier jour, à la dernière semaine, mois, années, etc.

Matt Cutts, de Google, et GoogleOperatingSystem en ont parlé en fin d’année dernière.

Vous pouvez accéder à ce filtre via l’URL, directement, en ajoutant simplement “&as_qdr=d” à la fin de n’importe quelle requête : comparez les deux résultats : Apple et Apple uniquement aujourd’hui. Changez simplement le « =d » en d5 pour 5 jours, ou w5 pour 5 semaines (w=weeks), ou y5 pour 5 ans, etc.

Librairie Apr : tutoriel : fichier flock-sample.c

Note

Regardez le tutoriel au complet, en Anglais, ici.
Vous trouverez tout ce tutoriel séparé en plusieurs pages ici.
Ce fichier exemple vient d’ici.

/**
 * Exemple pour le tutoriel apr
 * http://dev.ariel-networks.com/apr/
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <apr_general.h>
#include <apr_file_io.h>

static apr_status_t do_writelock(const char *fname, apr_pool_t *mp)
{
    apr_status_t rv;
    apr_file_t *fp;

    if ((rv = apr_file_open(&fp, fname, APR_WRITE, APR_OS_DEFAULT, mp)) != APR_SUCCESS) {
        return rv;
    }
    rv = apr_file_lock(fp, APR_FLOCK_EXCLUSIVE | APR_FLOCK_NONBLOCK);
    /* si vous mettez le drapeau APR_FLOCK_NONBLOCK, apr_file_lock() ne fonctionnera pas.
     * Il faut toujours vérifier la valeur de retour */
    if (rv != APR_SUCCESS) {
        puts("writable-lock failed");
        goto done;
    }
    printf("%s est verrouillé en écriture.\n", fname);
    printf("Appuyez sur une touche pour le déverrouiller.\n");
    getchar();

    apr_file_unlock(fp);
 done:
    apr_file_close(fp);
    return rv;
}

static apr_status_t do_readlock(const char *fname, apr_pool_t *mp)
{
    apr_status_t rv;
    apr_file_t *fp;

    if ((rv = apr_file_open(&fp, fname, APR_READ,  APR_OS_DEFAULT, mp)) != APR_SUCCESS) {
        return rv;
    }
    rv = apr_file_lock(fp, APR_FLOCK_SHARED | APR_FLOCK_NONBLOCK);
    if (rv != APR_SUCCESS) {
        puts("Impossible de mettre le verrou en lecture.");
        goto done;
    }

    apr_file_unlock(fp);
 done:
    apr_file_close(fp);
    return rv;
}

/**
 * Exemple de verrou fichier
 * @remark Vérif. des erreur supprimée pour plus de clarté
 */
int main(int argc, const char *argv[])
{
    apr_status_t rv;
    apr_pool_t *mp;
    int c;
    const char *fname;

    if (argc < 2) {
        printf("Utilisation : %s fichier-de-sortie\n", argv[0]);
        return 0;
    }
    fname = argv[1];

    apr_initialize();
    apr_pool_create(&mp, NULL);

    puts("verrou-écriture / verrou-lecture [w/r]?");
    c = getchar();
    if (c == 'w') {
        rv = do_writelock(fname, mp);
    } else if (c == 'r') {
        rv = do_readlock(fname, mp);
    }

    apr_pool_destroy(mp);
    apr_terminate();
    return 0;
}

Librairie Apr : tutoriels : 6 et 7

6. Les verrous sur les fichiers

Lorsqu’on veut verrouiller des fichiers entre processus, il faut utiliser apr_file_lock(). Historiquement, des confusions se sont installées concernant le verouillage sur Unix. C’est pourquoi le fait de n’avoir que deux fonctions simples grâce à la librairie libapr est très appréciable.

/* extrait de apr_file_io.h */
APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *thefile, int type);
APR_DECLARE(apr_status_t) apr_file_unlock(apr_file_t *thefile);

apr_file_lock() demande deux arguments. Le premier est un objet apr_file_t. Le second est un drapeau (« flag »), qui sert à spécifier les blocages qu’on veut imposer (« lock type »). Il peut être soit APR_FLOCK_SHARED, soit APR_FLOCK_EXCLUSIVE. We can use the former as a readable lock, and the latter as a writable lock. Pour déverrouiller le fichier, il suffit d’appeler apr_file_unlock(). Ou bien le fait d’appeler apr_file_close() le déverrouille implicitement. Regardez flock-sample.c pour savoir comment faire.
De plus, il est possible d’utiliser un paramètre composé de drapeaux (« bitwised-or flag ») en précisant APR_FLOCK_NONBLOCK. Sans le flag APR_FLOCK_NONBLOCK, apr_file_lock() est bloquant. Avec ce flag, APR_FLOCK_NONBLOCK, si apr_file_lock() ne peut pas verouiller un fichier, il ne bloque pas et renvoie immédiatement un code erreur : APR_EAGAIN.
Il faut toujours s’assurer que la valeur de retour de apr_file_lock() est APR_SUCCESS. Si c’est le cas, le fichier a été verouillé avec succès. Sinon, il n’a pas pu être verouillé.

7. Gestion des répertoires dans le système de fichiers

Quand on veut faire quelque chose avec des répertoires, il faut toujours appeler d’abord apr_dir_open(). Après cet appel, on a un objet apr_dir_t. La seule chose que l’on puisse faire avec un objet apr_dir_t est de parcourir le répertoire. La fonction à utiliser est apr_dir_read(). A la fin on appelle apr_dir_close() pour fermer le répertoire. Ci-suivent les déclarations de la librairie :

/* extrait de apr_file_info.h */
APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new_dir,
    const char *dirname, apr_pool_t *pool);
APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo,
    apr_int32_t wanted, apr_dir_t *thedir);
APR_DECLARE(apr_status_t) apr_dir_close(apr_dir_t *thedir);

Le premier argument de apr_dir_open() est un argument résultat. C’est grâce à lui qu’on récupère l’objet apr_dir_t qui est crée. Le second argument est le nom du répertoire. Le troisième est le nom du pool mémoire à utiliser.
Le premier arguement de  apr_dir_read() est un argument résultat. Comme mentionné précédemment, apr_finfo_t est un type complet. Donc il faut l’allouer explicitement. apr_dir_read() renvoie une entrée du répertoire  apr_finfo_t. L’entrée est soit un fichier soit un répertoire. Le second argument est une aggrégation de drapeaux (« bit-wised flag »). Ces drapeaux sont définis dans apr_file_info.h. Ils ont tous le préfixe APR_FINFO_, par exemple APR_FINFO_SIZE, APR_FINFO_TYPE et APR_FINFO_NAME. Le troisième argument est l’objet apr_dir_t à parcourir.

Voici un code d’exemple :

/* pseudo code expliquant apr_dir_read() */
/* no error checks */
apr_pool_t *mp;
apr_pool_create(&mp, NULL);
/* répertoire à scanner */
const char *dirpath = "/home";
apr_dir_t *dir;
/* créer l'objet apr_dir_t */
apr_dir_open(&dir, dirpath, mp);
apr_finfo_t dirent;
/* remplir l'objet apr_finfo_t */
apr_dir_read(&dirent, APR_FINFO_DIRENT, dir);
/* dirent est la première entrée du répertoire.
 * Cette entrée est soit un fichier soit un répertoire. */
apr_dir_close(dir);

Dans l’exemple au-dessus, on appelle apr_dir_read() une seule fois, mais habituellement on le fait en boucle pour énumérer tous les fichiers d’un répertoire. Pour ce faire, il suffit juste d’appeler apr_dir_read() tant qu’il renvoie APR_SUCCESS. Regardez l’exemple qui est plus parlant : dir-sample.c.

/* pseudo code sur la boucle apr_dir_read(). Vérif. des erreurs omise */
/* Boucle typique de apr_dir_read() */
apr_dir_open(&dir, dirpath, mp);
while ((apr_dir_read(&dirent, APR_FINFO_NAME, dir)) == APR_SUCCESS) {
    printf("Le nom est %s\n", dirent.name);
}
apr_dir_close(dir);

Comme vous pouvez l’imaginer, la position courante du répertoire est stockée dans l’objet apr_dir_t. Le fait d’appeler apr_dir_read() fait avancer la position d’un cran. On peut reculer cette potision (qui est interne) en appelant apr_dir_rewind(). Les seules opération que l’on peut faire avec la position sont ces deux là : aller en avant et aller en arrière.

Comme vous pouvez le voir dans dir-sample.c, si vous scannez un répertoire de manière récursive, vous devez appeler apr_dir_open() de manière récursive, ici aussi.

REMARQUE : Sur Unix, apr_dir_read() renvoie un objet apr_finfo_t dont la propriété apr_file_t::fname est NULL.