Reputation: 11444
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
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