【问题标题】:execl error == "file exists" when the file doesn't exist当文件不存在时,execl error == "file exists"
【发布时间】:2018-05-08 00:35:18
【问题描述】:

我试图了解 execl 在尝试启动不存在的文件时返回的错误。

这是我的实验代码,main 调用了 spawn1 函数,该函数将创建 fork 并尝试启动 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;
}

返回的错误是:

exec didn't work: File exists

为什么不是更像“文件不存在”?

【问题讨论】:

    标签: c execl


    【解决方案1】:

    你没有在正确的地方打电话给perror

    当某个函数失败时,需要在该函数失败后立即检查errno或调用perror。在失败的函数之后调用的任何其他系统或库函数都将用自己的错误代码覆盖errno

    更改您的代码以立即调用perror,如下所示:

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

    【讨论】:

      猜你喜欢
      • 2020-11-20
      • 1970-01-01
      • 2017-04-08
      • 2023-01-19
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多