简体   繁体   中英

execl error == “file exists” when the file doesn't exist

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"?

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM