2

我目前正在努力解决这个错误。我正在编写一个 shell 模拟器,使用 fork() 执行使用 execvp(); 的命令。几乎我尝试解析到我的 shell 的每个命令都运行良好,除了没有参数的 ls 。如果我尝试执行 ls -lah,一切正常,但简单的 ls 不会,收到以下错误:

ls: fts_open: No such file or directory

这是我的代码片段:(只是必不可少的)

pid = fork();
      if (pid==0)
      {
        puts("CHILD");
        puts(args[0]);
        puts(args[1]);
        printf("%d\n", strlen(args[1]));
        args[2] = NULL;
        execvp(args[0], args);
      }
      else wait(NULL);
      puts("BACK TO PARENT");
    }

这是 ls 的输出:

ls
CHILD
ls

0
ls: fts_open: No such file or directory
BACK TO PARENT

如您所见,args[0] 包含 ls,args[1] 为空,因为没有参数,args[1] 的长度为 0,但我不断收到错误消息。

知道它可能是什么吗?

编辑:

感谢 Jonathan Leffler 发现它:(另外,这似乎只是 Mac 上的一个问题)

关键是 args[1] 并不是真的为空,因此操作系统会尝试打开 '' 文件,该文件显然不存在,并且从外观上看,无法创建,因为它不是真的是一个名字。

所以,这就是我所做的:检查 args[1] 的 len。如果为 0,则将其设置为 NULL。(只是释放内存并没有真正帮助)

pid = fork();
      if (pid==0)
      {
        puts("CHILD");
        puts(args[0]);
        puts(args[1]);
        if (strlen(args[1]) == 0)
            args[1] = 0;
        args[2] = NULL;
        execvp(args[0], args);
      }
      else wait(NULL);
      puts("BACK TO PARENT");
    }
4

1 回答 1

5

如果没有更多参数,则指针应该为空,而不是指向零长度字符串的非空指针。

pid = fork();
if (pid==0)
{
    puts("CHILD");
    puts(args[0]);
    fflush(stdout);
    args[1] = 0;
    execvp(args[0], args);
    fprintf(stderr, "Failed to exec %s\n", args[0]);
    exit(1);
}
else
    wait(NULL);
puts("BACK TO PARENT");

纯粹出于好奇,我在命令行中尝试了这个:

$ ls ''
ls: fts_open: No such file or directory
$

你也在Mac上运行吗?(说我很惊讶看到同样的消息并没有开始描述我的反应!)更有趣的是,创建文件fts_open似乎并没有摆脱错误消息。的奇怪行为ls,但响应无效请求(没有空字符串的文件名)。

于 2013-04-09T03:41:12.633 回答