Jjang
Jjang

Reputation: 11444

Executing a program in C

At some point of my program, I'd like to run another program (which is getting parameters from stdin), with paramaters I have prepared in a text file. Then, I'd like to write the program's output into another file.

I'm new to linux, fork, and such. Tried breaking my head for HOURS without success. I read that I should associate my input file with stdin and output file with stdout, something like that.

This is the code I wrote:

//move on all sub-directories .....
while((indir=readdir(dir))!=NULL)
{
    pid_t pid;
    DIR *currDir;
    struct dirent *cfile;
    char *fullpath, *outpath, *outputpath;

    //ignore hidden files
    if(indir->d_name[0]=='.')
        continue;

    //create the full path of c file
    fullpath=(char*)calloc(strlen(dirpath)+strlen(indir->d_name)+1,sizeof(char));
    strcpy(fullpath,dirpath);
    fullpath=strcat(fullpath,indir->d_name);
    fullpath=strcat(fullpath,"/");
    //open current directory
    currDir=opendir(fullpath);
    //get the c file, ignore hidden files
    while((cfile=readdir(currDir))!=NULL)
    {
        if(cfile->d_name[0]!='.')
            break;
    }
    /*compile c file*/

    //child process
    if((pid=fork())==0)
    {
        fullpath=realloc(fullpath, sizeof(char)*(strlen(fullpath)+strlen(cfile->d_name)+1));
        outpath=(char*)calloc(strlen(fullpath)+strlen(OUT_NAME)+1,sizeof(char));
        strcpy(outpath,fullpath);
        strcat(fullpath,cfile->d_name);
        strcat(outpath,OUT_NAME);
        execl("/usr/bin/gcc", "/usr/bin/gcc", "-o", outpath, fullpath,NULL);
    }
    else
    {
        wait(NULL);
    }


    //create output file path
    outputpath=calloc(strlen(fullpath)+strlen(OUTPUTFILE_NAME)+1,sizeof(char));
    strcpy(outputpath,fullpath);
    strcat(outputpath,OUTPUTFILE_NAME);

    inputpath=(char*)calloc(strlen(buff)+1,sizeof(char));
    //get input file path from buffer
    for(j=0,buffIndex++;buff[buffIndex]!='\n';buffIndex++,j++)
    {
        inputpath[j]=buff[buffIndex];
    }

////Untill here works perfectly////
    //child process
    if((pid=fork())==0)
    {
        fullpath=realloc(fullpath, sizeof(char)*(strlen(fullpath)+strlen(OUT_NAME)+1));
        strcat(fullpath, OUT_NAME);
        //re-open input file and associate it with stdin
        freopen(inputpath, "r", stdin);
        //re-open output file and associate it with stdout
        freopen(outputpath, "w", stdout);
        execl(fullpath,inputpath, NULL);
    }
    else
    {
        wait(NULL);
    }

}

*inputpath is the full path of the file I prepared with inputs for the program.

*outputpath is the full path of a file where I want to save the program's output.

I'm definitely doing something wrong, since I get the following error:

/home/aviad/workspace/test/dean/input.txt~: file not recognized: File truncated
collect2: error: ld returned 1 exit status
/home/aviad/workspace/test/jjang/fileoutput.txt: file not recognized: File truncated
collect2: error: ld returned 1 exit status

Any help?

Upvotes: 0

Views: 306

Answers (1)

FatalError
FatalError

Reputation: 54551

There's not enough information in your post to confirm, but I suspect you are being bitten by choosing the same name as a build tool, e.g. ld, for your program's name. If you do so and run

ld 1.txt 2.txt

there's a very good chance you are not executing your ld, but rather the GNU linker or similar (/usr/bin/ld). Normally system directories are searched before ., if . is in PATH at all. This avoids some unpleasant surprises like if you had run ls in a directory with a binary named ls in it, you probably still wanted /bin/ls.

This is why it's a good idea to run things in your cwd prefixed with ./, so instead you'd say:

./ld 1.txt 2.txt

and the system ld would not longer be a candidate. You can determine which one will run by using which ld and which ./ld.

So, in reality you are not running your program at all. This has bitten a few people I've known, including myself. My first unix program was named "test" ;).

EDIT: based on the output, the name cc might be a better candidate than ld, but same idea.

EDIT:

Based on your update, it seems you are calling gcc after all, and by reading directory contents. There doesn't appear to be any check that the file you're compiling is even a .c file, are you sure that you're not calling this code in the directories where these text files live?

Upvotes: 2

Related Questions