char* argv[] = {"/bin/sh","sh","-c","/bin/ls", (char*) NULL};
execve(argv[0], argv, environ);
Обратите внимание, что вы используетеargv[0]
(/bin/sh
)дважды, один раз в качестве первого аргумента для execve()
, а другой раз как часть массива, переданного в качестве второго аргумента. Это не то, что происходит в вашем execl()
вызове, там у вас есть только /bin/sh
в качестве первого аргумента (файл программы ).
Итак, ваш execve()
выполняет файл /bin/sh
, присваивая ему имя программы (нулевой аргумент )из /bin/sh
и обычные аргументы sh
, -c
, /bin/ls
. Это почти то же самое, что и вызов execl("/bin/sh", "/bin/sh", "sh", "-c", "/bin/ls", (char*) NULL)
. Или в командной строке оболочки:
$ /bin/sh sh -c /bin/ls
/bin/sh: 0: Can't open sh
Это говорит оболочке попытаться запустить скрипт с именем sh
в текущем каталоге, и Dash выдает сообщение об ошибке, если скрипт не существует.Ноль, вероятно, является номером строки для аргумента командной строки. (Bash выдает похожее, но другое сообщение об ошибке и, кажется, тоже ищет сценарий из PATH
. Я не уверен, что стандарт говорит что-либо об использовании здесь PATH
.)
Вместо этого вы могли бы сделать
char *program = "/bin/sh";
char *argv[] = {"sh", "-c", "/bin/ls", NULL};
execve(program, argv, environ);
или, может быть,
char *argv[] = {"/bin/sh", "sh", "-c", "/bin/ls", NULL};
execve(argv[0], argv + 1, environ);