X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=lock.c;h=2d656df65289fcf3ae829ac3d5306cb192fd3d03;hb=a23a8cf8ee1da51c4392b9f52e6b72b0c01e3b5e;hp=39351be1f4bac84f98800539f841be48d18fdcb2;hpb=08f6a9bfc9a9ef93767f9fdcbc5c1991a943061a;p=~andy%2Ffetchmail diff --git a/lock.c b/lock.c index 39351be1..2d656df6 100644 --- a/lock.c +++ b/lock.c @@ -1,30 +1,24 @@ -/* - * lock.c -- cross-platform concurrency locking for fetchmail +/** + * \file lock.c cross-platform concurrency locking for fetchmail * * For license terms, see the file COPYING in this directory. */ #include "config.h" #include -#ifdef HAVE_STRING_H #include /* strcat() */ -#endif -#if defined(STDC_HEADERS) #include -#endif -#if defined(HAVE_UNISTD_H) #include -#endif #include #include #include #include "fetchmail.h" -#include "i18n.h" +#include "gettext.h" #include "lock.h" -static char *lockfile; /* name of lockfile */ -static int lock_acquired; /* have we acquired a lock */ +static char *lockfile; /** name of lockfile */ +static int lock_acquired; /** flag if have we acquired a lock */ void fm_lock_setup(struct runctl *ctl) /* set up the global lockfile name */ @@ -66,39 +60,54 @@ static void unlockit(void) void fm_lock_dispose(void) /* arrange for a lock to be removed on process exit */ { -#ifdef HAVE_ATEXIT atexit(unlockit); -#endif } int fm_lock_state(void) { - int pid, st; + long pid; + int st; FILE *lockfp; int bkgd = FALSE; if ((lockfp = fopen(lockfile, "r")) != NULL) { - int args = fscanf(lockfp, "%d %d", &pid, &st); + int args = fscanf(lockfp, "%ld %d", &pid, &st); bkgd = (args == 2); if (ferror(lockfp)) { fprintf(stderr, GT_("fetchmail: error reading lockfile \"%s\": %s\n"), lockfile, strerror(errno)); + fclose(lockfp); /* not checking should be safe, file mode was "r" */ exit(PS_EXCLUDE); } + fclose(lockfp); /* not checking should be safe, file mode was "r" */ - if (args == 0 || kill(pid, 0) == -1) { + if (args == EOF || args == 0 || kill(pid, 0) == -1) { + /* ^ could not read PID || process does not exist */ + /* => lockfile is stale, unlink it */ pid = 0; + fprintf(stderr,GT_("fetchmail: removing stale lockfile\n")); if (unlink(lockfile)) { if (errno != ENOENT) { perror(lockfile); + /* we complain but we don't exit; it might be + * writable for us, but in a directory we cannot + * write to. This means we can write the new PID to + * the file. Truncate to be safe in case the PID is + * recycled by another process later. + * \bug we should use fcntl() style locks or + * something else instead in a future release. */ + if (truncate(lockfile, (off_t)0)) { + /* but if we cannot truncate the file either, + * assume that we cannot write to it later, + * complain and quit. */ + perror(lockfile); + exit(PS_EXCLUDE); + } } - } else { - fprintf(stderr,GT_("fetchmail: removing stale lockfile\n")); } } - fclose(lockfp); /* not checking should be safe, file mode was "r" */ } else { pid = 0; if (errno != ENOENT) { @@ -112,7 +121,7 @@ int fm_lock_state(void) } void fm_lock_assert(void) -/* assert that we already posess a lock */ +/* assert that we already possess a lock */ { lock_acquired = TRUE; }