So here we do have to pass the file name twice in the function.
Eles não são exatamente a mesma coisa que você observa, observando que um deles é usado como o valor argv[0] . Isso não precisa ser o mesmo que o nome de base do executável; muitas / muitas coisas a ignoram e você pode colocar o que quiser lá.
O primeiro é o caminho real para o executável, para o qual há uma necessidade óbvia. O segundo é passado para o processo ostensivamente como o nome usado para invocá-lo, mas, por exemplo:
execl("/bin/ls", "banana", "-l", NULL);
Funcionará bem, presumindo que /bin/ls é o caminho correto.
No entanto, algumas aplicações utilizam argv[0] . Geralmente, eles possuem um ou mais links simbólicos em $PATH ; isso é comum com utilitários de compactação (às vezes eles usam invólucros de shell). Se você tem xz instalado, stat $(which xzcat) mostra que é um link para xz e man xzcat é o mesmo que man xz , o que explica que "xzcat é equivalente a xz --decompress --stdout". A maneira que o xz pode dizer como foi invocado é verificando argv[0] , tornando-os equivalentes:
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);