danny block notes

giovedì, 4 dicembre 2008

Guide Programmazione

Filed under: c,j2me,java,JSP,mysql,programming — danny @ 11:47 am

Guide Programmazione


Ant


Eclipse

Java

JavaME

JDBC

JSP/Servlet

MySQL

PHP

Project Managment


SQL

UML

VisualBasic.Net


Web Applications

Web Server

WordPress

domenica, 14 ottobre 2007

Unix Programming : Pipe e Fifo

Filed under: c,linux,programming — danny @ 4:29 pm
Tags: , , ,
/* PIPE */
// permettono la comunicazione tra processi relazionati (es. padre-figlio)

int pipe(int fd[2])
// Invoca la creazione di una PIPE
// fd: puntatore ad un array di due interi (in fd[0] viene restituito il descrittore di lettura della PIPE,
// in fd[1] viene restituito il descrittore di scrittura della PIPE)
// fd[0] e fd[1] possono essere usati da subito (senza open() ) come normali descrittori di file tramite le chiamate read() e write()
// ­1 in caso di fallimento

/* NOTE:
1. Un processo lettore vede la �fine� della PIPE quando tutti i
processi scrittori hanno chiuso il descrittore fd[1].
2. La chiamata read() effettuata da un lettore restituisce 0 come
notifica dell�evento che tutti gli scrittori hanno terminato il loro lavoro
3. Un processo scrittore che tenti di scrivere sul descrittore fd[1]
quando tutte le copie del descrittore fd[0] sono state chiuse
(cioè non ci sono lettori sulla PIPE) riceve il segnale SIGPIPE
4. NB: Per evitare deadlock è necessario che tutti i processi
chiudano i descrittori di PIPE che non gli servono usando la close().
*/

/* FIFO */
// permettono la comunicazione tra processi relazionati e non

int mkfifo(char* name, int mode)
// Invoca la creazione di una FIFO
// name: puntatore ad una stringa che identifica il nome della FIFO da creare
// mode: intero che specifica la modalità di creazione e permessi di accesso alla FIFO (in genere O_CREATE | 0666)
// ­1 in caso di fallimento, altrimenti un descrittore per lâ��accesso alla FIFO

int unlink (const char * nomefifo)
// elimina dal sistema la fifo.
// NB: con la close chiudo la fifo ma non la elimino
// ­1 in caso di fallimento

int open (const char * nomefifo,int FLAGS)
// NB: è bloccante : un processo che tenta di aprirla in lettura (scrittura) viene bloccato
// fino a quando un altro processo non la apre in scrittura (lettura).
// FLAGS principali : O_RDWR, O_RDONLY, O_WRONLY, O_NONBLOCK (per rendere la open non bloccante)
// ­1 in caso di fallimento, altrimenti un descrittore per lâ��accesso al canale della FIFO

/* NOTE:
1.
2. La chiamata read() effettuata da un lettore restituisce 0 come
notifica dell�evento che tutti gli scrittori hanno terminato il loro lavoro
3. Un processo scrittore che tenti di scrivere sulla fifo
quando non ci sono lettori sulla fifo riceve il segnale SIGPIPE
4. per gestire una chiusura inaspettata del programma che ha creato la pipe
si usa catturare i seguenti segnali (la funz. disconnetti_pipe contiene una unlink)
signal(SIGTERM, disconnetti_pipe);
signal(SIGHUP, disconnetti_pipe);
signal(SIGINT, disconnetti_pipe);
per i processi che invece non haano creato la pipe è sufficiente gestire un SIGPIPE
signal(SIGPIPE, esci_dal programma);
*/

domenica, 1 luglio 2007

Unix Programming : Segnali

Filed under: c,linux,programming — danny @ 2:47 pm
Tags: , ,
/* SEGNALI : EVENTI ASINCRONI */

/* sono segnalazioni asincrone generate in genere dal SO e da altri processi.
se non vengono gestite viene applicato il comportamento di default : chiusura del processo.
possibilità di gestione :
1. cattura del segnale   (e si esegue una certa routine)
2. ignoramento esplicito (non possibile per tutti i segnali es. SIGKILL)
2. ignoramento implicito (comp. di default)
Segnali più utilizzati:
SIGINT  : interrupt CTRL-C
SIGPIPE : già visto sopra
SIGALRM : inviato allo scadere di un timeout
SIGHUP  : si chiude il terminale
SIGTERM : chiusura non forzata processo
SIGUSRx : x=1,2,... definito dall'utente
*/

