如何处理execve函数?

如何处理execve函数?,c,pointers,execve,C,Pointers,Execve,我正在编写此函数: int main(int argc, char const *argv[]) { char* hack[]; hack[0] = "/bin/sh"; hack[1] = NULL; execve(hack[0], &hack, &hack[1]); return 0; } 我的问题是,写这句话的区别是什么: execve(hack[0], &hack, &hack[1]); 而不是: execve

我正在编写此函数:

int main(int argc, char const *argv[]) {
  char* hack[];
  hack[0] = "/bin/sh";
  hack[1] = NULL;

  execve(hack[0], &hack, &hack[1]);
  return 0;
}
我的问题是,写这句话的区别是什么:

execve(hack[0], &hack, &hack[1]);
而不是:

execve(hack[0], hack, NULL);
如果有任何不同,哪种方法是最好的?写第一种表达方式时,我会得到一个警告:

warning: passing argument 2 of ‘execve’ from incompatible pointer type [-Wincompatible-pointer-types]
note: expected ‘char * const*’ but argument is of type ‘char * (*)[3]’

这意味着什么?

编辑:我将从一个关于
execve
的解释开始,让它更清楚一点

execve
将运行程序路径名,替换当前进程、堆栈帧和堆。为此,需要三个参数:

  • 程序路径名的路径。这是一个基本的
    字符*
    ,带有程序的路径
  • 传递给程序argv的参数。这与传递给您自己的
    main
    :获取命令行参数的
    argv
    的用法相同,第一个这样的参数是程序的
    路径名
  • 环境变量envp。这列出了程序执行上下文中存在的环境变量(例如$PATH,它列出了操作系统可以合理地找到可执行文件的所有路径)
argv和envp都是
char**
,这意味着它们是
char*
(以null结尾的字符串)的列表,最后一个元素为null。 然后,程序可以期望迭代它们,直到找到一个空指针来收集其参数和环境

--

你的两种说法有两个不同之处:

  • 第二个参数(argv):

    • 在第一种情况下,指向
      hack
      数组的指针,这意味着您有一个
      字符***
      ,与需要一个
      字符**
      的声明不兼容
    • 在第二种情况下,
      hack
      数组本身是一个
      char**
      (也称为字符串数组)
  • 第三个参数(envp):

    • 在第一种情况下,指向
      hack
      数组的第二个元素的指针,它转换为“第一个元素为NULL的字符串数组”
    • 在第二种情况下,NULL(在LINUX系统上为的解释如上所述,但在大多数其他UNIX系统中会导致错误
  • 引用Exeve(2)手册页:

    在Linux上,argv和envp可以指定为NULL。在这两种情况下, 这与将参数指定为指针具有相同的效果 指向包含单个空指针的列表不要服用 这种非标准和不可携带的功能的优势打开 在许多其他UNIX系统中,将argv指定为NULL将导致 错误(默认)。其他一些UNIX系统将envp==NULL处理 案例与Linux相同

    总之,在你的情况下,正确的选择是

    execve(hack[0], hack, &hack[1]);
    

    旁注:
    char*hack[]应该是
    char*hack[2]
    (或者更好的是
    char*hack[]={/bin/sh”,NULL};
    )。