Reputation: 571
I'm trying to understand the error returned by execl when it is trying to launch a file that doesn't exist.
Here is my code for this experiment, where main calls the function spawn1 that will create the fork and try to launch execl:
# include <stdio.h>
# include <assert.h>
# include <sys/types.h>
# include <sys/wait.h>
# include <unistd.h>
# include <stdlib.h>
int spawn1(char *, char *, char *);
int main(){
int i, t, tt, state;
for(i = 0; i < 10; i++){
t = spawn1("functiondoesntexist", "strange name", "argument");
if (t < 0){
perror("fork"); // fork error
break;
}
tt = wait(&state);
assert(tt == t);
if (state != 0){
perror("exec didn't work");
break;
}
}
return i != 10;
}
int spawn1(char * file, char * command, char * arg){
int t;
t = fork();
if (t < 0) // fork error
return -1;
if (t == 0){ // child
execl(file, command, arg, (void *)0);
exit(1);
}
// parent
return t;
}
the error returned is:
exec didn't work: File exists
Why isn't it more something like "File DOESN'T exist"?
Upvotes: 0
Views: 636
Reputation: 223872
You're not calling perror
in the correct places.
When a function fails, you need to check errno
or call perror
immediately after the function that failed. Any other system or library function that is called after the one that failed will overwrite errno
with its own error code.
Change you code to call perror
right away as follows:
int main(){
int i, t, tt, state;
for(i = 0; i < 10; i++){
t = spawn1("functiondoesntexist", "strange name", "argument");
if (t < 0){
fprintf(stderr, "fork failed\n"); // not perror
break;
}
tt = wait(&state);
assert(tt == t);
if (state != 0){
fprintf(stderr, "exec didn't work\n"); // not perror
break;
}
}
return i != 10;
}
int spawn1(char * file, char * command, char * arg){
int t;
t = fork();
if (t < 0) { // fork error
perror("fork failed"); // call perror here to check fork
return -1;
}
if (t == 0){ // child
execl(file, command, arg, (void *)0);
perror("exec failed"); // call perror here to check execl
exit(1);
}
// parent
return t;
}
Upvotes: 4