Issue
I want to write program that becomes daemon on demand:
if_there_are_no_daemon_alive_start_daemon();
pass_job_to_daemon();
and I stuck on implementation of if_there_are_no_daemon_alive_start_daemon
.
At first I think of trying to lock file /run/lock/my-unique-name.lck
,
and if succeeded then do double fork and done,
and if not then daemon is up and running and time to call pass_job_to_daemon
.
But file lock acquired in parent process, just disappears after parent die:
#include <assert.h>
#include <fcntl.h>
#include <sys/file.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
assert(argc > 1);
int fd = open(argv[1], O_WRONLY | O_APPEND | O_CREAT, 0600);
assert(fd >= 0);
int ret = flock(fd, LOCK_EX);
assert(ret == 0);
printf("get flock\n");
pid_t pid = fork();
assert(pid >= 0);
if (pid == 0) {
printf("child process\n");
sleep(5); //<-- no flock here according to lslocks
printf("child done\n");
} else {
printf("parent: time to exit\n");
}
return 0;
}
So what variant of interprocessor lock can I use here, to make check if daemon running atomic and then pass this lock to child process after double forking without problems?
Solution
Lock files don't require any file locking such as flock
. The existence of the file is used as the lock. Add O_EXCL
to the open
call. If open
succeeds, you have the lock; then to release the lock you remove
or unlink
the file.
You need some handling for stale lock files in the case of a crash. That's one reason they are typically created in a particular directory, because the system startup scripts know about it and delete the lock files.
Answered By - Kaz Answer Checked By - Mary Flores (WPSolving Volunteer)