int kill (int pid, int segnale)
// non è la kill!!! ma serve per generare un segnale da inviare al processo pid
// tranne che se si è root, si possono inviare segnali solo a processi dello stesso utente
// è asincrona non bloccante.
// -1 in caso di fallimento

int raise(int segnale)
// invia un segnale al proesso corrente
// come kill (getpid(),sengale)

unsigned int alarm(unsigned int seconds);
// programma un timer interno al sistema operativo che invia al processo stesso un segnale SIGALRM dopo seconds secondi.
// restituisce il numero di secondi rimanenti alla generazione di un evento  impostato da una precedente chiamata ad alarm.
// Effettuare una chiamata ad alarm quando ne era stata già effettuata un�altra imposta il valore del timer
// pari a quello nell�ultima chiamata.

void (* signal(int sig, void (*func)(int))) (int);
// cattura il segnale sig e lancia la funzione func:
// func: puntatore alla funzione di gestione del segnale oppure SIG_DFL/SIG_IGN.
// ritorna SIG_ERR in caso di errore, altrimenti il valore della precedente funzione
// di gestione del segnale che viene sovrascritto con func.
//    SIG_DFL impone al processo il comportamento di default.
//    SIG_IGN impone al processo di ignorare esplicitamente il segnale.

int pause(void);
// blocca il processo in attesa di un qualsiasi segnale.
// ritorna sempre -1 e dopo la eventuale funzione di gestione (in una signal)
// non è possibile sapere direttamente da pause quale segnale ha provocato lo sblocco;
// si può rimediare facendo si che l�handler del segnale modifichi il valore di
// una variabile globale.

/* NOTE:
1. I processi figli ereditano le eventuali gestioni dei segnali (tranne se si ha una exec).
2. Possono interrompere sia funzioni di programma sia systemcall bloccanti, in questo caso
la chiamata non viene ripetuta e la variabile globale errno viene settata a EINTR.
Questo implica che la corretta invocazione di una systemcall bloccante è :
while ( systemCall() == -1 )
if ( errno != EINTR ) {
printf (�Errore!\\n�);
exit(1);
}
Infatti lo schema seguente non basta :
if ( systemCall() == -1 ) {
printf (�Errore!\\n�);
exit(1);
}
*/

/* LA GESTIONE DEI SEGNALI VISTA FINORA è INAFFIDABILE POICHé PUò GENERARE DEADLOCK!!!
questo poichè non si gestiscono segnali che possono arrivare in un breve lasso di tempo,
eventualmente minore del tempo di esecuzione dell'handler di gestione.
Per questo un processo può bloccare temporaneamente la consegna di un segnale (tranne SIGKILL).
In pratica si crea un accodamento gestito dalla SIGNAL MASK cioè una maschera che indica quali segnali
si stanno bloccando.
Si lavora sulla Signal Mask attraverso la struttura SIGSET_T ed alle funzioni : */

int sigemptyset (sigset_t *set);
// Svuota set.
int sigfillset (sigset_t *set);
// Mette tutti i segnali in set.
int sigaddset (sigset_t *set, int signo);
// Aggiunge il segnale signo a set.
int sigdelset (sigset_t *set, int signo);
// Toglie il segnale signo da set.
int sigismember (sigset_t *set, int signo);
// Controlla se signo è in set.

int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
// modifica la signal mask.
// how: indica in che modo intervenire sulla signal mask e può valere:
//     SIG_BLOCK: i segnali indicati in set sono aggiunti alla signal mask;
//    SIG_UNBLOCK: i segnali indicati in set sono rimossi dalla signal mask;
//    SIG_SETMASK: La nuova signal mask diventa quella specificata da set;
// set: il signal set sulla base del quale verranno effettuate le modifiche.
// oset: se non è NULL, il backup della signal mask attuale/precedente
// -1 in caso di errore.

int sigpending(sigset_t *set);
// restituisce l�insieme dei segnali bloccati che sono attualmente pendenti.
// set: il signal set in cui verrà scritto l�insieme dei segnali pendenti.
// -1 in caso di errore.

int sigaction( int sig,
const struct sigaction * restrict act,
struct sigaction * restrict oact);
// Permette di esaminare e/o modificare l�azione associata ad un segnale.
// sig: il segnale interessato dalla modifica;
// act: indica come modificare la gestione del segnale;
// oact: backup della precedente struttura sigaction
// -1 in caso di errore.

