Ossia Frequently Asked Questions.
Nella descrizione del progetto per un errore di stampa sono nominati i socket AF_INET, tuttavia la comunicazione deve avvenire attraverso i socket AF_UNIX.
Su Linux la costante non risulta essere definita, createvi voi una macro con il valore visto a lezione nel file lcscom.h
.
Si, basta che si tratti di “aggiunte” che non modificano i prototipi delle funzioni date.
Si, il server deve attivare thread paralleli per gestire le connessioni concorrenti (e' possibile attivare un thread per ogni connessione o un pool di thread). In particolare no ne' possibile usare un server con un solo thread utilizzando la select per scegliere fra i descrittori pronti.
NO, il client dplan (come generalmente avviene per i comandi unix) puo' essere invocato con le opzioni in ordine qualsiasi. In particolare le due versioni seguenti sono equivalenti ed accettabili
dplan -r gigi agenda.txt dplan agenda.txt -r gigi
come anche
dplan agenda -u mario#compleanno -d 12-12-2008 dplan -u mario#compleanno -d 12-12-2008 agenda dplan -u mario#compleanno agenda -d 12-12-2008
per evitare di impazzire, usate la funzione di libreria getopt
per il parsing evitando di fare a mano tutti i casi possibili.
Le specifiche di Wator sono abbastanza lasche. Essenzialmente lo squalo se puo' mangia (e si sposta nella cella del pesce mangiato) altrimenti si sposta solamente. La riproduzione puo' avvenire dopo aver mangiato o essersi spostati. La scelta della preda, della cella dove spostarsi e della cella dove inserire il figlio viene effettuata casualmente sulle scelte possibili.
Per verificare il formato di data ed ora e' possibile usare direttamente il comando date
con opzione -d
, consultate il man relativo.
E` possibile usare GDB per debuggare programmi multiprocesso / multithread come indicato nella documentazione qui e qui. E` possibile usare i comandi indicati anche in DDD, scrivendoli manualmente nel prompt del GDB in basso nella schermata.
E' possibile usare il debugger GDB da emacs. Questo permette di seguire interattivamente il flusso di esecuzione in due sottofinestre dell'editor. Per attivarlo:
ESC-X gdb
e fornendo il nome dell'eseguibile da debuggare (a questo punto si attiva una finestra GDB in cui e' possibile fornire gli usuali comandi)si`. ci possono essere grafi con archi uguali, cioe` che collegano gli stessi nodi piu` di una volta. Il primo grafo nel programma di test corrisponde al noto grafo di Eulero rappresentante i ponti della citta di koenigsberg.
La funziona find_clique restituisce il numero di clique inserite nell'array e non il numero di clique trovate in totale in quanto l'array puo' non avere spazio per tutte le clique.
R: Questa situazione si puo` verificare per tre ragioni differenti:
-g
);g++
);libc
, libm
…).
Quest'ultima situazione si verifica nel caso in cui siano state usate funzioni di libreria all'interno delle quali viene allocata della memoria (come la strdup()
). La memoria, anche se allocata da funzioni di libreria, deve essere sempre liberata usando una free()
.
char *p; char s[6] = "pippo"; p = strdup(s); /* ... */ free(p);
R: Molto probabilmente la causa di buona parte dei problemi di quota e` dovuta all'utilizzo di eclipse come ambiente di sviluppo. la prima cosa da fare e` vedere quanto spazio e` utilizzato inutilmente da eclipse. (si assume che l'utente lavori nella directory workspace)
(susanna):==>du -sh ~/workspace/.metadata 12.4M /home/susanna/workspace/.metadata
a questo punto si puo` procedere con l'eliminazione. ATTENZIONE: state attenti ad inserire questo comando esattamente cosi`, altrimenti rischiate di cancellare tutti i vostri files
(susanna):==>rm -fr ~/workspace/.metadata
Oppure
Si puo' cancellare la cache di Mozilla mediante l' utilizzo dello script rimuovicache.sh fornito dai docenti:
(susanna):==> wget http://www.cli.di.unipi.it/~bartolin/rimuovicache.sh (susanna):==> chmod +x rimuovicache.sh (susanna):==> ./rimuovicache.sh
Oppure:
(susanna):==> ./rimuovicache.sh --help
Per un mostrare le opzioni dello script.
R: Molto probabilmente e' stata raggiunta la quota disco. Per risolvere il problema e' sufficiente digitare [CTL+ALT+F1], effettuare il login in modo testuale e seguire i passi della FAQ “ho la quota disco piena e non riesco a salvare i miei files”.
R: Per ragioni “storiche” il CDC usa la csh/tcsh come shell default di login e non permette di cambiarla. Nel prossimo futuro verra' effettuato un adeguamento allo standard di fatto attuale fornendo la bash come shell di login e permettendo a chi non ce l'ha di sceglierla. Per sperimentare con la shell bash basta digitare
(susanna):==> bash bash-2.05b$
oppure
(susanna):==> exec bash bash-2.05b$
in entrambi i casi la vostra shell mandera' in esecuzione una bash con cui potrete interagire. Alla fine potete uscire con
bash-2.05b$ exit exit (susanna):==>
oppure EOF (CTRL-D).
Per non avere un ambiente “nudo” si consiglia di salvare i seguanti script di configurazione (esattamente con questi nomi) nella vostra home directory (ad esempio, ~susanna/ per l'utente susanna):
.bashrc .bash_profile .bash_aliases
In questo modo otterrete un prompt piu' significativo e un ambiente piu` gradevole:
(susanna):==> bash susanna@aulaa:~$
In particolare aggiungendo ulteriori comandi di alias al terzo script potete personalizzare la shell creandovi i vostri alias usuali per i vari comandi (es, “rm -i” per “rm”, o “h” per “history”).
NOTA BENE: I sistemisti sconsigliano vivamente di mettere il comando exec bash
direttamente nei file .login o .cshrc perche' questo potrebbe interferire negativamente con altri settaggi standard dei vostri ambienti, in particolare quello grafico.
nella directory che lo contiene 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:.
o 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).
R: Usando le sezioni 2 e 3 dei manuali, rispettivamente per system calls e funzioni di libreria, ad esempio
$ man 2 read $ man 3 printf
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/
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 non ha niente a che vedere con il punto in cui si e' verificato l'errore vero e proprio.
In questo caso la cosa da fare e' ricontrollare incrementalmente tutto il codice (magari con l'aiuto di un debugger) alla ricerca di possibili malfunzionamenti su stringhe e puntatori.
R: E' possibile usare il comando indent (vedi la sua pagina di manuale per tutte le opzioni) per indentare automaticamente il codice: una buona linea di comando e'
indent -kr -br -brs file.c
Su Vim l'indentazione puo' essere fatta tramite il comando =
R: Molto brevemente: il testing del codice non va confuso con il debugging (ovvero la ricerca dell'errore in un programma che si ritiene sbagliato). Infatti nel testing si cerca di mettere sotto pressione un codice in principio corretto in modo da evidenziare tempestivamente possibili malfunzionamenti.
E' buona norma testare sistematicamente i vari aspetti delle funzioni man mano che queste vengono sviluppate. In particolare e' una buona idea sviluppare, parallelamente al codice, un programma di test che stressa i punti importanti e controlla automaticamente che i risultati siano corretti.
In particolare, e' una PESSIMA idea iniziare a testare il codice dopo averne scritta gran parte. Il testing deve essere fatto incrementalmente su ogni funzione sviluppata. Questo permette di trovare piu' semplicemente gli errori perche' e' possibile concentrarsi su porzioni piu' piccole e ben definite del programma.
E' anche una buona norma raccogliere tutti i test che verificano le varie funzioni in modo da ripeterli automaticamente (con opportuni script) ogni volta che il codice viene modificato per fissare un nuovo bug o aggiungere nuove funzionalita' su una funzione gia' testata.
In rete esistono librerie che aiutano ad organizzare i test (vedi ad esempio C unit e gcov o man gcov per controllare quale parte del codice e' stata testata e quale no). Per una trattazione piu' dettagliata ma introduttiva vedi ad esempio Kerninghan & Pike capitolo 6.
R: Una possibile struttura della relazione e' la seguente:
R: Su alcune architetture la accept() va invocata con
struct sockaddr_un addr; int ret; socklen_t x2 = sizeof (addr); ret = accept(s, (struct sockaddr *)&addr, &x2);
invece che passando il secondo argomento NULL.