【问题标题】:execve() returning error for any commandexecve() 为任何命令返回错误
【发布时间】:2017-06-20 03:34:07
【问题描述】:

我必须制作一个自定义外壳作为学校项目,但我遇到了这个问题:

int exec_shell(char **argv) //
{
    if (execve(argv[0], (char **)argv , NULL)==-1) //if an error occurs
    {
            printf("Commande invalide : %s\n", argv[0]);
            fflush(stdout);//vide le buffer
            exit(0);
            return -1;
    }

    return 0;
}

这应该很简单——你以字符串形式输入一个命令,然后 exec 调用该命令。 但是,它总是返回错误。

我做错了什么?

这是一个警告:

primitives.c:25:30: 警告:不推荐将字符串常量转换为‘char*’ [-Wwrite-strings]

【问题讨论】:

  • 代码的第 25 行是什么?这就是警告的来源。
  • 鉴于char **argv 参数,(char **) 演员表毫无意义。不要使用不必要的演员表。 argv[0] 中有什么内容?您不应该将空指针作为环境参数传递。进程有权使用最小环境 - 您应该将有效指针传递给空列表而不是空指针(char *empty[] = { 0 }; 并传递 empty 代替 NULL)。如果您检查了errno(或在调用printf() 之前使用了perror()),您希望看到EINVALInvalid argument 作为错误条件。此外,错误通常应该报告在stderr,而不是stdout
  • 请阅读本规范以获取 execve api。 linux.die.net/man/2/execve
  • 这是我使用execvp()写的一个例子:stackoverflow.com/a/42973015/900078
  • 你确定你使用的是 C 编译器吗,不知何故这个警告闻起来像 C++。

标签: c linux exec


【解决方案1】:

步骤:1

/* myecho.c */

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
   int j;

   for (j = 0; j < argc; j++)
       printf("argv[%d]: %s\n", j, argv[j]);

   exit(EXIT_SUCCESS);
}

编译程序:gcc myecho.c -o myecho

步骤:2

/* execve.c */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int
main(int argc, char *argv[])
{
   char *newargv[] = { NULL, "hello", "world", NULL };
   char *newenviron[] = { NULL };

   if (argc != 2) {
       fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
       exit(EXIT_FAILURE);
   }

   newargv[0] = argv[1];

   if (execve(argv[1], newargv , newenviron) == -1) //if an error occurs
    {
            printf("Commande invalide : %s\n", argv[0]);
            fflush(stdout);//vide le buffer
            exit(0);
            return -1;
    }
}

编译程序:gcc execve.c -o execve

step: 3 //最终调用

./execve ./myecho

步骤:观察输出。

【讨论】:

  • 你是对的。根据您的建议,它已修改。谢谢。
【解决方案2】:

要传递一个空的环境,要么定义并传递

char * env[] = { NULL };

像这样作为execve() 的第三个参数

execve(argv[0], argv, env)

或者使用复合文字

execve(argv[0], argv, (char*[]){NULL})

同样,exec*() 系列函数的成员在错误时返回,因此周围的代码可能如下所示:

int main(void)
{

  ...

  execve(argv[0], argv, (char*[]){NULL});
  perror("execve() failed");

  return EXIT_FAILURE; /* include stdlib.h to have this macro available */
}

【讨论】:

    【解决方案3】:

    [已解决] 嘿,谢谢大家的回答。它帮助我更好地弄清楚出了什么问题,我找到了答案here。 主要问题是路径不正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-30
      • 1970-01-01
      • 1970-01-01
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      • 1970-01-01
      相关资源
      最近更新 更多