struct sigaction {
void (*sa_handler)();
/* indirizzo del gestore o SIG_IGN o SIG_DFL*/
void (*sa_sigaction)(int, siginfo_t *, void*);
/* indirizzo del gestore che riceve informazioni addizionali
sul segnale ricevuto (utilizzato al posto di sa_handler se
sa_flags contiene SA_SIGINFO ) */
sigset_t sa_mask;
/* segnali addizionali da bloccare prima dell'esecuzione del gestore */
int sa_flags;
/* opzioni addizionali */
};

/* Notifiche (eventualmente multiple) dello stesso segnale durante l�esecuzione del
gestore sono bloccate fino al termine del gestore stesso (a meno che sa_flags valga NO_DEFER).
Con l�uso di sigaction l�azione specificata per il trattamento di un segnale rimane
attiva fino ad una successiva modifica.
*/

int sigsuspend(const sigset_t *sigmask);
// attende l�arrivo di un segnale.
// sigmask: prima di mettersi in attesa la funzione rende attiva questa signal mask;
// torna sempre -1 con errno che vale EINTR.
// una volta terminata, ripristina la signal mask precedente alla sua chiamata.
// Quando viene attivata, se esistono segnali pendenti che vengono sbloccati da
// sigmask, questi vengono immediatamente consegnati.
// Se non esistono segnali pendenti, oppure questi non vengono sbloccati, la funzione
// mette il processo in attesa dell�arrivo di un qualsiasi segnale non bloccato.

// ESEMPIO : passi da seguire per una gestione sicura dei segnali

// 1. definire l'handler di gestione
void myhandler(...)

// 2. dichiarazione strutture necessarie nel main
struct sigaction sig, oldsig;
sigset_t sigmask, oldmask, zeromask;
// le old sono solo di backup...potrebbe esser necessario utilizzarle (null altrimenti nelle successive chiamate)
// zeromask è una sigmask vuota che utilizziamo per disattivare il blocco

// 3. inizializzazione : blocco del segnale SIGUSR1
sigemptyset(&zeromask);

sigemptyset(&sigmask);
sigaddset(&sigmask,SIGUSR1);
sigprocmask(SIGBLOCK, &sigmask, &oldmask);
// ho aggiunto il sigset sigmask all'insieme dei segnali da bloccare

// 4. inizializzazione gestore di segnale
sig.sa_handler = myhandler;
sig.sa_flags = 0;
sigemptyset(&sig.sa_mask);
// sono segnali addizionali da bloccare prima del gestore...dipende dal programma

sigaction(SIGUSR1,&sig,&oldsig)
// quello che faceva la signal ma lo indirizzo al gestore e non direttamente all'handler

// 5. dipende dal programma :
// a questo punto in genere si creano i processi figli considerando che fin qui i segnali SIGUSR1 sono bloccati.
// se per esempio il figlio dovesse fare qualcosa ed inviare un segnale al padre allora una volta finito il suo lavoro :
kill(getppid(),SIGUSR1);
// sblocca il segnale qualora anche lui dovesse ricevere un segnale dal padre
sigsuspend(&zeromask);
// in pratica si mette in attesa di segnali rendendo attiva zeromask (che è vuota quindi non blocca niente)
// e ripristinando poi la sigmask precedente alla chiamata (quella che blocca SIGUSR1)
// il padre analogamente prima sblocca il segnale fa quello che deve fare ed eventualmente manda un segnale di risp al figlio

Unix Programming : Socket

Filed under: c,linux,programming — danny @ 2:43 pm
Tags: , ,
TCP_SERVER: socket,bind,listen,accept,(rcv/send),close
TCP_CLIENT: socket,connect,(send/rcv),close

UDP_SERVER: socket,bind,(rcvfrom/sendto),close
UDP_CLIENT: socket,(sendto/rcvfrom),close

/* strutture che utilizzeremo */

struct sockaddr_in {
u_char sin_len;
u_char sin_family;
u_short sin_port;
struct in_addr sin_addr;
char     sin_zero[8];
};
struct in_addr {
in_addr_t s_addr;
};
// sockaddr_in è definita in <netinet /in.h>

struct   hostent {
char    *h_name;       // official name of host
char    **h_aliases;   // alias list
int     h_addrtype;    // host address type
int     h_length;      // length of address
char    **h_addr_list; // list of addresses from name server
};
// hostent

/* SERVER */

int socket(int family, int type, int protocol)
// family = AF_INET (IPv4), AF_INET6 (IPv6), AF_LOCAL (local Unix)...
// type = SOCK_STREAM (TCP), SOCK_DGRAM (UDP), SOCK_RAW (for special IP packets, PING, etc. Must be root)
// protocol = 0 (used for some raw socket options)
// restituisce sockfd
// fare bzero() prima per inizializzare

