Journal C

Posté par  (site Web personnel) .
Étiquettes : aucune
0
16
avr.
2004
je note ça dans un coin.


close(STDOUT_FILENO);
dup2(p[1]);
close(p[1]);

write(STDOUT_FILENO,"prout", 5);
printf("plop");

ca donne pas la même chose... pourquoi?
  • # Re: C

    Posté par  . Évalué à 3.

    c'est quoi la variable p[1] ?
    quel est l'efficacité de dup2(p[1]) si tu n'en récupère pas le retour ?
    qu'est ce que tu t'attends à avoir ?
    qu'est ce que tu as ?

    Franchement, t'as pas trouvé plus obscur comme question ?
    • [^] # Re: C

      Posté par  (site Web personnel) . Évalué à 2.

      c'est quoi la difference entre Debian ?
      • [^] # Re: C

        Posté par  . Évalué à 2.

        Aucune, surtout la sid.
      • [^] # Re: C

        Posté par  . Évalué à 1.

        et avec un pigeon ?
        • [^] # Re: C

          Posté par  . Évalué à 1.

          l'une de ses pattes se ressemble.
          • [^] # Re: C

            Posté par  (site Web personnel) . Évalué à 1.

            ah moi je croyais que c'était le fait qu'il est 2 pattes de la même longueur, surtout la gauche...
        • [^] # Re: C

          Posté par  . Évalué à 1.

          Quel âge avait Rimbaud ?
    • [^] # Re: C

      Posté par  (site Web personnel) . Évalué à 1.

      42?

      le but c'est de faire un fork, dans le fils faire un execv et envoyer le stdout de ce exec dans un tube relié au papa.

      1)p c'est un pipe.
      2) j'ai pas mis tous le code
      3) un comportement identique entre write(STDOUT_FILENO, ...) et printf(...)
      4) pas la meme chose. le write(STDOUT_FILENO,...) écrit bien dans le tube et le papa le lit correctement. Le printf se perd dans l'espace.

      plop
  • # Re: C

    Posté par  (site Web personnel) . Évalué à 1.

    Voici un bout de code qui compile et qui montre le probleme (enfin, je suis pas sûr)
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    int main(void)
    {
    int p;

    p = open("plouf", O_CREAT | O_WRONLY | O_TRUNC);
    close(STDOUT_FILENO); /* inutile, dup2 est sensé faire un close() anyway */
    dup2(p, STDOUT_FILENO);
    close(p);
    write(STDOUT_FILENO, "prout\n", 6); /* marche */
    printf("prout2\n"); /* marche pas */
    close(STDOUT_FILENO); /* amusant :
    si on commente cette ligne, le printf
    fonctionne. */

    return 0;
    }
    • [^] # Re: C

      Posté par  (site Web personnel) . Évalué à 1.

      Je pense qu'un fflush(1) avant le close() final résoudra ton problème, et cela bien sûr si j'ai compris ton problème...
      • [^] # Re: C

        Posté par  . Évalué à 1.

        setbuf ( stdout, NULL ); doit aussi marcher
    • [^] # Re: C

      Posté par  . Évalué à 1.

      Le fait de fermer les stdin stderr ou stdout peut être vu comme une faille de sécu, il est possible qu'il y ait des protections la dessus.

      "La première sécurité est la liberté"

    • [^] # Re: C

      Posté par  . Évalué à 1.

      printf("prout2\n"); /* marche pas */
      close(STDOUT_FILENO); /* amusant :


      le strace donne :
      close(1) = 0
      write(1, "prout2\n", 7) = -1 EBADF (Bad file descriptor)

      c'est marrant (l'assembleur est bon) et si on met un sleep apres le printf, ca change rien (l'attente se fait avant le close)

      Par contre chez moi le prout est ecrit dans le fichier plouf....

      PS le strace complet

      execve("./a.out", ["./a.out"], [/* 30 vars */]) = 0
      uname({sys="Linux", node="mat-pc", ...}) = 0
      brk(0) = 0x804a000
      old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40017000
      access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
      open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory)
      open("/etc/ld.so.cache", O_RDONLY) = 3
      fstat64(3, {st_mode=S_IFREG|0644, st_size=46963, ...}) = 0
      old_mmap(NULL, 46963, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40018000
      close(3) = 0
      access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
      open("/lib/tls/libc.so.6", O_RDONLY) = 3
      read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240X\1"..., 512) = 512
      fstat64(3, {st_mode=S_IFREG|0644, st_size=1271388, ...}) = 0
      old_mmap(NULL, 1281772, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40024000
      old_mmap(0x40152000, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x12d000) = 0x40152000
      old_mmap(0x4015b000, 7916, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4015b000
      close(3) = 0
      old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4015d000
      set_thread_area({entry_number:-1 -> 6, base_addr:0x4015d2a0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
      munmap(0x40018000, 46963) = 0
      open("plouf", O_WRONLY|O_CREAT|O_TRUNC, 010000713231) = 3
      close(1) = 0
      dup2(3, 1) = 1
      close(3) = 0
      write(1, "prout\n", 6) = 6
      fstat64(1, {st_mode=S_IFREG|S_ISVTX|0611, st_size=6, ...}) = 0
      mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40018000
      close(1) = 0
      write(1, "prout2\n", 7) = -1 EBADF (Bad file descriptor)
      munmap(0x40018000, 4096) = 0
      exit_group(0)
      • [^] # Re: C

        Posté par  . Évalué à 1.

        Par contre chez moi le prout est ecrit dans le fichier plouf....
        j'ai rien dis

        Comme dis plus haut, printf (ou quelque chose d'autre) doit voir qu'on ecrit dans un fichier, et le met en cache.
        Mais comme on ferme indirectement le fichier, ça chie...
        • [^] # Re: C

          Posté par  . Évalué à 1.

          utiliser printf, fopn, strcpy ... en C c'est une hérésie !!
  • # Re: C

    Posté par  (site Web personnel) . Évalué à 1.

    ok effectivement, faire un fflush après le printf règle le problème. Dans ce cas, comment je peux faire pour que mon execlp donc le stdout est relié à mon tube écrive dedans =) Je vais voir du coté de fcntl, mais bon =)
    • [^] # Re: C

      Posté par  (site Web personnel) . Évalué à 1.

      s/donc/dont
    • [^] # Re: C

      Posté par  (site Web personnel) . Évalué à 1.

      Voici un truc que j'avais écris pour controller l'entrée standard d'un programme (nommé apt, mais rien avoir avec deb) et récupérer ce qui en sortait.
      ----
      int childPid;
      int pipefdin[2],pipefdout[2];

      /* Pipes init */
      if( pipe(pipefdin) == -1 || pipe(pipefdout) == -1 ){
      perror("Creating apt communication pipes");
      exit(1);
      }

      childPid = fork();

      if( !childPid ){

      // son, so we launch apt and we connect
      // its standards channels to pipes

      // close unused channels
      close(pipefdin[1]);
      close(pipefdout[0]);

      // Duplicate stdin to our pipe
      close(STDIN);
      if( dup(pipefdin[0]) == -1 ){
      perror("duplicating apt stdin");
      exit(1);
      }

      // Duplicate stdout to our pipe
      close(STDOUT);
      if( dup(pipefdout[1]) == -1 ){
      perror("duplicating apt stdout");
      exit(1);
      }

      // Duplicate stderr to the same pipe as stdout
      close(STDERR);
      if( dup(pipefdout[1]) == -1 ){
      perror("duplicating apt stderr");
      exit(1);
      }

      // Launch apt
      if( execl(apt_path,apt_path,NULL) == -1 ){
      perror("can't find apt");
      exit(1);
      }

      }else{

      // father, this process, continues execution

      // Close unusable channels
      close(pipefdin[0]);
      close(pipefdout[1]);

      // Return the right values to control the apt
      *aptin_k = pipefdin[1];
      *aptout_k = pipefdout[0];

      }
      ----
      aptin_k doit être le fd pour écrire sur la stdin du prog que tu veux controller, et aptou_k doit être là où tu lis pour récupérer sa stdout...
      En espérant te filer un coup de main...
      • [^] # Re: C

        Posté par  (site Web personnel) . Évalué à 1.

        ca marche....quand l'appli dansle fork quitte (genre ls ou autre).
        moi ca marche plus comme un truc qu'on interroge. je le lance, et il attend sur stdin, je lui donne des trucs, ensuite il repond sur stdout, je l'interoge sur in...etc :)
        • [^] # Re: C

          Posté par  (site Web personnel) . Évalué à 1.

          J'ai utilisé ce code pour faire exactement ce que tu dis, et ca marchait parfaitement...
          • [^] # Re: C

            Posté par  (site Web personnel) . Évalué à 1.

            ben alors je sais pas pkoi, mais ça marche pas trop ici =)
            Je retoucherais au code plus tard... j'ai peut etre bouletisé, mais j'ai vraiment épuré tout ce qui trainait autour (GTK & cie)

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.