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)
21 #include "fetchmail.h"
24 static char *lockfile; /* name of lockfile */
25 static int lock_acquired; /* have we acquired a lock */
28 /* set up the global lockfile name */
30 /* set up to do lock protocol */
31 #define FETCHMAIL_PIDFILE "fetchmail.pid"
33 lockfile = (char *)xmalloc(
34 sizeof(PID_DIR) + sizeof(FETCHMAIL_PIDFILE));
35 sprintf(lockfile, "%s/%s", PID_DIR, FETCHMAIL_PIDFILE);
37 lockfile = (char *)xmalloc(strlen(fmhome)+sizeof(FETCHMAIL_PIDFILE)+2);
38 strcpy(lockfile, fmhome);
39 strcat(lockfile, "/");
41 strcat(lockfile, ".");
42 strcat(lockfile, FETCHMAIL_PIDFILE);
44 #undef FETCHMAIL_PIDFILE
48 static void unlockit(int n, void *p)
50 static void unlockit(void)
52 /* must-do actions for exit (but we can't count on being able to do malloc) */
54 if (lockfile && lock_acquired)
58 void lock_dispose(void)
59 /* arrange for a lock to be removed on process exit */
65 on_exit(unlockit, (char *)NULL);
76 if ((lockfp = fopen(lockfile, "r")) != NULL )
78 bkgd = (fscanf(lockfp, "%d %d", &pid, &st) == 2);
80 if (kill(pid, 0) == -1) {
81 fprintf(stderr,_("fetchmail: removing stale lockfile\n"));
85 fclose(lockfp); /* not checking should be safe, file mode was "r" */
88 return(bkgd ? -pid : pid);
91 void lock_assert(void)
92 /* assert that we already posess a lock */
97 void lock_or_die(void)
98 /* get a lock on a given host or exit */
104 #define O_SYNC 0 /* use it if we have it */
108 if ((fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL|O_SYNC, 0666)) != -1)
110 sprintf(tmpbuf,"%d", getpid());
111 write(fd, tmpbuf, strlen(tmpbuf));
112 if (run.poll_interval)
114 sprintf(tmpbuf," %d", run.poll_interval);
115 write(fd, tmpbuf, strlen(tmpbuf));
117 close(fd); /* should be safe, fd was opened with O_SYNC */
118 lock_acquired = TRUE;
122 fprintf(stderr, _("fetchmail: lock creation failed.\n"));
128 void lock_release(void)
129 /* release a lock on a given host */
134 /* lock.c ends here */