0

I'm doing a program that will receive 3 arguments, ./a.out a b c, where a and c are column numbers and b and operand from lines separated by :.

When its true reproduces the stdin else no results.

examples:

$ ./a.out 1 > 2
$ 5:2:1:6
5:2:1:6

$ ./a.out 2 = 4
$ 1:2:3:4
$

I've tried in my first version, doint the pipe and reading from the stdin when the cut asks for it, but my problem is that i lose the input.

Now i'm trying to read from the stdin inside the child, store and pass it thru a pipe, but for my testing i'm guessing the execlp is not getting the stdin input.

I can't use awk, its for a academic work.

my code at this moment:

int main(int argc, char const *argv[]){

    int n,f;
    char coluna1[16];
    char coluna2[16];
    char strin[PIPE_BUF];
    //put together args cut
    char buffer[PIPE_BUF];
    sprintf(buffer, "-f%s,%s",argv[1],argv[3]);

    //pipes
    int fd[2];
    int fd2[2];
    pipe(fd);
    pipe(fd2);

    if(!fork()) {
        close(fd[0]); //close read
        dup2(fd[1],1); //std output duplicated to pipe write
        close(fd2[0]); //close read
        //readline stdin
        n = read(0,strin,PIPE_BUF);
        write(fd2[1],strin,n);
        //cut -d: -f2,4 -
        execlp("cut","cut","-d:",buffer,"-",NULL);
    }
    //pai recebe do pipe
    close(fd[1]); //close write
    close(fd2[1]); //close write
    n = read(fd2[0],strin,PIPE_BUF); //read stdin from pipe
    f = read(fd[0],buffer,PIPE_BUF); //stdout from cut
    sscanf(buffer,"%[^:]:%s",coluna1,coluna2);

    //write the result from the cut to "bug check"
    write(1,buffer,f);

    //printfs just to check if everything worked
    if(strcmp(argv[2],"=")) if(atoi(coluna1) == atoi(coluna2)) { write(1,strin,n); printf("ACERTEI NO =\n"); }
    if(strcmp(argv[2],">=")) if(atoi(coluna1) >= atoi(coluna2)) { write(1,strin,n); printf("ACERTEI NO >=\n"); }
    if(strcmp(argv[2],"<=")) if(atoi(coluna1) <= atoi(coluna2)) { write(1,strin,n); printf("ACERTEI NO <=\n"); }
    if(strcmp(argv[2],">")) if(atoi(coluna1) > atoi(coluna2)) { write(1,strin,n); printf("ACERTEI NO >\n"); }
    if(strcmp(argv[2],"<")) if(atoi(coluna1) < atoi(coluna2)) { write(1,strin,n); printf("ACERTEI NO <\n"); }
    if(strcmp(argv[2],"!=")) if(atoi(coluna1) != atoi(coluna2)) { write(1,strin,n); printf("ACERTEI NO !=\n"); }

}
  • One issue that I can see is that in many shells the '>' and '=' characters have special meaning. It's also a little ugly to be using literals for fds. I prefer macros to clarify that. – Gold Dragon May 06 '17 at 23:07
  • when i try on the shell i use ">" to avoid rederection problems. Macros mean like STDIN and such ? – José Moreira May 07 '17 at 10:57
  • Macros I'm talking about are STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. And yes, quoting or escaping the sign should fix that kind of problem. – Gold Dragon May 08 '17 at 12:22

1 Answers1

0

Fixed it like this:

if(!fork()) {
    close(fd[0]); //close read
    dup2(fd[1],1); //std output duplicated to pipe write
    close(fd2[1]); //close write
    dup2(fd2[0],0); //std input from father duplicated to pipe read
    //cut -d: -f2,4 -
    execlp("cut","cut","-d:",buffer,"-",NULL);
}
//father
close(fd[1]); //close write
close(fd2[0]); //close read
n = read(0,strin,PIPE_BUF);
write(fd2[1],strin,n);
close(fd2[1]);
//n = read(fd2[0],strin,PIPE_BUF); //read stdin from pipe
f = read(fd[0],buffer,PIPE_BUF); //stdout from cut