I've noticed an problem involving flock() on device files [/dev/null in
particular] under FreeBSD. There is a comment in the source code which
implies awareness of this issue but it looks to me like there is a logic
error in the code:
maildrop-1.8.0/maildrop/filelock.C: [re-formatted]
52 void FileLock::do_filelock(int fd)
53 {
54 int flockrc;
55
56 while ((flockrc=ll_lock_ex(fd)) < 0 && errno == EINTR)
57 ;
58
59 if (flockrc < 0)
60 {
61 struct stat stat_buf;
62
63 // FreeBSD has problems locking /dev/null. Presume that if
64 // you're writing to a device file, you know what you're doing.
65
66 if (fstat(fd, &stat_buf) >= 0 && (
67 S_ISREG(stat_buf.st_mode) || S_ISDIR(stat_buf.st_mode)))
68 {
69 return;
70 }
71
72 throw "flock() failed.";
73 }
74 }
The comment on lines 63-64 implies that an flock() failure for device
file will be ignored, however the code on lines 66-72 returns without
throwing an flock() exception when the file descriptor belongs to a
regular file or directory. I expect the desired behaviour is to return
without throwing exception when the file descriptor belongs to a
character or block device file type, as expressed in this patch:
--- maildrop/filelock.C.orig Sat Apr 29 03:17:45 2000
+++ maildrop/filelock.C Fri Apr 15 13:09:25 2005
@@ -64,7 +64,7 @@
// you're writing to a device file, you know what you're doing.
if (fstat(fd, &stat_buf) >= 0 && (
- S_ISREG(stat_buf.st_mode) || S_ISDIR(stat_buf.st_mode)))
+ S_ISCHR(stat_buf.st_mode) || S_ISBLK(stat_buf.st_mode)))
{
return;
}