I found out about the correct demonization here (back in the day):
Good to read. Since then, I have improved the lock code to eliminate race conditions on platforms that allow messages to be blocked in certain regions.
Here is the relevant snippet from the project in which I participated:
static int zfsfuse_do_locking(int in_child) { mkdir(LOCKDIR, 0700); if (!in_child) { ASSERT(lock_fd == -1); lock_fd = creat(LOCKFILE, S_IRUSR | S_IWUSR); if(lock_fd == -1) return -1; if (0==lockf(lock_fd, F_TEST, 0)) return lockf(lock_fd, F_TLOCK, 1); else return -1; } else { ASSERT(lock_fd != -1); lock_fd = open(LOCKFILE, O_WRONLY); if(lock_fd == -1) return -1; ASSERT(-1 == lockf(lock_fd, F_TEST, 0)); if (-1 == lseek(lock_fd, 1, SEEK_SET)) { perror("lseek"); return -1; } return lockf(lock_fd, F_TLOCK, 0); } } void do_daemon(const char *pidfile) { chdir("/"); if (pidfile) { struct stat dummy; if (0 == stat(pidfile, &dummy)) { cmn_err(CE_WARN, "%s already exists; aborting.", pidfile); exit(1); } } { int forkres, devnull; if(getppid()==1) return; forkres=fork(); if (forkres<0) { cmn_err(CE_WARN, "Cannot fork (%s)", strerror(errno)); exit(1); } if (forkres>0) { int i; for (i=getdtablesize();i>=0;--i) if ((lock_fd!=i) && (ioctl_fd!=i)) close(i); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 200000; select(0, NULL, NULL, NULL, &tv); VERIFY(0 == close(lock_fd)); lock_fd == -1; exit(0); } setsid(); VERIFY(0 == chdir("/")); umask(027); devnull=open("/dev/null",O_RDWR); ASSERT(-1 != devnull); dup2(devnull, 0); dup2(devnull, 1); dup2(devnull, 2); if (devnull>2) close(devnull); signal(SIGTSTP,SIG_IGN); signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); } if (0 != zfsfuse_do_locking(1)) { cmn_err(CE_WARN, "Unexpected locking conflict (%s: %s)", strerror(errno), LOCKFILE); exit(1); } if (pidfile) { FILE *f = fopen(pidfile, "w"); if (!f) { cmn_err(CE_WARN, "Error opening %s.", pidfile); exit(1); } if (fprintf(f, "%d\n", getpid()) < 0) { unlink(pidfile); exit(1); } if (fclose(f) != 0) { unlink(pidfile); exit(1); } } }
See also http://gitweb.zfs-fuse.net/?p=sehe;a=blob;f=src/zfs-fuse/util.c;h=7c9816cc895db4f65b94592eebf96d05cd2c369a;hb=refs/heads/maint