Un Python demoniaco alla fermata del bus!

## dei processi del demone: verranno creati due fork, in questo modo

## sarà possibile "staccare" il programma dal terminale e farne

## continuare l’esecuzione in background.

def start():

try:

# procediamo con il primo fork…

pid = os.fork()

if pid > 0:

# chiudiamo il processo padre…

sys.exit(0)

except OSError, e:

print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)

sys.exit(1)

# "stacchiamolo" dal processo principale…

os.setsid()

os.umask(0) # …e diamogli i giusti permessi!

# Ora procediamo con il secondo fork…

try:

pid = os.fork()

if pid > 0:

print "test daemon: pid " + str(pid)

sys.exit(0)

except OSError, e:

print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)

sys.exit(1)

# Controlla l’esistenza della directory del file di log. Se non esiste, la crea.

if not os.path.isdir(LOG_DIR):

os.mkdir(LOG_DIR, 0755)

# Infine scrive l’id del processo nel file .pid.

f = open(os.path.join(LOG_DIR, ‘run.pid’), ‘w’)

f.write("%d" % os.getpid())

f.close()

return 0

## Se start() serve per avviarlo, immaginate un po’ a che serve

## questo… Se il demone è attivo lo termina e restituisce 0, altrimenti

## stampa un avviso e restituisce -1.

def stop():

## Controlliamo la presenza del file .pid…

if os.path.isfile(os.path.join(LOG_DIR, ‘run.pid’)):

## apre il file e legge l’id del processo…

f = open(os.path.join(LOG_DIR, ‘run.pid’), ‘r’)

pid = string.atoi(string.strip(f.readline()))

f.close()

try:

os.kill(pid, 0) ## …dunque prova a killarlo…

except os.error, args:

if args[0] != errno.ESRCH: ## …se non trova il processo

raise os.error, args ## lancia un’eccezione…

else:

os.kill(pid, signal.SIGTERM) ##….altrimenti invia un SIGTERM

return 0 ## al demone

return -1

# Memorizza il nome del programma.

call_name = os.path.split(sys.argv[0])[1]

## Riceve gli argomenti passati sulla riga di comando. Stabiliamo di

## processarne 3, "start", "status" e "stop", uno per ogni metodo di

## quelli definiti in precedenza.

if len(sys.argv) != 2:

sys.stderr.write("Usage: %s [start|stop|status]\n" % call_name)

sys.exit(1)

if len(sys.argv) == 2:

if sys.argv[1] == ‘stop’:

# "Stoppa" il demone

s = stop()

if s == 1: ## se il demone non è attivo stampa un avviso…

sys.stdout.write("%s: daemon is not running\n" % call_name)

sys.exit(1) ## …e esci.

sys.stdout.write("%s: stopped.\n" % call_name)

sys.exit(0)

elif sys.argv[1] == ‘status’:

# Stampa lo stato del demone…. beh, questa è facile, no?

s = status()

if s == -1:

sys.stdout.write("%s: daemon is not running\n" % call_name)

else:

sys.stdout.write("%s: daemon [%d] is running\n" % (call_name, s))

sys.exit(0)

elif sys.argv[1] == ‘start’:

# Oh ecco, qui avviamo il demone, verificando prima che non sia già

# già stato caricato in memoria.

s = status()

if s != -1:

sys.stdout.write("%s: daemon [%d] is running\n" % (call_name, s))

sys.exit(1)

start()

else:

## e qui ricordiamo all’utente come funziona il nostro demone….

sys.stderr.write("Usage: %s [stop|status]\n" % call_name)

sys.exit(1)

## Terminata la parte "infernale", ovvero quella relativa al demone,

## passiamo ad occuparci del lato server.

# Apriamo la connessione con DBus e "attacchiamoci" al bus della sessione.

session_bus = dbus.SessionBus() # Per un demone di sistema va sostituito con dbus.SystemBus()

try:

# Creiamo, inizializziamo e "attacchiamo" l’oggetto a DBus

bus_name = dbus.service.BusName(‘org.test.daemon’, bus=session_bus)

object = Demone(bus_name)

except Exception, e:

print "Errore ", e

# Ora non resta che avviare il loop principale

mainloop = gobject.MainLoop()

mainloop.run()

# Il demone è pronto e già freme nell’attesa di

# rispondere alle nostre richieste!

Ok, salvato il file apriamo un terminale e diamogli i giusti permessi con

chmod +x ~/test/daemon.py

Finito! Per avviarlo basta digitare il nome del comando seguito dall’opzione start:

~/test/daemon.py start

Successivamente, per stopparlo, basterà sostituire start con stop.

Se si vuole essere sicuri che tutto sia andato a buon fine, su Ubuntu è possibile andare su Sistema -> Amministrazione -> Monitor di sistema e verificare con i propri occhi la presenza del demone fra i processi residenti in memoria:

Page 2 of 3 | Previous page | Next page