简体   繁体   中英

linux C sending data from child to parent is fine, but fail to send data from child to parent

I would like to fork a child and connect pipes to the stdin and stdout of child. And then run the exec ./xx. After that I send 17 from parent to child and child print it. all good so far. but when I send a 17 return to parent it doesnt work. The result is : output nothing and look like wait for some input. if I remove the code "fscanf(b, "%d", &x); " in parent, the output is: from C 0 from p 17 I pretty confuse why I get the odd result?? Thank you

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>

int main(int argc, char** argv) {
    int fds[2], cp[2], x = 0;
    pipe(fds); 
    pipe(cp);
    int pid=fork();

// c
if (pid==0) {               
    close(fds[1]);
    close(cp[0]);
    dup2(fds[0],0);
    dup2(cp[1], 1);
    close(cp[1]);
    close(fds[0]);      
    execlp("./xx", "xx", 0);            
}
// p
if (pid) {      

    close(fds[0]);
    close(cp[1]);
    dup2(fds[1],1);
    close(fds[1]);
    FILE* a=fdopen(1, "w");
    FILE* b=fdopen(cp[0], "r");
    fprintf(a, "17");       
    fscanf(b, "%d", &x); 
    fprintf(stderr, "from C %d", x);
    }

    return 0;
}

XX

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
int main() {
    int y = 0;
    FILE* r=fdopen(STDIN_FILENO, "r");
    fscanf(r, "%d", &y);
    fprintf(stderr, "from p %d \n ", y);
    FILE* w=fdopen(STDOUT_FILENO, "w");
    fprintf(w, "17");
    return 0;
}

I think I figured it out. You need to flush your output buffers. fprintf only does this by default for stderr. So in the parent.c file:

fprintf(a, "17");
fflush(a);

And in the child:

fprintf(w, "17");
fflush(w);

I would have expected that to work on its own, but I'm not a C expert, and it didn't. However, changing the two lines in the parent to

fprintf(a, "17\n");
fflush(a);

made it work for me.

Use this code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>

int main(int argc, char** argv) {
    int fds[2], cp[2], x = 0;
    pipe(fds); 
    pipe(cp);
    int pid = fork();

if (pid==0) {               
    close(fds[1]);
    close(cp[0]);
    dup2(fds[0], 0);
    dup2(cp[1], 1);    
    execlp("./xx", "xx", NULL);       
}
if (pid > 0) {      

    close(fds[0]);
    close(cp[1]);
    FILE * a = fdopen(fds[1], "w");
    FILE * b = fdopen(cp[0], "r");
    fprintf(a, "17\n");
    fflush(a);
    fscanf(b, "%d", &x); 
    fprintf(stderr, "from C %d\n", x);
} else {
    // error while fork
    perror("fork"); // print error to console.
    return 1;
}

    return 0;
}

And xx:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
int main() {
    int y = 0;
    FILE* r = stdin;
    fscanf(r, "%d", &y);
    fprintf(stderr, "from p %d \n ", y);
    FILE* w = stdout;
    fprintf(w, "17\n");
    fflush(w);
    return 0;
}

It's working for me :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM