#include <sys/file.h>
#include <stdint.h>
+#include <stdbool.h>
#include <time.h>
#include <fcntl.h>
void exec_or_die(const char *arg, ...);
int exec_and_wait(const char *arg, ...);
time_t strtotimet(const char *np, const char **errpp);
-
-static inline int open_locked(const char *path, int flags, mode_t mode) {
-#ifdef O_EXLOCK
- flags |= O_EXLOCK;
- return (open(path, flags, mode));
-#else
- int fd = open(path, flags, mode);
- if (fd != -1) {
- if (flock(fd, LOCK_EX) == -1) {
- close(fd);
- fd = -1;
- }
- }
- return (fd);
-#endif
-}
-
-static inline int openat_locked(int dfd, const char *path, int flags, mode_t mode) {
-#ifdef O_EXLOCK
- flags |= O_EXLOCK;
- return (openat(dfd, path, flags, mode));
-#else
- int fd = openat(dfd, path, flags, mode);
- if (fd != -1) {
- if (flock(fd, LOCK_EX) == -1) {
- close(fd);
- fd = -1;
- }
- }
- return (fd);
-#endif
-}
-
+bool lock(int fd, bool write);
const char *errstr;
xasprintf(&indexfilename, "%s/index", listdir);
- fd = open_locked(indexfilename, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
- if(fd == -1) {
+ fd = open(indexfilename, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
+ if(fd == -1 && !lock(fd, true)) {
free(indexfilename);
log_error(LOG_ARGS, "Error opening index file");
return 0;
free(tmp);
}
- fd = open_locked(logfilename, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
- if(fd < 0) {
+ fd = open(logfilename, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
+ if(fd < 0 && !lock(fd, true)) {
log_error(LOG_ARGS, "Could not open %s", logfilename);
free(logfilename);
return -1;
digestinterval = ctrltimet(dfd, "digestinterval", DIGESTINTERVAL);
digestmaxmails = ctrllong(listdir, "digestmaxmail", DIGESTMAXMAILS);
- fd = openat_locked(dfd, "lastdigest", O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
- if (fd < 0) {
+ fd = openat(dfd, "lastdigest", O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd < 0 && !lock(fd, true)) {
log(" - Could not open or create 'lastdigest': %s\n",
strerror(errno));
return (false);
/* initialize file with mail to send */
- if((mailfd = open_locked(mailfilename, O_RDWR, 0644)) < 0) {
+ if((mailfd = open(mailfilename, O_RDWR, 0644)) < 0 &&
+ !lock(mailfd, true)) {
log_error(LOG_ARGS, "Could not open '%s'", mailfilename);
exit(EXIT_FAILURE);
}
subfilename = concatstr(3, listdir, subdir, chstr);
- subfilefd = open_locked(subfilename, O_RDWR|O_CREAT|O_APPEND,
+ subfilefd = open(subfilename, O_RDWR|O_CREAT|O_APPEND,
S_IRUSR|S_IWUSR|groupwritable);
- if(subfilefd == -1) {
+ if(subfilefd == -1 && !lock(subfilefd, true)) {
log_error(LOG_ARGS, "Could not open '%s'", subfilename);
exit(EXIT_FAILURE);
}
strcmp(dp->d_name, "..") == 0)
continue;
- rfd = openat_locked(fd, dp->d_name, O_RDONLY, 0644);
+ rfd = openat(fd, dp->d_name, O_RDONLY, 0644);
if (rfd == -1)
continue;
+ if (!lock(rfd, false))
+ continue;
if (fstat(rfd, &st) == -1) {
log_err("Impossible to determine the size of %s/%s: %s",
}
xasprintf(&wrname, "%s.new", dp->d_name);
- wfd = openat_locked(fd, wrname, O_RDWR|O_CREAT|O_TRUNC,
+ wfd = openat(fd, wrname, O_RDWR|O_CREAT|O_TRUNC,
S_IRUSR|S_IWUSR|groupwritable);
- if (wfd == -1) {
+ if (wfd == -1 && !lock(wfd, true)) {
log_err("Could not open '%s/%s': %s", subdir, wrname,
strerror(errno));
munmap(start, st.st_size);
* IN THE SOFTWARE.
*/
+#include <fcntl.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <errno.h>
#include <inttypes.h>
#include <spawn.h>
+#include <stdbool.h>
#include <unistd.h>
#include "xmalloc.h"
return (WEXITSTATUS(pstat));
}
+
+bool
+lock(int fd, bool wr)
+{
+ struct flock lck;
+ int r;
+
+ if (fd == -1)
+ return (false);
+ lck.l_type = wr ? F_WRLCK : F_RDLCK;
+ lck.l_whence = SEEK_SET;
+ lck.l_start = 0;
+ lck.l_len = 0;
+ do {
+ r = fcntl(fd, F_SETLKW, &lck);
+ } while (r < 0 && errno != EINTR);
+ if (r == -1) {
+ close(fd);
+ return (false);
+ }
+ return (true);
+}