I have been using execvp to execute unix commands written in a text file. Below is the code i have written but it doesn't seem to work.
I am reading lines from a file and each line contains a unix command(mv,cp etc).
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include <unistd.h>
int main ( int argc, char *argv[] )
{ pid_t pid;
pid_t child_pid;
int child_status;
char *token;
FILE *fp;
fp = fopen(argv[1],"r");
int i,j,ctr,rc_wait;
if( fp == NULL){
perror("An error has occurred\n");
exit(1);
}
char buff[100];
while(fgets(buff, sizeof(buff), fp)){
child_pid=fork();
if(child_pid<0){
printf("\nfork failed, error");
exit(0);
}
else if(child_pid==0){
//printf("\nString value = %s", buff);
token = strtok(buff, " \t");
execvp(token,buff);
}
else{
rc_wait = wait(NULL);
continue;
}
}
}
return 0;
}
input file has been provided as an argument to the program and the input contains below as example:
cp temp1/f1.txt temp2/
mv temp1/f2.c temp2/
cp temp1/f3.txt temp2/
cp temp1/f4.txt temp2/
cp temp1/f5.txt temp2/
cp temp1/f6.txt temp2/
mv temp1/f7.c temp1/f8.c
mv temp1/f9.c temp2/
cp temp1/f1.txt temp1/f1a.txt
You're misusing strtok
and execvp
. The former mutates the input string as you call it, so after it has run once, it's split up buff
by a NUL
(token
and buff
actually refer to the same address after the first call, though token
would change after additional tokenization). You can only use strtok
to fully parse the input if you make copies of each result as it's generated (e.g. via strdup
if you can rely on modern POSIX standards), because only the most recently returned pointer is ever valid.
Your execvp
usage is also wrong; the second argument to execvp
is an array of C-style strings, char*
s (the array itself being terminated with a NULL
pointer). You passed it a plain array of char
(one string, not an array of them).
Please read the man
pages for both APIs; you're so far off the mark it's clear you're just guessing at how they work.