简体   繁体   中英

Usage of pipes and dup2 in C

I have this code

int main() {
    int fd[2];
    pipe(fd);
    dup2(fd[1], 1); close(fd[1]);

    printf("I wanna print this.");

    char * buf = malloc(100);
    read(fd[0], buf, 50);

    fprintf(stderr, ">>>%s<<<\n", buf);

    close(fd[0]);
}

Expected output: print >>>I wanna print this.<<< on stderr

How can I make this work?

The main problem is that the line you printed got buffered, so it didn't actually get sent to the pipe. Either do fflush(stdout); somewhere between your printf and read to flush the buffer, or disable buffering of stdout with setbuf or setvbuf at the very beginning of your program.

A secondary problem is that you're mixing up counted and null-terminated strings, as Jonathan Leffler alluded to in the comments.

This code produces the desired answer. It uses the suggestions I made in my comment .

/* SO 7493-6183 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    int fd[2];
    pipe(fd);
    dup2(fd[1], 1);
    close(fd[1]);

    printf("I wanna print this.");
    fflush(stdout);

    char *buf = malloc(50);
    int n = read(fd[0], buf, 50);

    fprintf(stderr, ">>>%.*s<<<\n", n, buf);
    close(fd[0]);
    free(buf);
    return 0;
}

Output:

>>>I wanna print this.<<<

Alternatively, you could use:

    buf[n] = '\0';
    fprintf(stderr, ">>>%s<<<\n", buf);

This null-terminates the string before printing it. The key parts of the exercise are fflush(stdout) and capturing the length from read() and using that to limit the output of the fprintf() statement.

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