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?
CodePudding user response:
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.