1

First of all, I want to redirect the output of ls (exec) in a file and then from a file to pipe, why is not working? It's ok when I redirect in a file, but that's all.

How can I do to find the length of the output of ls? (that's why I did a redirect to a file).

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>

int main()
{
    char input[]="ls",ch, delim[]=" ",*result,aux[2000],*user=NULL,*password=NULL,aux1[2000],aux2[2000],aux3[2000],aux4[2000],*arg[1000];
    int p1[2],p2[2],i,j,len,nrRead,ok,log,f;
    pid_t pid,pidd;
    pid=fork(); f=open("alice.txt",O_RDWR|O_TRUNC|O_CREAT,0700);

    if(pid == 0){
        i=0; 
        printf("f: %d",f);
        if(strlen(input) == 2) {arg[0]="ls";arg[1]=NULL; i=2;}
        else 
        {       
            result=strtok(input,delim);
            arg[i++]=result;
            result=strtok(NULL,delim);
            while(result!= NULL)
            {
                printf("LS --- 5\n");
                arg[i++]=result;
                result=strtok(NULL,delim);
            }
            arg[i]=NULL;
        }

        close (1);

        if (dup2(f,1) == -1)    
        {
            fprintf (stderr, "dup - 1\n");
            exit (9);
        }

        if( 0 == (pidd=fork())) { 
            execvp("ls",arg);
        }

        close(f);
        i=0;
        while(0 != read(1,&ch,sizeof(char)))
        { 
            aux4[i]=ch;
            i++;
        }
        aux4[i]='\0';

        close(1);
        if (dup2(p2[1],1) == -1)    
        {
            fprintf (stderr, "dup - 1\n");
            exit (9);
        }
        //close(p2[1]);
        len=strlen(aux4);
        //printf("LUNG: %d",len);
        write(1,&len, sizeof(4));       
        return 0;
    } else {
        wait(NULL);
        close(p2[1]);
        read(p2[0],&len,sizeof(int));
        printf("pp: %d",len);

    }
}
Yefim Dinitz
  • 414
  • 3
  • 9

1 Answers1

0

Instead of forking and duping yourself you can conveniently use popen to do what you want. If you really need to know the size of the output beforehand, you don't need to redirect to a file, you can simply count the bytes you can read from the pipe before you hit EOF. Example (no error checking):

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fd;
    char *buf;
    size_t size; /* counter for output size */

    fd = popen("ls", "r"); /* open a pipe running ls for reading ("r") */

    size = 0;
    while (fgetc(fd) != EOF) {
        size++;
    }

    pclose(fd);

    printf("Output is %d bytes\n", size);

    fd = popen("ls", "r");

    buf = malloc(size+1);

    while (fgets(buf, size, fd)) {
        fputs(buf, stdout); /* do what you want here */
    }

    pclose(fd);

    return 0;
}

Note that if you intend to parse the ls output later to find files or directories, you are much better off using the opendir, readdir and closedir functions on Unix.

Yefim Dinitz
  • 414
  • 3
  • 9
  • Thanks for the answer. Actually I need to use fork si exec to my homework, but this idea is ok, too. :) – user1764981 Oct 22 '12 at 16:28
  • well, if `exec` was a requirement, then this solution does not help, obviously. I was just pointing out how I would solve this problem "in production" - actually using exec makes sense for homework or the like, but I wouldn't use here it if I don't have to. – Yefim Dinitz Nov 05 '12 at 08:14