FAQ 2004/05

1. Ho provato ad eseguire il programma digitando

> a.out
ma il risultato e' stato
bash: a.out command not found

R: La variabile di ambiente ambiente PATH non contiene la directory corrente ("."): per eseguire il programma basta fornire il parth name completo dell'eseguibile, ad esempio quello relativo:
> ./a.out
Per risolvere il problema si deve aggiungere la directory corrente alla variabile PATH della shell, nella bash basta dare il comando:
> export PATH=$PATH:. 
nella csh/tcsh
> setenv PATH ${PATH}:.
Per vedere il valore del PATH
> echo $PATH
per capire che shell stiamo utilizzando
> echo $SHELL
Per non dover ripetere il comando export/setenv ogni volta che aprite una finestra dovrebbe essere sufficiente aggiungere il comando come una riga dello script ~/.bashrc (bash) o ~/.cshrc (csh/tcsh).

2. Come posso ottenere informazioni in linea sulle funzioni di libreria C?
R: Usando la sezione 3 dei manuali, ad esempio

> man 3 printf

3. Quali sono le informazioni che devono essere incluse nella relazione? Come possiamo strutturarle?
R: Una possibile struttura della relazione e' la seguente:
1. Introduzione 
  (struttura complessiva dell'implementazione)
  (principali idee guida)
  (deve tracciare a grandi linee il quadro complessivo, delineando le  
parti giocate da quanto descritto nelle sezioni successive)

2. Strutture Dati
  (le strutture dati principali utilizzare per realizzare il progetto,
puo' fare anche un elenco puntato indicando come sono strutturate, le
motivazioni della scelta, il file di header in cui sono dichiarate e
quanto altro sembra opportuno)

3. Struttura del server
(Descrizione dettagliata della struttura del server con la descrizione
delle fasi principali di elaborazione. Qua si fa ovviamente riferimento
alle SD gia' descritte senza introdurle di nuovo)
(ovviamente va dato piu' spazio ai punti critici rispetto a parti ovvie)

4. Struttura del client
( come server)


Appendice
A. Guida per l'utente
     Compilazione
     Installazione
     Esecuzione/terminazione del server
     Esecuzione/Terminazione del client
B. Problemi/bug noti (se ce ne sono ...:-)...)

4. I campi della struttura voce devono contenere il terminatore?
R: Si , il campi di voce sono stringhe terminate da '\0' dopo l'ultimo carattere significativo. Le stringhe possono contenere anche spazi bianchi (es. per i nomi composti).
5. La stringa b prodotta dalla formatvoce() deve essere chiusa dal terminatore '\0'?
R: Si, deve essere una stringa a tutti gli effetti.
6. Il record r prodotta dalla vocetorec() deve essere chiuso dal terminatore '\0'?
R: No, il formato del database prevede un record di 140 caratteri senza alcun terminatore.
7. Il record r prodotta dalla vocetorec() deve essere chiuso dal newline '\n'?
R: No, il formato del database prevede un record di 140 caratteri senza newline. Il newline sara' usato per separare un decord dall'altro nel file che contiene il database.
8. Non ho consegnato il frammento 1 del progetto, posso ancora consegnare il frammento 2?
R: Si, prima di tutto deve consegnare il frammento 1, anche dopo la scadenza e poi procedere alla consegna del 2 entro la scadenza. Quindi:
> make consegna1
> make consegna2

9. Ho trovato un errore nel frammento 1 del progetto, anche se passava il test, posso consegnare la versione corretta insieme al frammento 2?
R: Si, consegni entrambi i frammenti prima delle scadenza del frammento due con:
> make consegna1
> make consegna2

10. Nella funzione push() devo allocare sia elem che voce?
R: No, non e' necessario. Si puo' assumere che la voce sia gia' stata allocata, basta che poi le chiamate vengano effettuate in modo consistente.
11. Ho dei Segmentation Fault quando invoco funzioni di libreria tipo free(), getenv(), etc...
R: Questo e' un tipico sintomo di errori nell'allocazione delle stringhe (spazio insufficiente), buffer overrun (come effetto spesso di strcpy() o di altre funzioni che assumono di lavorare su stringhe terminate correttamente se invocate su stringhe senza terminatore), oppure di errata gestione e copia dei puntatori. Quindi la manifestazione spesso no nha niente a che vedere con il punto in cui si e' verificato l'errore vero e proprio.
In questo caso la cosa da fare ricontrollare incrementalmente tutto il codice alla ricerca di possibili malfunzionamenti su stringhe e puntatori.
12. Come si testa effettua il test del codice?
R: Molto brevemente. Il test del codice *non* deve essere effettuato alla fine della stesura di tutte le funzioni, ma deve essere fatto incrementalmente su ogni funzione sviluppata. Questo permette di trovare piu' semplicemente gli errori perche' e' possibile concentrarsi su una porzione piu' piccole e ben definita delle funzioni. E' anche una buona idea raccogliere tutti i test che verificano le varie funzioni in modo da ripeterli automaticamente ogni volta che il codice viene modificato per fissare un nuovo bug su una funzione gia' testata. I risultati potrebbere essere sorprendenti.
13. Attenzione alla funzione cerca()
R: Fate in modo che la lista risultato r e la lista di partenza db *non* condividano memoria nascosta. Quindi per ogni elemento inserito in r deve essere allocata opportuna memoria ed effettuate opportune copie in modo che la memoria occupata dalla due liste sia disgiunta. Altrimenti una deallocazione di una delle due liste dealloca automaticamente anche pezzi dell'tra con ovvi problemi.
14. Come posso proteggere i miei file in modo che non siano leggibili dagli altri gruppi? Posso anche lasciare accesso agli utenti del mio gruppo?
R: Basta fissare un nome di directory noto solo agli utenti del gruppo (es 56yu897j) e proteggere in lettura la directory che la contiene in modo che solo chi ne conosce il nome possa accedervi. Ad esempio
> chmod 711 ~                    (*tolgo i diritti di lettura della mia home a tutti eccetto me*)
> ls -ld ~
drwx--x--x    8 susanna     user          672 2005-04-12 16:48 /home/susanna/
> mkdir ~/56yu897j               (*creo la directory segreta*)
Adesso per gli altri utenti e' impossibile fare ls sulla mia home directory es:
> echo $USER           (* sono l'utente garibaldi*)
garibaldi
>ls ~susanna
ls: /home/susanna/: Permission denied
pero' posso ancora accedere alla directory 56yu897j se ne conosco il nome
> echo $USER           (* sono l'utente garibaldi*)
garibaldi
>ls ~susanna/56yu897j
prorub/

15. Ho completato il progetto, ma non riesco a passare il test perche' i miei messaggi appaiono in ordine diverso da quelli di ./test3/out3.check . Che significa?
R: Il file ./test3/out3.check raccoglie i messaggi stampati sullo standard output (printf(), fprintf(stdout,...) etc) dal server e dal client durante l'esecuzione dello script test-finale. Tali messaggi utilizzano l'output bufferizzato (libreria stdio.h) e quindi *non* possono essere riprodotti nello stesso ordine utilizzando la SC write() non bufferizzata. Quindi per superare il test si deve quindi
  • utilizzare solo le primitive di stdio.h per la stampa sullo standard output
  • Siccome lo standard error non viene controllato durante il test finale, il formato e la struttura dei messaggi di errore e' completamente libero e non influisce sul passaggio del test.