rnews: batch naming and locking
Miquel van Smoorenburg
miquels at cistron.nl
Tue Oct 22 12:31:58 UTC 2002
According to Miquel van Smoorenburg:
> The patch is not completely working though. The fixes are correct,
> but the locking still has a race condition.
> This is caused by the *stupid* POSIX fcntl() locking rules.
.. and here is the fix for that. We simply open the spool file
twice, and use one fd for locking only.
--- inn-2.4-20020916/frontends/rnews.c.orig Wed Sep 18 12:59:05 2002
+++ inn-2.4-20020916/frontends/rnews.c Tue Oct 22 13:40:39 2002
@@ -593,7 +593,7 @@
register bool ok;
struct stat Sb;
char hostname[10];
- int fd;
+ int fd, lockfd;
size_t i;
char *badname, *uuhost;
@@ -625,8 +625,20 @@
continue;
}
- /* Make sure multiple Unspools don't stomp on eachother */
- if (!inn_lock_file(fd, INN_LOCK_READ, 0)) {
+ /*
+ ** Make sure multiple Unspools don't stomp on eachother.
+ ** Because of stupid POSIX locking semantics, we need to lock
+ ** on a seperate fd. Otherwise, dup()ing and then close()ing
+ ** the dup()ed fd removes the lock we're holding (sigh).
+ */
+ if ((lockfd = open(InputFile, O_RDONLY)) < 0) {
+ if (errno != ENOENT)
+ syswarn("cannot open %s", InputFile);
+ close(fd);
+ continue;
+ }
+ if (!inn_lock_file(lockfd, INN_LOCK_READ, 0)) {
+ close(lockfd);
close(fd);
continue;
}
@@ -657,12 +669,14 @@
if (rename(InputFile, badname) < 0)
sysdie("cannot rename %s to %s", InputFile, badname);
(void)close(fd);
+ (void)close(lockfd);
continue;
}
if (unlink(InputFile) < 0)
syswarn("cannot remove %s", InputFile);
(void)close(fd);
+ (void)close(lockfd);
}
(void)closedir(dp);
More information about the inn-patches
mailing list