Obsidian a écrit 5291 commentaires

  • [^] # Re: Re :

    Posté par  . En réponse au message interception de fermeture de fenêtre. Évalué à 5.

    Si tu veux mais ça ne changera RIEN à ton problème de terminal. Le seul moyen d'empêcher sa fermeture serait de lui envoyer une séquence de code, CSI, OSC ou autres qui lui en donne explicitement l'instruction mais après avoir rapidement parcouru la liste de ces séquences et les sources de xterm hier soir, je n'ai rien vu qui ressemble de près ou de loin à cela.

    En revanche, un langage de programmation tel que le C ou le Python te permettrait effectivement d'ouvrir tes propres fenêtres et de les gérer comme tu le souhaites, mais c'est un autre niveau. Sans être vraiment difficile, il faut quand même initialiser un contexte, gérer une boucle principale, etc.

  • [^] # Re: Re :

    Posté par  . En réponse au message interception de fermeture de fenêtre. Évalué à 4.

    Juste un petit détail : tous les commentaires ici sont munis de leur propre lien « répondre ». Comme Linuxfr.org organise les discussions en arbre, ce qui est à la fois rare et très agréable, c'est mieux si tu veilles à les utiliser. :-)

    Pour le reste, il faut savoir que lorsque tu ouvres un terminal, tu n'ouvres pas un shell comme si tu ouvrais une « boîte DOS ». Tu crées en fait un véritable terminal virtuel qui s'exploite à travers une pseudo liaison série. Par défaut, le fait de lancer un xterm provoque automatiquement le lancement d'un shell qui y est relié, mais ce n'est pas nécessairement le cas. Il peut très bien rester passif jusqu'à ce qu'une application externe prenne d'elle-même l'initiative d'envoyer quelque chose vers ce port.

    Cela veut dire le terminal X-Term et l'application qui tourne dedans ne sont pas du tout liés entre eux et qu'ils ne communiquent qu'à travers une sorte de pipe bidirectionnel. Donc, tu ne peux pas empêcher le xterm de se refermer puisque c'est une application distincte. Tu peux simplement agir en conséquence.

  • [^] # Re: L'auto-hébergement d'amateur, ce fléau

    Posté par  . En réponse au journal Newton Adventure la soluce 1/6: la terrible jungle. Évalué à 2.

    Bref, quand tu auras D6D d'être de retour dans le présent, fais-moi 6gne.

    Bof, de toutes façons, à l'heure d'iPot, ça ne sert plus à rien de rester dans le présent.
    D'ailleurs le chrono-télé-travail, c'est l'avenir (ou le passé, enfin c'est pas le présent, quoi).

    →[].

  • [^] # Re: caractères bizare dans le nom de fichier ?

    Posté par  . En réponse au message Copier un fichier qui "n'existe pas". Évalué à 7.

    Bon, puisqu'on est vendredi :

    — Même dans ce fil, reconnais que mon commentaire initial reste beaucoup plus utile que les tiens ;
    — Ça fait 13 ans maintenant que je participe à ce forum et je pense modestement avoir rendu service à un certain nombre de personnes ;
    — Quitte à poster pour ne rien dire, essaie au moins de relire le fil avant de poster, ça m'évitera d'avoir à me répéter et d'augmenter le niveau de bruit.

    Allez zou ! →[].

  • [^] # Re: caractères bizare dans le nom de fichier ?

    Posté par  . En réponse au message Copier un fichier qui "n'existe pas". Évalué à 1.

    C'est ce que je dis : « -b » était approprié mais la man page Linux déclare que c'est une option GNU, et comme l'option n'était pas disponible du tout sur un des mes shells sous OpenBSD, je m'en suis tenu à ce que j'avais écrit et je ne suis pas allé voir si le LS d'AIX proposait la même option. J'aurais dû.

  • [^] # Re: caractères bizare dans le nom de fichier ?

    Posté par  . En réponse au message Copier un fichier qui "n'existe pas". Évalué à 2.

    Exact. C'est écrit « OPTIONS GNU » dans les man pages linux et ça ne marche pas sous OpenBSD, donc je n'étais pas allé chercher plus loin.

  • [^] # Re: caractères bizare dans le nom de fichier ?

    Posté par  . En réponse au message Copier un fichier qui "n'existe pas". Évalué à 4.

    Essaie d'utiliser l'auto-complétion avec la touche TAB. Si le shell est propre, soit il te l'encadrera avec des guillemets ou des « quotes », soit il te mettra des anti-slashes devant les caractères à problème. Sinon, tu peux toujours essayer un « find . -inum | hexdump » ou autre éditeur hexa pour voir s'il te les affiche explicitement.

  • [^] # Re: Ça suffit maintenant

    Posté par  . En réponse au journal Il n'y a pas que le sexisme des linuxiens qui fait débat. Évalué à 3.

    Envoie un patch.

  • # Changeons le thème

    Posté par  . En réponse au journal Il n'y a pas que le sexisme des linuxiens qui fait débat. Évalué à 10.

    Pour dépoussiérer une franchise vieillissante, l'éditeur d'un jeu vidéo à décidé de faire subir un viol à son héroïne. […]
    La miss est plaquée au sol ; les mains attachées dans le dos (…). […]
    Le tollé couve lentement mais sûrement et commence à se propager. Heureusement, c'est la fin du vendredi et le code source du jeu n'est pas disponible.
    Par contre, les complotistes vont pouvoir passer le weekend à se demander si des "ultra-féministes" - n'ayons pas peu des mots - ne sont pas en train de
    faire un raid dans cet univers informatique qui semblait si tranquille.

    D'un autre côté, si c'est Lara Croft qui ligote un type au sol et qui le viole, ça ferait encore plus de ventes, je crois…

    →[]

  • [^] # Re: Plagiat évident !!!!!

    Posté par  . En réponse au journal Nouveau logo MS. Évalué à 2.

    Ah, moi c'est l'inverse, c'est le logo « corporate » que je préfère. Et le dernier, au contraire, me fait l'effet d'une application X-Window mal configurée qui se rabattrait sur la fonte par défaut faute de trouver la bonne. Il est bien possible, malgré tout, que ce logo ait fait l'objet d'un vrai travail et que les caractères aient été dessinés individuellement mais, malgré tout, j'ai l'impression de voir la fonte Arial.

    Je pense qu'un tel logo se fait en trois minutes sous Excel, carreaux compris. :-)

  • # Par d'erreur…

    Posté par  . En réponse au journal Nouveau logo MS. Évalué à 7.

    Moi je trouve que c'est surtout un plagiat de ceci :-)

    Lesieur

  • [^] # Re: Que pensez-vous de…

    Posté par  . En réponse au message Recherche bonne source pour apprendre le C++. Évalué à 3.

    Moi j'aime beaucoup le cours de Christian Casteyde : http://casteyde.christian.free.fr/cpp/cours/online/book1.html

    Il y a des esprits chagrins qui lui reprochent d'avoir mélangé C et C++ mais en réalité, il fait le tour de ce qui est réellement commun aux deux langages jusqu'au chapitre 8, à partir duquel le reste est C++ only. Je le trouve exhaustif, bien structuré, il est en français et, cerise sur le gâteau, en GFDL.

  • [^] # Re: cable ordinaire

    Posté par  . En réponse au message Cable micro-usb pour smartphone. Évalué à 5.

    En principe, toutefois, on ne peut rien reprocher à un tel câble s'il n'est pas frappé du logo USB officiel, et il y a effectivement des chances pour qu'il ne le soit pas.

  • [^] # Re: compteur ?

    Posté par  . En réponse au journal Parlons C, parlons pipe !. Évalué à 5.

    Un journal qui parle de langage C, qui tente de résoudre un cas de figure technique et qui finit en troll politico-sexiste dès le cinquième niveau d'imbrication : pas de doute, on est bien sur DLFP. Tout va bien. :-)

  • [^] # Re: ça marche !

    Posté par  . En réponse au journal Et Dieu inventa le soutien gorge !. Évalué à 3.

    C'est une très bonne chose en soi ! Mais il est important de le faire uniquement pour les cas non définis par la norme ou alors explicitement marqués comme indéfinis par elle. Et en l'occurrence, dans le dernier draft de C99 (n1256.pdf), section § 6.7.2.1, on lit :

    6.7.2.1 Structure and union specifiers

    13
    Within a structure object, the non-bit-field members and the units in which bit-fields
    reside have addresses that increase in the order in which they are declared. A pointer to a
    structure object, suitably converted, points to its initial member (or if that member is a
    bit-field, then to the unit in which it resides), and vice versa. There may be unnamed
    padding within a structure object, but not at its beginning.

    Donc, tu es sûr que l'adresse du premier élément d'une structure sera toujours l'adresse de la structure elle-même avec tout compilateur qui se respecte (et qui, surtout, respecte la norme), ce qui permet d'échafauder de façon tout-à-fait officielle et sans warning des montages comme celui de XEvent.

    Ça s'explique également par le fait que le padding est généralement utilisé à des fins d'alignement et que, si tu dois aligner un membre, alors tu auras besoin d'aligner de la même façon la structure entière d'une manière générale.

  • [^] # Re: compteur ?

    Posté par  . En réponse au journal Parlons C, parlons pipe !. Évalué à 2.

    Oui mais justement, même pour quelques octets, c'est plus simple et plus efficace : en fait, la méthode des décalages telle que tu l'as écrite n'est intéressante qu'à partir du moment où ta file tient sur un seul entier (ou que les mots que tu empiles ne sont pas multiples de huit bits). Dès que tu dépasses 8 octets (si l'on considère le cas du long long), alors tu es obligé d'utiliser plusieurs variables consécutives.

    De là, soit tu utilises une boucle et un pointeur, ce qui t'oblige à déclarer des variables supplémentaires, soit tu gères manuellement chacun de tes registres en contrôlant à chaque fois s'il est concerné en fonction de la valeur de « count ». Tu gagnes quatre octets de RAM mais tu perds 64 octets de ROM. Ce genre de chose est effectivement à prendre en compte dans le cas de micro-contrôleurs, mais pas sur PC. Pas seulement parce que la quantité de RAM disponible est considérable, mais surtout parce que c'est la même dans les deux cas.

  • [^] # Re: compteur ?

    Posté par  . En réponse au journal Parlons C, parlons pipe !. Évalué à 1.

    C'est vrai, mais ça te permet en revanche de gérer une file d'une longueur arbitraire sans avoir à décaler tout son contenu. Avec 4 octets, la différence est subtile, avec 4096 elle devient beaucoup plus nette.

  • [^] # Re: Constante invalide

    Posté par  . En réponse au journal Parlons C, parlons pipe !. Évalué à 2.

    Oui, c'est parce que j'ai un raccourci trop rapide, en effet.

    Le principe demeure cela dit mais en fait, c'est déjà ce que tu fais à l'entrée. Tu décales à l'empilement et tu vas chercher la bonne position au dépilement. C'est effectivement l'un ou autre.

  • [^] # Re: ça marche !

    Posté par  . En réponse au journal Et Dieu inventa le soutien gorge !. Évalué à 2.

    Oui, mais mon compilateur fait du padding avant le premier membre pour arranger mon explication !

    Si tu as trouvé un compilateur qui accepte de faire du copinage, c'est très bien. :-)
    Mais autrement, d'une manière générale, la norme empêche les compilateurs de faire cela. Elle te garantit que le premier membre est bien aligné en début de structure et/ou d'union. Ça permet entre autres de faire des unions de structures commençant toutes par un champ « type », par exemple, qui permet de savoir tout de suite ce qu'il y a à l'intérieur, comme avec les XEvents de X-Window.

  • [^] # Re: compteur ?

    Posté par  . En réponse au journal Parlons C, parlons pipe !. Évalué à 4.

    Si.

  • # Constante invalide

    Posté par  . En réponse au journal Parlons C, parlons pipe !. Évalué à 10.

     if(f->count>0) return 0xEB; /* mes initiales \o/ */
    
    

    Moi, je lis « Enormous Boobs ». C'est sexiste ! Je te demande de changer de constante.

    unsigned char sf_pop(SmallFifo * f)
    {
         if(f==NULL) return 0x00;
         /* Pas tomber trop bas */
         if(f->count>0) f->count--;
         return (unsigned char)(f->data>>(8 * f->count)) & 0xFF;
    }
    
    

    Quand tu fais ceci, tu récupères l'octet situé à la position « count », mais tu n'effaces pas le contenu de « data », et tu ne tiens pas compte du fait non plus que ta file peut être vide (sauf pour la gestion de « count »). Ça veut dire d'une part que si tu continues à dépiler une file vide, tu vas obtenir à chaque fois la dernière valeur dépilée qui peut être non nulle.

    Puisque tu utilises déjà des opérateurs de décalage sur des registres du même format, pourquoi ne t'en sers-tu pas pour décaler directement le contenu de ta file ?

    data >>=8;
    return data & 0xff;
    
    
  • [^] # Re: Structure

    Posté par  . En réponse au message retourner un pointeur vers un tableau de pointeurs. Évalué à 4.

    Mouais, c'est un débat récurrent. Il y a même un flag à passer à GCC si on veut qu'il nous signale ce genre de choses. Pour autant, je trouve que c'est encore une des nombreuses mesures parties d'un bon sentiment et qui se sont avérées plus pénibles qu'autre chose à l'usage. Il ne faut pas oublier que le propre d'une fonction, en mathématiques, est d'être une expression évaluable et dont la valeur dépend du paramètre. Qu'on utilise les arguments en entrée et en sortie et qu'on utilise le code de retour que comme état du bon déroulement du processus, c'est un paradigme intéressant, certes, mais il s'agit alors de simples procédures, et plus de fonctions à proprement parler.

    Ça commence à devenir franchement lourdingue lorsque ce flag est imposé à la va-vite en entreprise et que ça t'empêche de faire un usage judicieux de tes structures. Le cas d'école que l'on brandit à chaque fois est celui des nombres complexes, bien sûr. Mais de façon similaire, et c'est intéressant parce que c'est un cas vécu, on pourrait parler des timestamps, par exemple.

    J'ai travaillé sur un filtre qui loguait certains événements sous forme d'objets datés avec une « struct timeval » utilisée entre autres par gettimeofday() et qui embarque un nombre de secondes et un nombre de micro-secondes. Au bout d'un moment, pour pouvoir les comparer facilement et traiter les échéances, j'ai fini par écrire une panoplie de fonctions pour pouvoir additionner, soustraire et comparer des durées, ainsi que quelques autres opérations.

    struct timeval timeadd (struct timeval, struct timeval); /* Additionne deux durées */
    struct timeval timesub (struct timeval, struct timeval); /* Soustrait deux durées  */
    int            timecmp (struct timeval, struct timeval); /* Compare deux durées    */
    
    

    ce qui me permettait d'écrire directement des trucs du style :

    if (timecmp(timesub(datefin,datedebut),dureemaximum)>0) action_approriee();
    
    

    Essaie de faire facilement la même chose avec des pointeurs. Tu te retrouves obligé de tout allouer toi-même et décomposer ton calcul. Ensuite, soit tu fais des malloc()/free() en gérant les erreurs éventuelles ce qui, même à l'exécution, est autrement plus long à traiter que huit octets passés dans la pile, soit tu déclares à l'avance des variables locales pour recevoir des résultats et là, dans un cas comme dans l'autre, les résultats se retrouveront dans la pile, avec la conséquence supplémentaire que tes variables auront une existence plus longue que les paramètres et la valeur de retour de chacune de ces fonctions.

    Alors autant je suis le premier à dire qu'il faut s'efforcer autant possible d'être sobre avec la pile (on voit beaucoup de débutants allouer des tableaux d'entiers de 2 Gio) et ne pas l'encombrer pour rien, autant je pense que dans ce genre de cas, aujourd'hui, on peut se permettre de passer des objets jusqu'à une centaine d'octets quand leur taille est fixe, qu'il faut en produire beaucoup et qu'ils sont éphémères.

  • [^] # Re: 0xB16B00B5

    Posté par  . En réponse au journal Et Dieu inventa le soutien gorge !. Évalué à 4.

    Je prends le risque : 0xb16b00b5

  • [^] # Re: Structure

    Posté par  . En réponse au message retourner un pointeur vers un tableau de pointeurs. Évalué à 10.

    Ce qu'il faut surtout savoir, c'est que le C est un langage très proche du fonctionnement réel du micro-processeur et, quand on connaît celui-ci, les caractéristiques et les limitations du C deviennent naturelles.

    Le micro-processeur est indépendant, en lui-même, de la machine dans laquelle il est installé et on peut ainsi retrouver le même CPU dans des ordinateurs très différents. Mais dans tous les cas, il ne communique avec l'environnement qu'avec un bus d'adresse, un bus de données et une ligne R/W (Read or Write). Les « bus » sont un ensemble de lignes électriques parallèles distribuées simultanément à tous les périphériques d'un ordinateur. Le bus d'adresse sert donc à coder un nombre binaire indiquant le numéro de l'octet en mémoire auquel on cherche à accéder, le bus de données à véhiculer la donnée, soit pour lire son contenu, soit pour écrire dedans et la ligne R/W à savoir justement laquelle des deux opérations on cherche à faire.

    Ça veut dire que la seule chose que voit le micro-processeur, c'est une longue plage continue d'octets, eux-mêmes numérotés de 00000000 à FFFFFFFF sur les architectures 32 bits. Ce plan mémoire est principalement occupé par des plages de RAM, quelques plages de ROM, quelques zones vides éventuellement (il y a quelques années, on aurait dit « pratiquement toujours » mais aujourd'hui, les machines équipées de 4 Gio de RAM au moins deviennent courantes) et quelques mini-plages réservées aux ports d'entrées-sorties servant à piloter les différents périphériques et composants de la machine. Ça veut dire également que la seule chose, en fin de compte, que sait faire un micro-processeur, c'est lire des données à un certain endroit, appliquer une opération logique ou arithmétique dessus, et la ré-écrire à un autre. Il est donc possible, en théorie, de piloter un ordinateur entier uniquement avec l'équivalent de « PEEK » et « POKE » en Basic.

    Donc, lorsque tu fais « x=1 » dans n'importe quel langage pour affecter la valeur « 1 » à la variable « x », en particulier avec un langage interprété, tu fais appel aux routines du logiciel que tu utilises qui, elles, vont aller déposer cette valeur quelque part en mémoire, dans une zone réputée décrire le contenu de la variable « x ». Le processus est généralement invisible au programmeur mais si tu te débrouilles pour savoir quel est l'adresse de cet emplacement, alors tu peux le modifier en écrivant dedans. Évidemment, c'est de la bidouille et tu fais ta manip' dans le dos du langage, mais c'est marrant de voir sa variable « muter » comme par magie.

    En C, en revanche, c'est totalement normal : on manipule directement les adresses mémoire sans utiliser de système sous-jacent, ne serait-ce que parce que le langage C sert justement à écrire ces systèmes. En fait, c'est pour cela qu'il a été conçu : compiler des programmes en un code autonome et restant au plus proche de la machine tout en s'affranchissant de l'assembleur et en écrivant donc des programmes en principe portables partout. Il faut aussi souligner que le C est apparu en 1972 et qu'à cette époque, les ressources systèmes étaient autrement plus limitées qu'elles le sont aujourd'hui.

    Maintenant, un pointeur est, comme son nom l'indique, quelque chose qui « pointe » une autre chose en mémoire, donc qui indique l'emplacement. Un pointeur est donc l'adresse mémoire de quelque chose et, par extension, la variable qui contient cette adresse. Un pointeur est donc une variable de type « adresse mémoire » et a généralement la largeur du bus d'adresse, donc quatre octets sur une machine 32 bits. En ce sens, un pointeur est donc en fait un entier non signé mais, sémantiquement parlant, il a été décidé d'en faire un type à part entière. D'abord pour informer le compilateur de ce dont il s'agit, ensuite parce que le format minimum des entiers imposé par la norme C ne correspond pas forcément avec celui du bus d'adresse de la machine cible, et enfin parce qu'il existe une arithmétique propre aux pointeurs, alors qu'en revanche, toutes les opérations applicables aux entiers numériques n'ont pas forcément de sens avec un pointeur, par exemple, le multiplier. Pas plus qu'additionner deux pointeurs d'ailleurs : ce n'est pas parce que toi, tu habites au № 5 et un de tes amis au № 8 qu'à vous deux, vous habitez au № 13. :-)

    Si j'utilise « & », je peux connaître l'emplacement en mémoire de mes variables et du code de mes fonctions (plus précisément, leur point d'entrée). Par exemple, en écrivant ceci :

    #include <stdio.h>
    
    int main (void)
    {
        int x;
        int y;
    
        printf ("Emplacement de x : %p\n",&x);
        printf ("Emplacement de y : %p\n",&y);
    
        return 0;
    }
    
    

    … j'obtiens :

    Emplacement de x : 0x7fff93cc99dc
    Emplacement de y : 0x7fff93cc99d8
    
    

    On voit donc clairement où mes variables sont matérialisées, et on voit également que « x » se trouve quatre octets après « y » parce mes entiers tiennent sur 32 bits eux aussi.

    Par contre, le seul service que te garantit un pointeur est conserver une adresse mémoire, à laquelle est censé se trouver un objet de type connu. Mais il n'y a aucune garantie que cette adresse soit valide si tu ne l'as pas initialisé correctement. Par exemple, dans l'exemple précédent, si j'affecte à mon pointeur l'adresse de « y » et que je me débrouille pour le faire avancer d'exactement deux octets, je vais me retrouver « à cheval » entre deux variables.

    #include <stdio.h>
    
    int main (void)
    {
        int x = 0;
        int y = 0;
        unsigned int * ptr = NULL;
    
        printf ("Avant : x=%d ; y=%d\n",x,y);
        ptr = (unsigned int *)(((char *)&y)+2);
        *ptr = 0xffffffff;
        printf ("Après : x=%d ; y=%d\n",x,y);
    
        printf ("%p %p %p\n",&x,&y,ptr);
    
        return 0;
    }
    
    

    … ce qui donne :

    Avant : x=0 ; y=0
    Après : x=65535 ; y=-65536
    0x7fff720800b4 0x7fff720800b0 0x7fff720800b2
    
    

    On voit que les deux variables sont affectés. Le C me laisse le faire. Il me laisse même écrire n'importe où en mémoire si j'en ai envie, écrasant éventuellement les autres programmes ou le système d'exploitation, comme on pourrait le faire en assembleur. Heureusement, le mode protégé est désormais sur toutes les machines et c'est le micro-processeur lui-même qui refusera de continuer si on lui demande de lire ou d'écrire dans une zone non explicitement déclarée par ton O.S., déclenchant la célibrissime « segfault ».

  • [^] # Re: Merci!

    Posté par  . En réponse au message retourner un pointeur vers un tableau de pointeurs. Évalué à 4.

    C'est souvent le cas ! :-) Un problème bien compris et/ou bien exposé est à moitié résolu.

    Bonne chance pour la suite.