int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
// la sockaddr è in lettura dal SO e può essere riempita con ip e porta altrimenti auto dal SO
// nota : un server può offrire servizi su + indirizzi ip se ha + interfacce di rete
// restituisce 0,-1

int listen(int sockfd, int backlog)
// mette in ascolto la server socket (passiva)
// backlog = num massimo di connessioni in attesa, in genere 5
// non serve nelle connessioni UDP
// restituisce 0,-1

int accept(int sockfd, struct sockaddr *clientaddr, socklen_t *addrlen)
// sockaddr scritto dal SO
// mette in attesa il server e restituisce il NUOVO sockfd che gestisce il client (un po' come welcomeSocket in java)

/* read &amp; write  */

int close(int sockfd)
// restituisce o,-1

/* CLIENT */

int socket(int family, int type, int protocol)
// family = AF_INET (IPv4), AF_INET6 (IPv6), AF_LOCAL (local Unix)...
// type = SOCK_STREAM (TCP), SOCK_DGRAM (UDP), SOCK_RAW (for special IP packets, PING, etc. Must be root)
// protocol = 0 (used for some raw socket options)
// restituisce sockfd del client per comunicare col server (ancora da associare)
// fare bzero() prima per inizializzare

int  connect(int socket fd, const struct sockaddr *serveraddr, socklen_t addrlen)
// sockaddr in lettura dal SO per indirizzare la connessione al server (va impostato prima)
// non ha senso in UDP
// restituisce 0,-1 non socket descriptor

// int bind ...!!! la usa il prof in una esercitazione di un echoClient UDP ???

/* read &amp; write  */

int close(int sockfd)
// restituisce o,-1

/* CLIENT &amp; SERVER  */

// inizializzazione
struct sockaddr_in myaddr;
bzero(myaddr, sizeof(myaddr) );
oppure memset(&amp;myaddr, 0, sizeof(myaddr) );

// funzioni di IO

int read (int sockfd, char* recvline, int size);
// legge size caratteri dal socket. Se la funzione legge meno dati di quanti richiesti da size, vuol dire che non ci sono dati da leggere.

int readline(int sockfd, char* recvline, int size);
// legge size caratteri dal socket. La funzione si blocca in lettura sul socket fino a quando non riceve una battuta di invio (un carattere di newline '\\n'.

int write(int sockfd, char* line, int size);
// scrive size caratteri nel socket. Se la funzione scrive meno byte di quanti richiesti da size, allora non c'è spazio disponibile nel buffer del socket.

// al posto* delle classiche read() &amp; write() posso utilizzare :

int recv(int sockfd, void *buffer, size_t mbytes, int flags)
int send(int sockfd, void *buffer, size_t mbytes, int flags)

// per UDP invece

int recvfrom(int sockfd, void *buffer, size_t mbytes, int flags, struct sockaddr *from, socklen_t *addrlen)
int sendto(int sockfd, void *buffer, size_t mbytes, int flags,  struct sockaddr to, socklen_t addrlen)

/* *hanno in + solo i flags :
MSG_DONTWAIT (this send non-blocking)
MSG_OOB (out of band data, 1 byte sent ahead)
MSG_PEEK (look, but don�t remove)
MSG_WAITALL (don�t give me less than max)
MSG_DONTROUTE (bypass routing table)
*/

struct hostent *gethostbyname(const char *hostname)
// restituisce l'indirizzo ip (in una struttura hostent) associato ad un nome di dominio (www oppure locale)

int gethostname(char *hostname, int bufferlen)
// ritorna il nome dell'host su cui viene lanciata

unsigned long inet_addr(char *addr)
//conversione formato indirizzo da dotted form a numeric (network byte order)

char* inet_ntoa(struct in_addr addr)
// viceversa con addr.s_addr = long int rappesentation

inet_aton("10.1.45.8", &amp;mio_servaddr.sin_addr);
// converte l'indirizzo ip passato come stringa, in una struttura in_addr.

// altre da studiare htons, htons, strtol

Unix Programming : Multi-processo e Multi-thread

Filed under: c,linux,programming — danny @ 2:41 pm
Tags: , , , ,
/* MULTI-PROCESSO */

pid_t fork()
// ritorna 0 nel figlio ed il nuovo pid nel padre

pid_t getpid()
// restituisce il pid del processo su cui viene chiamato

pid_t getppid()
// restituisce il pid PADRE del processo su cui viene chiamato

