Non capisco come funziona execlp() in Linux

Non capisco come funziona execlp() in Linux


Ho passato gli ultimi 2 giorni cercando di capire il execlp() chiamata di sistema, ma eccomi qui. Passo subito al problema.


Il man page di execlp dichiara la chiamata di sistema come int execlp(const char *file, const char *arg, ...); con la descrizione:Il const char arg e le successive ellissi nelle funzioni execl(), execlp() ed execle() possono essere considerate come arg0, arg1, ..., argn.


Eppure vedo che la chiamata di sistema viene chiamata in questo modo nel nostro libro di testo:execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...); (i "..." devono essere individuati da noi studenti). Tuttavia questa chiamata di sistema non assomiglia nemmeno alla dichiarazione su man page della chiamata di sistema.


Sono super confuso. Qualsiasi aiuto è apprezzato.


Risposte:


questo prototipo:


  int execlp(const char *file, const char *arg, ...);

Dice che execlp è una funzione di argomento variabile. Occorrono 2 const char * . Il resto degli argomenti, se presenti, sono argomenti aggiuntivi da consegnare al programma che vogliamo eseguire - anche char * - tutte queste sono stringhe C (e l'ultimo argomento deve essere un puntatore NULL)


Quindi, il file argomento è il nome del percorso di un file eseguibile da eseguire. arg è la stringa che vogliamo che appaia come argv[0] nell'eseguibile. Per convenzione, argv[0] è solo il nome del file dell'eseguibile, normalmente è uguale a file .


Il ... sono ora gli argomenti aggiuntivi da fornire all'eseguibile.


Supponi di eseguirlo da una riga di comando/shell:


$ ls

Sarebbe execlp("ls", "ls", (char *)NULL);
O se corri


$ ls -l /

Sarebbe execlp("ls", "ls", "-l", "/", (char *)NULL);


Quindi, vai a execlp("/bin/sh", ..., "ls -l /bin/??", ...);


Qui stai andando alla shell, /bin/sh , e stai dando alla shell un comando da eseguire. Quel comando è "ls -l /bin/??". Puoi eseguirlo manualmente da una riga di comando/shell:


 $ ls -l /bin/??

Ora, come si esegue una shell e le si dice di eseguire un comando? Apri la documentazione/pagina man per la tua shell e leggila.


Quello che vuoi eseguire è:


$ /bin/sh -c "ls -l /bin/??"

Questo diventa


  execlp("/bin/sh","/bin/sh", "-c", "ls -l /bin/??", (char *)NULL);

Nota a margine:
Il /bin/?? sta eseguendo la corrispondenza dei modelli, questa corrispondenza dei modelli viene eseguita dalla shell e si espande a tutti i file in /bin/ con 2 caratteri. Se lo hai fatto semplicemente


  execlp("ls","ls", "-l", "/bin/??", (char *)NULL);

Probabilmente non succederebbe nulla (a meno che non ci sia un file effettivamente chiamato /bin/?? ) poiché non esiste una shell che interpreti ed espanda /bin/??