Otro de los requerimientos de un demonio es salvar
su identificador de proceso en un fichero como /var/run/eliza.pid
.
Antes de crearlo comprobamos la existencia del fichero.
Si existe leemos el PID del proceso y miramos si todavía esta ejecutándose usando una señal 0. Si devuelve verdadero detenemos la ejecución.
Si es falso puede ser porque la última ejecución terminara bruscamente sin poder borrar el fichero o bien porque el proceso esta vivo pero se está ejecutando por otro usuario y no tenemos los privilegios para entregar la señal. Si es este último caso lo que ocurrirá es que no podremos eliminar el fichero y terminaremos la ejecución.
sub open_pid_file { my $file = shift; if (-e $file) { # oops. pid file already exists my $fh = IO::File->new($file) || die "Can't open file $file\n"; my $pid = <$fh>; die "Corrupted PID file $PID_FILE\n" unless defined($pid) && ($pid =~ /^\s*\d+\s*$/); die "Server already running with PID $pid" if kill 0 => $pid; warn "Removing PID file for defunct server process $pid.\n"; die "Can't unlink PID file $file" unless -w $file && unlink $file; } return IO::File->new($file,O_WRONLY|O_CREAT|O_EXCL,0644) or die "Can't create $file: $!\n"; }
Creamos el fichero con
IO::File->new($file,O_WRONLY|O_CREAT|O_EXCL,0644)La combinación de modos
O_WRONLY|O_CREAT|O_EXCL
garantiza
que el fichero será creado y abierto pero sólo si no existe.
Aunque hemos comprobado previamente la no existencia podría ocurrir que
varios procesos estuvieran lanzando este daemon casi simultáneamente e
intentan crear el fichero al mismo tiempo.
El flag O_EXCL
indica exclusividad en este sentido:
Si el fichero ya existe la apertura falla. O_EXCL
puede fallar en sistemas NFS y no tiene efecto a menos que se use también la flag
O_CREAT
.
Casiano Rodríguez León