pid_t wait(int *stat_loc)
// mette il processo chiamante in attesa che termini il figlio e ne ritorna il pid (del figlio)
// infine scrive all'indirizzo stat_loc il codice di ritorno del figlio

/* MULTI-THREAD */

int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)(void *),
void *arg)
/* Crea un nuovo thread eseguendo in esso la funzione start_routine con i parametri
attuali specificati in arg. Il tID del nuovo thread creato viene scritto nella variabile
puntata da thread. La funzione restituisce 0 in tutti i casi in cui non si verifica errore.
*/

int pthread_detach(pthread_t thread);
/*  Rende il thread, il cui tID è stato passato come parametro, un detached thread in
modo che possa rilasciare le sue risorse alla fine della sua esecuzione.
*/

int pthread_join(pthread_t thread, void **value_ptr);
/*  Mette il thread chiamante in attesa che il thread indicato con il primo parametro
termini. La locazione di memoria puntata da value_ptr può essere usata per
raccogliere un eventuale valore restituito dal thread in uscita. La funzione
restituisce un valore diverso da 0 in caso di errore.
*/

int pthread_exit(void *value_ptr);
/*  Termina il thread chiamante rendendo disponibile il valore puntato da value_ptr
per un eventuale pthread_join eseguito da un altro thread.
*/

int pthread_cancel(pthread_t thread);
//  Termina il thread indicato come parametro.

Unix Programming : Basics

Filed under: c,linux,programming — danny @ 2:38 pm
Tags: ,
// Concetti di base
/* INCLUDE */
#include <lib_standard .h>
#include "lib_programmer.h"

/* ISTRUZIONI DI SELEZIONE */

// selezione semplice
if (cond) {blocco then}
{blocco else}

// operatore ternario
(condizione)? bloccoThen : bloccoElse

// selezione multipla
// espressione può essere solo int, short, long o char;
switch (espressione) {
case elem1:
istruzione1;
break;
...
default:
istruzione;
}

/* PUNTATORI */
indirizzo = &amp; variabile
variabile = * indirizzo

variabile = * ( &amp; variabile )
indirizzo = &amp; ( * indirizzo )

// dichiarazione di un puntatore
tipo_ptr * nome_ptr

// relazione con array
array: tipo nome[dim]
vale : nome = &amp; nome[0]
vale : nome + i = &amp; (nome[i])
vale : nome[0] = * nome
vale : nome[i] = * (nome + i)

/* STRUCT E UNION */
la union si dichiara come una struct ma si può usare un solo campo preso in mutua esclusione

/* IO STANDARD */
std_in    = 0; sI
std_out   = 1; sO
std_error = 2; sE

// output oltre alla printf(const char *format,arg1,arg2,...)
int putchar(int c)
// scrive c sullo sO e ritorna il carattere stesso
int puts(const char *s)
// scrive s (deve terminare con '') sullo sO e ritorna un numero positivo.

// input oltre alla scanf(const char *format,ptr1,ptr2,...)
int getchar();
// legge un carattere (confermato da ENTER) dallo sI e lo ritorna
char* gets(char *s)
// legge una stringa dallo sI, ritorna il puntatore alla stringa e scrive nel buffer s ed aggiunge ''

/* FILE */

// apertura e/o creazione
FILE* fopen(const char *path, const char *mode)
// mode = percorso + nome file
// mode = "r" "w" "a"

// chiusura
int fclose(FILE *f)
// ritorna 0 se non ci sono errori

// output - scrittura
int fputc(char c, FILE *stream)
// scrive c sul file stream e ritorna il carattere stesso
int puts(const char *s, FILE *stream)
// scrive s (deve terminare con '') sul file stream e ritorna un numero positivo.
int fprintf(FILE *stream, const char *format,arg1,arg2,...)
// come la printf

// input - lettura
int fgetc(FILE *stream);
// legge un carattere dal file stream e lo ritorna
char* fgets(char *s, int size, FILE *stream)
// legge una stringa di size byte dal file stream, ritorna il puntatore alla stringa e scrive nel buffer s ed aggiunge ''
int fscanf(const char *format,ptr1,ptr2,...)
// come la scanf

// accesso
int fseek(FILE *stream, long offset, int whence)
// posiziona il puntatore in whence + offset
// offset : entità dello spostamento in byte
// whence : posizione di riferimento = SEEK_SET,SEEK_END,SEEK_CUR cioè inizio,fine,corrente

void rewind(FILE *stream)
// posiziona il puntatore all'inizio

Blog su WordPress.com.