I want to create a c program that executes commands in a txt file. I read each value of my txt file and put them in an array and then I want to run them one by one using a fork function. Thank you for your help
I hope a charitable help to tell me where the problem is. I enclose a part of my code and my data file.
void Execfile(char*filename)
{
char**T;
int nb;
FILE*f;
char buff[MAX_ARG];
f=fopen("data1.txt","rb");
while(fgets(buff,MAX_ARG,f)!=NULL){
T=File2TabArgv(filename,&nb);
}
fclose(f);
execvp(T[0],T);
printf("\n");
printf("END");
}
in txt.file```
sleep20
CodePudding user response:
The problem is that execvp
replaces the current process (see the linked man
page). At minimum, you want to fork
into a new process, prior to calling execvp
, and in the parent process, you will want to wait
for the newly forked child process. You might want to do other things, like close the child's file handles inherited from the parent, and so on.
Without forking, the first "command" in your text file replaces you own execution. Without waiting, you won't know what's going on. This is sort of the basic flow of running executables from POSIX C.
Here is a pretty standard idiom for doing fork
/exec
, since it's helpful to see actual code:
int do_fork_exec(void) {
/* Just something to exec... */
static char const exec_cmd[] = "ls";
static char const *exec_args[] = { [0] = "-l", [1] = NULL, };
pid_t const fork_result = fork();
switch (fork_result) {
case -1: {
int const fork_errno = errno; /* Save it before it changes. */
fprintf(stderr, "Could not fork a new process: %s\n",
strerror(fork_errno));
return fork_errno;
}
case 0: {
printf("Child process executing: %s...\n", exec_cmd);
int const exec_result = execvp(exec_cmd, (char **)exec_args);
assert(exec_result == -1); /* Exec only returns on ERRORS. */
int const exec_errno = errno;
fprintf(stderr, "Could not excecute the process: %s\n",
strerror(exec_errno));
return exec_errno;
}
default: {
printf("Forking process waiting for PID %d\n", fork_result);
int child_result = -1;
pid_t const wait_result = wait(&child_result);
if (wait_result == -1) {
int const fork_errno = errno; /* Save it before it changes. */
fprintf(stderr, "Could not wait for PID %d: %s\n",
fork_result, strerror(fork_errno));
return fork_errno;
}
/* Wait waits on the entire process group, and we only forked one
* process, so I am asserting that what we forked is what we waited
* for... */
assert(fork_result == wait_result);
printf("Child process with PID %d exited with a status of %d\n",
fork_result, child_result);
break;
}
}
return 0; /* Return 0 on success. */
}
CodePudding user response:
You should do a fork like this
int status;
my_pid = fork();
if (my_pid >= 0) {
if (my_pid == 0) { /*child*/
execvp(...);
printf("failed\n");
exit(1);
} else { /*parent*/
wait(&status);
printf("child exit code: %d\n", WEXITSTATUS(status));
}
} else {
perror("fork failed");
exit(1);
}