2 * lock.c -- cross-platform concurrency locking for fetchmail
4 * For license terms, see the file COPYING in this directory.
10 #include <string.h> /* strcat() */
12 #if defined(STDC_HEADERS)
15 #if defined(HAVE_UNISTD_H)
22 #include "fetchmail.h"
25 static char *lockfile; /* name of lockfile */
26 static int lock_acquired; /* have we acquired a lock */
29 /* set up the global lockfile name */
31 /* set up to do lock protocol */
32 #define FETCHMAIL_PIDFILE "fetchmail.pid"
33 if (getuid() == ROOT_UID) {
34 lockfile = (char *)xmalloc(
35 sizeof(PID_DIR) + sizeof(FETCHMAIL_PIDFILE) + 1);
36 strcpy(lockfile, PID_DIR);
37 strcat(lockfile, "/");
38 strcat(lockfile, FETCHMAIL_PIDFILE);
40 lockfile = (char *)xmalloc(strlen(fmhome)+sizeof(FETCHMAIL_PIDFILE)+2);
41 strcpy(lockfile, fmhome);
42 strcat(lockfile, "/");
44 strcat(lockfile, ".");
45 strcat(lockfile, FETCHMAIL_PIDFILE);
47 #undef FETCHMAIL_PIDFILE
50 static void unlockit(void)
51 /* must-do actions for exit (but we can't count on being able to do malloc) */
53 if (lockfile && lock_acquired)
57 void lock_dispose(void)
58 /* arrange for a lock to be removed on process exit */
71 if ((lockfp = fopen(lockfile, "r")) != NULL)
73 int args = fscanf(lockfp, "%d %d", &pid, &st);
77 fprintf(stderr, GT_("fetchmail: error reading lockfile \"%s\": %s\n"),
78 lockfile, strerror(errno));
82 if (args == 0 || kill(pid, 0) == -1) {
84 if (unlink(lockfile)) {
85 if (errno != ENOENT) {
89 fprintf(stderr,GT_("fetchmail: removing stale lockfile\n"));
92 fclose(lockfp); /* not checking should be safe, file mode was "r" */
95 if (errno != ENOENT) {
96 fprintf(stderr, GT_("fetchmail: error opening lockfile \"%s\": %s\n"),
97 lockfile, strerror(errno));
102 return(bkgd ? -pid : pid);
105 void lock_assert(void)
106 /* assert that we already posess a lock */
108 lock_acquired = TRUE;
111 void lock_or_die(void)
112 /* get a lock on a given host or exit */
117 if (!lock_acquired) {
120 if ((fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL, 0666)) != -1) {
121 snprintf(tmpbuf, sizeof(tmpbuf), "%ld\n", (long)getpid());
122 if (write(fd, tmpbuf, strlen(tmpbuf)) < strlen(tmpbuf)) e = 1;
123 if (run.poll_interval)
125 snprintf(tmpbuf, sizeof(tmpbuf), "%d\n", run.poll_interval);
126 if (write(fd, tmpbuf, strlen(tmpbuf)) < strlen(tmpbuf)) e = 1;
128 if (fsync(fd)) e = 1;
129 if (close(fd)) e = 1;
134 lock_acquired = TRUE;
137 fprintf(stderr, GT_("fetchmail: lock creation failed.\n"));
143 void fm_lock_release(void)
144 /* release a lock on a given host */
148 /* lock.c ends here */