Я предполагаю, что execvp не работает, но, поскольку вы не обрабатываете ошибки, вы его не видите.
Попробуйте это:
char *const args[] = {"ls", NULL};
execvp(args[0], args);
/* If this is reached execvp failed. */
perror("execvp");
В качестве альтернативы вы можете использовать составные литералы:
execvp("ls", (char *[]){"ls", NULL});
Вторая идея: попытайтесь запустить вещи нормально, без перенаправления и посмотрите, как это работает.