Home > Software engineering >  C - Redirecting awk/sed stdout to pipe doesn't work
C - Redirecting awk/sed stdout to pipe doesn't work

Time:06-03

So I have an exercise to do, and one part of this exercise requires us to execute a command passed as an argument, be able to pass it some strings on stdin, and get its output on stdout and stderr. How I did it, I need to redirect the stdout and stderr (of the child, which is gonna call an exec) to a couple of pipes (other end of the pipes is held open by the parent). I managed to do it, when I ask it to execute bash and send it "ls", it gives me what i want, where i want it. Same with cat and others. Problem is, when I try executing awk or sed, nothing is ever written on the pipe. Ever. If i leave stdout untouched, it does print it how it should. But as soon as i redirect the stdout, nothing. I tried everything, select(), wait(), sleep() (even though it's not allowed). Nothing seems to work.

I made a minimum working example of what i mean (clearly, it lacks of conventions and mindful writing, as free() and close(), but it does it's job) which Is the one I'm attaching. The code works when i call it like this: ./program $(which bash) It prompts for something, i write "ls" and it gives me the result expected but when i try ./program $(which awk) '{print $0;}' I get nothing at all

Here's the code (minimum working example):

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>

int main(int argc, char* argv[]){
    int fdStdinP[2],fdStdoutP[2];
    char *string,*array[3];
    array[0]=argv[1];
    array[1]=argv[2];
    array[2]=0;
    pipe(fdStdinP);
    pipe(fdStdoutP);
    int pid=fork();
    if(pid==0){
        close(fdStdinP[1]);
        close(fdStdoutP[0]);
        dup2(fdStdinP[0],0);
        close(fdStdinP[0]);
        dup2(fdStdoutP[1],1);
        close(fdStdoutP[1]);
        //as suggested, the file descriptors are now closed
        execvp(argv[1],array);
        perror("");
        return 0;
    }
    close(fdStdinP[0]);
    close(fdStdoutP[1];
    string=calloc(1024,sizeof(char));
    read(0,string,1024);
    write(fdStdinP[1],string,1024);
    free(string);
    string=calloc(1024,sizeof(char));
    read(fdStdoutP[0],string,1024);
    printf("I have read:%s",string);
    return 0;
}

Thank you for your time.

CodePudding user response:

Awk continues to wait for input and buffers its output, so appears to hang. Closing the sending end will tell awk that it's input has ended so that it will end and flush its output.

write(fdStdinP[1],string,1024);
close(fdStdinP[1]);    // just added this line.
  • Related