|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9455
|
[ C ] Ditemi dove sta l'errore...
Come da soggetto...
/* File: microshell-0.c Specifica: piccola shell che esegue un comando passato (con argomenti) dallo STDIN, ne restituisce codice di uscita e torna ad attendere un successivo comando Data: 28-04-2004 Problema: Non considera gli argomenti passati. Inoltre bisogna "per forza" dare uno spazio dopo aver digitato il comando sullo standard input */ #include <sys/types.h> #include "sysmacro.h" #include "util.h" #define TRUE 1 #define MAXCOMMANDLENGTH 100 int main (int argc, char * argv[]) { int pid; char * stringa = (char*) malloc(sizeof(char) * MAXCOMMANDLENGTH);/*Al massimo un comando di 100 caratteri*/ char**a; int n; int contaComando = 0; int statoComando = 0; while(TRUE) { contaComando++; printf("PROMPT>"); fgets(stringa, MAXCOMMANDLENGTH, stdin); a = split_arg(stringa, " ", &n); if ((pid = fork()) == -1) { perror("Padre> errore nella fork"); exit(0); } if (pid == 0) {/*FIGLIO*/ execvp(a[0], &a[1]);//<-- L'errore e' qua ?!? perror("Figlio> errore nella exec"); /*Perror solo in caso d'errore*/ } else {/*PADRE*/ wait(&statoComando); printf("Padre> eseguito comando n.: %d ; stato di uscita : %d\n", contaComando,statoComando); } } return(0);/*Mai...*/ } Questo e', invece, il codice dove si trova la funzione split_args(...); /* File: util.c Specifica: funzioni di utilita' */ /* include per stat */ #include <sys/stat.h> /* include per malloc e strlen */ #include <stdlib.h> #include <string.h> #include "util.h" ..... ..... ..... @description -- split_arg ritorna il vettore dei token in una stringa separati da un qualsiasi carattere separatore @param -- linea, la linea da cui estrarre i token @param -- separatori, i caratteri separatori (es ": ;", due punti, blank e puntevvirgola) @param -- numerotoken (OUTPUT) contiene il numero dei token trovati @return -- puntatore all'array di token (stesso formato di argv) */ char ** split_arg(char *linea, char *separatori, int *numerotoken) { int i = 0; /* numero token trovati */ char **argv; /* vettore dei token */ char *copialinea; /* copia della linea */ char **indirizzocopialinea = &copialinea; /* punta a copialinea */ /* copia la stringa argomento */ copialinea = malloc( strlen(linea) + 1 ); strcpy(copialinea, linea); /* alloca la prima posizione vettore dei token */ argv = malloc(sizeof(char *)); while( (argv[i] = strsep(indirizzocopialinea, separatori)) != NULL ) { /* ancora un token */ i++; /* ridimensiona vettore dei token */ argv = realloc(argv, (i + 1) * sizeof(char *)); } /* scrive il numero di token trovati */ *numerotoken = i; /* libera lo spazio allocato */ free(copialinea); return(argv); } THKS
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Feb 2003
Città: fra casa e lavoro
Messaggi: 1061
|
a parte che esiste il tag [ CODE ] (senza spazi) che è una manna dal cielo per ste cose...
non ho capito cos'è che vorresti, che prendessimo quella roba, capissimo cosa c'è che non va e ti dicessimo dove e come risolverla?
|
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9455
|
Quote:
Ho chiesto solo se qualcuno puo' dirmi se capisce dove ho sbagliato e perche' in esecuzione ho l'errore descritto. Altrimenti cosa avrei postato a fare ?!?
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Ma che errore ti riporta il compilatore ?
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9455
|
Quote:
Esempio di sessione: [xxx@localhost Lab4]$ microshell-0 PROMPT>ls -al 3interi.c filetype.c mycatlib strcmpp.c albero2004.c Frase.c mycatlib.c strcpyy.c albero.c mycopydir strdupp.c albero.h infoDirectory.c mycopydir.c studente.h cattura.c invia.c myfind sysmacro.h CreaFile.c joinn.c myfind.c tailn.c CreaProcessi.c Lista.h pippo tastieraperdue.c CreaWaitpid.c lsb Primo.c timeout.c critical.c lsb.c QuantiDescrittori.c #timeOut.c# CrivelloBeta.c makefile scrittori.c timeres Crivello.c microshell-0 sorgente.c timeres.c CrivelloGamma.c microshell-0.c StampaQuadrato.c util.c Dati.h microshell-0.c~ ste util.h exstudente.c mycat util.o exstudente.h mycat.c strcatt.c Padre> eseguito comando n.: 1 ; stato di uscita : 0 PROMPT>man fork Quale pagina di guida vuoi? Padre> eseguito comando n.: 6 ; stato di uscita : 256 PROMPT>man 3 exec No manual entry for exec Padre> eseguito comando n.: 7 ; stato di uscita : 256 PROMPT> ... -opzione ls non considerata !! -opzione fork non considerata !! -opzione exec considerata ma ugualmente errore: il secondo argomento viene ignorato (3)
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9455
|
UUUUUUUUUUUUUUPPPPPPPPPPPPPPPPPPPPPP.....
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Hai provato ad eseguire la funzione split_arg al di fuori del programma...mettila in un programma di prova e passagli i parametri adatti... Vedrai che il risultato non è corretto...
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9455
|
Quote:
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9455
|
La funzione split_arg(...) funziona correttamente. Non da nessun errore a compilazione e fa cio' che ci si aspetta ovvero divide una stringa di caratteri in parole a seconda del carattere di separazione passatto.
Esempio: char * stringa = "Mi sono rotto i coglioni"; char ** parole; int numeroToken; parole = split_args(stringa, " ", &numeroToken); /*Avremo che: parole[0] = mi parole[1] = sono parole[2] = rotto parole[3] = i parole[4] = coglioni numeroToken = 5 */
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Ah...ho scoperto... Il primo argomento passato come secondo parametro di execvp deve essere il nome del comando...
Quindi la devi chiamare così: execvp(a[0], a); |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9455
|
Quote:
Cmq. ora riprovo... ... no, no... niente da fare... non viene eseguito niente... ne il comando da solo ne il comando con parametri. Esempio: [xxx@localhost Lab4]$ microshell-0 PROMPT>ls Figlio> errore nella exec: No such file or directory PROMPT>ls ls: : No such file or directory Padre> eseguito comando n.: 2 ; stato di uscita : 256 PROMPT>ls -l ls: invalid option -- Usare `ls --help' per ulteriori informazioni. Padre> eseguito comando n.: 3 ; stato di uscita : 256 PROMPT> Mah...
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Mi fai il favore di stampare il contenuto di tutti gli elementi di a prima dell'esecuzione ?
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Jun 2003
Città: vivo in Sicilia (tra la prov. di AG e Palermo)
Messaggi: 956
|
Conosco poco l'uso di fork, wait e execvp (quasi per niente), comunque provo a capire qualcosa del codice.
Innanzitutto, se non ricordo male, fgets a differenza di gets, non toglie il carattere di new line dalla stringa di ritorno, quindi forse ti conviene modificare la stringa di separatori passata a split_args in " \n" Poi non capisco perchè passi la stringa a[1] per variabile: ti serve modificare il vettore di puntatori a? Già passando a[1] dai alla funzione la possibilità di modificare la stringa, passando &a[1] modifichi anche il punto di inizio della stringa: se execvp valuta param_2 (consentimi di chiamarlo così) un carattere alla volta, incrementando il puntatore (come saprai, una stringa in c non è altro che il puntatore al suo primo carattere) alla fine a[1] sarà una stringa nulla (a furia di param_2++ sarà param_2 == "\0"). Ti serve? Oppure devi passare un vettore di stringhe? In questo caso, se devi passare il vettore a da a[1] in poi ticonviene fare qualcosa del tipo execvp(a[0], ++a). Infine, non capisco bene il modo in cui chiami execvp. Come prima cosa chiami una fork() e assegni il risultato a pid. Quindi se pid vale -1 notifichi un errore e termini il programma; se pid vale 0 esegui la execvp e notifichi un altro errore (oppure hai omesso di riportare un controllo if sul valore di ritorno della exec prima di eseguire la perror?); per qualsiasi altro valore di pid esegui una wait e quindi notifichi l'avvenuta esecuzione di un comando (ma non dovresti rieseguire la execvp? ho sempre più l'impressione che manchi del codice...). Quanto all'output, in che ordine dovrebbero essere inseriti il nome del processo da eseguire e i parametri da passare come argomenti? Nel caso dell'ultimo comando della prima sessione che hai postato (man 3 exec), se ho interpretato bene il tuo codice, dovrebbe valere a[0] == "man", a[1] == "3", a[2] == "exec". Mi fai la cortesia di postare nome e tipo dei parametri di execvp (magari con una breve descrizione del loro significato) così vedo di farmi venire qualche idea... Ciao |
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9455
|
Quote:
Ciao, ![]() Ed.
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Per la precisione la lunghezza del vettore di puntatori è pari al numero di parametri + 1...l'ultimo deve essere inizializzato a 0...
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jun 2003
Città: vivo in Sicilia (tra la prov. di AG e Palermo)
Messaggi: 956
|
Capito. Su &a[0] ho sparato una mezza ca@@at@. Ho ragionato su una generica stringa s, e ho esteso male il ragionamento al vettore di stringhe. In pratica è come passare a.
Grazie per le info su fork e execvp Ciao |
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Sì...è come passare a...
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 05:20.




















