Il tuo problema è che temp
è un puntatore singolo ed è necessario passare una serie di puntatori a execvp()
.
Qualcosa di simile:
enum { MAX_ARGS = 64 };
char *args[MAX_ARGS];
char **next = args;
temp = strtok(line, " ");
while (temp != NULL)
{
*next++ = temp;
printf("%s\n", temp);
temp = strtok(NULL, " ");
}
*next = NULL;
execvp(args[0], args);
Nota che la lista degli argomenti è stato dato un puntatore nullo come terminatore, proprio come argv[argc] == NULL
in main()
. Chiaramente, ho risparmiato sul controllo degli errori (se si superano più di 63 argomenti, si verificherà un overflow della matrice args
). Ma questo contiene l'idea centrale.
Con questo esempio, io non riesco a ottenere il semplice comando del ls
al lavoro, ho provato mkdir
e echo
e sembrano funzionare bene. Passando a ls
restituisce -1 da execvp()
.
io non sono sicuro di quello che il problema potrebbe essere - tutto questo lavoro per me:
ls
ls -l
ls -l madump.c
(dove madump.c
capita di essere un file nella directory Sto provando)
Il codice che ho usato era:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
char line[1024];
while (fgets(line, sizeof(line), stdin) != NULL)
{
if (strcmp(line, "exit\n") == 0)
exit(EXIT_SUCCESS);
char *args[64];
char **next = args;
char *temp = strtok(line, " \n");
while (temp != NULL)
{
*next++ = temp;
printf("%s\n", temp);
temp = strtok(NULL, " \n");
}
*next = NULL;
puts("Checking:");
for (next = args; *next != 0; next++)
puts(*next);
execvp(args[0], args);
}
return EXIT_SUCCESS;
}
Nota che ho aggiunto \n
alla strtok()
lista di token, dopo aver creato una directory con un nuova riga alla fine del suo nome. Ottimo per gli amici fastidiosi e i nemici sconcertanti semi-istruiti, ma una seccatura dalla maggior parte delle altre prospettive. Nota come stampo i dati che verranno passati a execvp()
poco prima di farlo davvero. Spesso, userei printf("<<%s>>\n", *next);
anziché solo puts()
per ottenere un'indicazione univoca di dove iniziano e terminano gli argomenti.
L'output di eseguire il comando (doit
) era:
$ ./doit
ls -l madump.c
ls
-l
madump.c
Checking:
ls
-l
madump.c
-rw-r--r-- 1 jleffler staff 2352 Jul 28 2011 madump.c
$
Cosa hai preso dalla versione?
Dato che non si sta usando 'argc' o' argv', si potrebbe usare 'int main (void)'. Con le opzioni del compilatore io uso abitualmente, che impedisce un paio di avvertimenti. –
@ JonathanLeffler Le userò più tardi. Solo non in questo momento. – caerulean
Abbastanza onesto - ma per un SSCCE ([Esempio breve, autonomo e corretto] (http://sscce.org/)), ti sforzi di eliminare tutto ciò che è irrilevante nell'esempio ridotto. È un problema minore - molto minore. La maggior parte dei programmi offre molte più possibilità di cecchinaggio rispetto alla tua. –