Помните, что argv[0]
- это «имя программы», поэтому при вызове вашей программы это будет что-то вроде ./a.out
.Тогда argv[1]
- это первый аргумент вашей программы, то есть имя программы, которую вы хотите exec
, а остальная часть argv
- это остальные аргументы для передачи этой программе.
Таким образом, массив argv
, который вы хотите передать программе, которую вы собираетесь выполнить, начинается с argv[1]
.Или, если быть более точным, указатель argv
, который вы хотите указать для программы, которую вы собираетесь exec
, равен argv + 1
.
Вы, очевидно, поняли это для вызова execlp
, поскольку выуказан argv[1]
дважды, один раз в качестве имени программы для exec
и один раз в качестве первого (и единственного) элемента в массиве argv
для передачи этой программе.Вам просто нужно сделать то же самое для звонка на execvp
;вместо execvp(argv[1], argv)
вам понадобится execvp(argv[1], argv + 1)
.
Сообщение об ошибке, которое вы получаете от самой утилиты ls
.Вы вызвали ls
с execvp
, передав ему весь массив argv
.Другими словами, вы сказали ему, что его имя ./a.out
(что, вероятно, немного сбивает с толку, так как большинство утилит используют имя программы, которое они дают для создания сообщений об ошибках), и вы предоставили его ls -l
в качестве аргументов командной строки.По сути, это то же самое, что командная строка:
ls ls -l
, которая, если вы попробуете это, с большой вероятностью скажет вам, что файл ls
не существует.(Если в текущем каталоге нет файла с именем ls
.)
Кстати:
argv[argc++] = NULL;
совершенно не нужен.argv[argc]
гарантированно будет равным NULL, и вам не нужна переменная argc
(и если она у вас есть, вам, вероятно, понадобится, чтобы она была на один меньше, а не на один больше).